#include <v_lib.h>

cam_t					cam;
sdof_control_t			ctl;
sdof_keymap_t			*km;
mouse_drag_control_t	mdc;

tripatch_t *pat=NULL;
patchprofile_t *pp=NULL;

int   pts=1;
int   drawpatch = 1, drawtri = 1, drawlines = 1;

int fc=0;
int cbase;

void uuDrawWireChains(wirechains_p mesh,vec_t val)
{
	int i,j;
	vec3_t  *vlist;
	char label[64];
	if(!mesh)
		return;
	vlist=mesh->vlist;
	for(i=0;i<mesh->numchains;i++)
	{
		glBegin(GL_LINE_STRIP);
	    glColor3f(1,1,1);
    	for(j=0;j<mesh->numvert[i];j++)
    			GL_VERTEX3V(vlist[mesh->clist[i][j]]);
	   	glEnd();
	    if(pts && cbase)
    	{
	    	glPushMatrix();
    		glTranslatef(mesh->llist[i].center[0],mesh->llist[i].center[1],
    			mesh->llist[i].center[1]);
	    	glScalef(.1f,.1f,.1f);
			vglPrintf(label,"%1.3g",val);
			glPopMatrix();
		}
	}
}

static void uuDrawPatchprofile(patchprofile_t *iso)
{
  int i;
  if(!iso) return;
  for(i=0;i<iso->splits;i++)
  {
    if(iso->wires[i])
		uuDrawWireChains(iso->wires[i],iso->chainvals[i]);
  }
}

static void	DrawScene(void)
{
	int i;
	if(!pat)
		return;
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1,1,-1,1,2,100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	sdcSyncronize(km,&ctl,&cam);
	camLoadGLTransform(&cam);
	
	glEnable(GL_DEPTH_TEST);
	if(drawpatch)
	{
		glBegin(GL_TRIANGLES);
		for(i=0;i<pat->numtri;i++)
		{
			glColor3f((float).7,(float).3,(float).2);
			glVertex3fv(pat->vlist[pat->tlist[i][0]]);
			glColor3f((float).2,(float).8,(float).2);
			glVertex3fv(pat->vlist[pat->tlist[i][1]]);
			glColor3f((float).2,(float).3,(float).7);
			glVertex3fv(pat->vlist[pat->tlist[i][2]]);
		}
		glEnd();
	}
	glDisable(GL_DEPTH_TEST);
	if(drawlines)
		uuDrawPatchprofile(pp);
	
	timeDelay(10);
	vglSwapBuffers();
}

mvec_t V_CALL rot_para(mvec_t x,mvec_t y)
{
	/* return .5*x*x+y*y - x*y/2 + .5*(x*x+y*y)*sin(sqrt(x*x+y*y)*5); */
	/* return x*x+y*y+2*x*x*x-x*y*y; */
	return - x*x - y*y - 2*x*x*x + x*y*y + 1;
}

mvec_t	V_CALL	sheffe(mvec_t x,mvec_t y,mvec_t z)
{
	return 20 * x*y*z;
}

int main(int argc, char *argv[])
{
	input_record_t ev;
	vhandle_t font;
	vec3_t center={0,0,0};
	logStartConsoleLog();
	logUpperLevel(LOG_TRACE);
	if(argc>1 && !strcmp(argv[1],"-gibbs"))
	{
		pat=ppGridSheffePolynom(center,1,0,20,false,NULL,sheffe,0);
		pp=ppCreateTriangular(center,1,0,NULL,sheffe,5,0);
	}
	else
	{
		pat=ppGridFunction(-1,-1,1,1,20,20,false,rot_para,1);
		pp=ppCreateRectangular(-1,-1,1,1,rot_para,10,1);
	}
	vglCreateWindow("Test",0,0,512,512);
	glClearColor(0.0f,0.2f,0.2f,0.0f);

	puts("Use r,f,d,g,a,z & arrows & mouse to control. 1,3 toggles elements. F10 exits");
	font=vglLoadBGIFont("../../media/bgi-fonts/arus.chr");
	vglSelectFont(font);
	vglDestroyFont(font);
	
	camInit(&cam);
	sdcInit(&ctl);
	km=sdckCreate();
	memZero(&mdc,sizeof(mouse_drag_control_t));

	for(;;)
	{
		while(vglPending())
		{
			vglNextEvent(&ev);
			switch(ev.event)
			{
				case ev_key_down:
					switch(ev.first_code)
					{
						case key_f10:
							goto bye;
						case key_f1:
							drawpatch = !drawpatch;
							break;
						case key_f2:
							drawtri=!drawtri;
							break;
						case key_f3:
							drawlines=!drawlines;
							break;
						case key_f4:
							pts=!pts;
							break;
						default:
							break;
					}
					break;
				default:
					break;
			}
			sdckProcessKey(km,ev.event,ev.first_code);
			sdofMouseDragControl(km,&mdc,&cam,&ev);
		}
		DrawScene();
	}
bye:;
	vglDestroyWindow(vglGetCurrentWindow());
	sdckDestroy(km);
	patFree(pat);
	ppFree(pp);
	return 0;
}
