#include <v_lib.h>

/*
#define	USE_COMPILED_IN_FONT
#define	SAVE_IMAGE_TO_METAFILE
#define	USE_TEXTURE_SHADER
*/

#ifdef	USE_TEXTURE_SHADER

GLuint	shader;						/* texture object */
GLfloat plane_abcd[4] = {0,1,0,0};	/* plane equation for glTexGen() */

void	create_shader(void)
{
	int i;
	color4b_t	rgb_shift[256];
	for(i=0;i<256;i++)
	{
		vec4_t rgba, hsv;
		hsv[0] = i * (vec_t)360 / (vec_t)256;
		hsv[1] = 0.2f;
		hsv[2] = 1;
		rgbFromHsv(rgba,hsv);
		rgba[3] = 1;
		rgbaByteFromFloat(rgb_shift[i],rgba);
	}
	glGenTextures(1,&shader);
	glBindTexture(GL_TEXTURE_1D,shader);
	glTexImage1D(GL_TEXTURE_1D,0,4,256,0,GL_RGBA,GL_UNSIGNED_BYTE,rgb_shift);
	glTexParameterf(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameterf(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameterf(GL_TEXTURE_1D,GL_TEXTURE_WRAP_S,GL_REPEAT);
	glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
	/* setup planar texgen */
	glBindTexture(GL_TEXTURE_1D,shader);
	glTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
	glTexGenfv(GL_S,GL_OBJECT_PLANE,plane_abcd);
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_1D);
}

void	animate_shader(void)
{
	plane_abcd[3] += 0.01f;
	glTexGenfv(GL_S,GL_OBJECT_PLANE,plane_abcd);
    /*
    glMatrixMode(GL_TEXTURE);
    glRotatef((GLfloat)0.1,0,0,1);
    glMatrixMode(GL_MODELVIEW);
    */
}

void	destroy_shader(void)
{
	glDisable(GL_TEXTURE_1D);
	glBindTexture(GL_TEXTURE_1D,0);
	glDeleteTextures(1,&shader);
}

#else	/* !USE_TEXTURE_SHADER */

vec_t alpha = 0.5f;

void	create_shader(void)
{
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    glEnable(GL_LINE_SMOOTH);
    glColor4f(1,1,1,(GLfloat)alpha);
}

void	animate_shader(void)
{
	alpha += 0.01f;
    if(alpha >= 1.0f)
		alpha = 0.5f;
    glColor4f(1,1,1,(GLfloat)alpha);
}

void	destroy_shader(void)
{
}

#endif	/* !USE_TEXTURE_SHADER */

/*
 * This function will be passed later to vglDrawToMetafile(),
 * so we need to declare it as 'V_CALL'
 */
void V_CALL draw_scene(void *param)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
	/* vglPutsKoi8r("pRIWET !\n"); */
    vglPuts("Привет !\n\n");
    vglPuts("1234567890");
    glPopMatrix();
}

int main()
{
	input_record_t r;
    vhandle_t font = LIBV_INVALID_HANDLE;
    logStartConsoleLog();
    logUpperLevel(LOG_TRACE);
#ifdef	USE_TEXTURE_SHADER
	vglCreateWindow("Stroke font demo (1D texture shader)",0,0,512,384);
#else	/* !USE_TEXTURE_SHADER */
	vglCreateWindow("Stroke font demo (alpha smooth shader)",0,0,512,384);
#endif	/* !USE_TEXTURE_SHADER */
	if(vglGetCurrentWindow() == LIBV_INVALID_HANDLE)
		return -1;
	create_shader();
#ifndef	USE_COMPILED_IN_FONT
    font = vglLoadBGIFontEx("../../../media/bgi-fonts/cyrgoth.chr",false);
	if(font != LIBV_INVALID_HANDLE)
	{
		vglSelectFont(font);
        /*
         * Note: fonts are reference-counted, so we can safe
         * call vglDestroyFont() before vglDestroyWindow().
         */
        vglDestroyFont(font);
	}
	else
	{
		vglDestroyWindow(vglGetCurrentWindow());
    	conlPuts(LOG_ERROR,"Error loading BGI font\n");
		return -1;
	}
#else	/* USE_COMPILED_IN_FONT */
	vglLoadDefaultFont();
#endif	/* !USE_COMPILED_IN_FONT */
	/* Setup GL */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1,1,-1,1,-1,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(-1,1,0);
    glScalef(.24f,.4f,1);
    glTranslatef(0,-1,0);
	glClearColor(0,0,0,1);
	glDisable(GL_DEPTH_TEST);
    glLineWidth(2.8f);
   	/* Animate text */
    do
    {
    	while(!vglPending())
		{
			draw_scene(NULL);
     		vglSwapBuffers();
      		timeDelay(10);
			animate_shader();
		}
        vglNextEvent(&r);
	} while(r.event!=ev_key_down);
#ifdef	SAVE_IMAGE_TO_METAFILE
	/* Save vector image */
	vglDrawToMetafile("out.wmf",100,100,draw_scene,font);
#ifdef  __WIN32__
	/* Draw text to the system clipboard */
	vglDrawToMetafile("//./clipboard",100,100,draw_scene,font);
#endif  /* __WIN32__ */
#endif	/* SAVE_IMAGE_TO_METAFILE */
	destroy_shader();
	vglDestroyWindow(vglGetCurrentWindow());
	memPrintStats();
	return 0;
}
