#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)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  __WINAPI__
	/* Draw text to the system clipboard */
	vglDrawToMetafile(libv_clipboard_name,100,100,draw_scene,font);
#endif  /* __WINAPI__ */
#endif	/* SAVE_IMAGE_TO_METAFILE */
	destroy_shader();
	vglDestroyWindow(vglGetCurrentWindow());
	memPrintStats();
	return 0;
}
