//
// this file by brian martin 1996
// brian@phyast.pitt.edu
//
// this is part of the source for the MedDLe quake model viewer/editor
//
//
#include "mdl.h"

GrContext *BitMapContext;

draw_bitmap_context(GrContext  *, MDL_model *);

int mdl_2d(MDL_model *model, MDL_window *w)
{
	FILE *out;
	int i,j,k,l;
	unsigned p1,p2,p3,p4;
	int ontopof=0;
	int selectedx, selectedy, selectedindex;
	int madechanges=0;
	int loop;
	static int draw_triangles=1,draw_vertices=1;
	int draw_3d=0;
	int goto_3d=0;
	int zoom_factor=2;
	static int paint_mode=0;
	static int show_model=0;

	BG_ClearScreen(0);
	// make room for bitmap of skins
	BitMapContext = GrCreateContext(model->skinw,model->skinh,NULL,NULL);

	draw_bitmap_context(BitMapContext, model);

	BG_MouseStatus();

	int update=1;
	int refresh=1;
	int oldx=BG_MouseX,oldy=BG_MouseY,oldr=BG_MouseRight,oldl=BG_MouseLeft;
	BG_MouseShow();
	loop=1;
	char cur_key;
	int selected=0;
	while(loop)
	{
		BG_MouseStatus();

		if(kbhit())
		{

			if((cur_key=getch())==0x0){
			 cur_key=getch();
			 //	cur_key=getch();
			switch(cur_key)
			{
				case ARROW_DOWN:    if(BG_MouseY<(BG_ScreenHeight-1)) {BG_MouseY++; BG_MouseToXY(BG_MouseX,BG_MouseY); BG_MouseStatus();} break;
				case ARROW_UP:	    if(BG_MouseY>0) {BG_MouseY--;BG_MouseToXY(BG_MouseX,BG_MouseY); BG_MouseStatus();} break;
				case ARROW_LEFT:    if(BG_MouseX>0) {BG_MouseX--;BG_MouseToXY(BG_MouseX,BG_MouseY); BG_MouseStatus();} break;
				case ARROW_RIGHT:   if(BG_MouseX<(BG_ScreenWidth-1)) {BG_MouseX++; BG_MouseToXY(BG_MouseX,BG_MouseY); BG_MouseStatus();} break;
			}
			}
			else{
			switch(cur_key)
			{
				case 27:	       	loop=0; draw_3d=0; break;
				case '3':			loop=0; draw_3d=1; break;
				case '1':			loop=0; draw_3d=2; break;
				case 't':case 'T':  if(draw_triangles==0)draw_triangles=1;
									else draw_triangles=0; break;
				case 'v':case 'V':  if(draw_vertices==0)draw_vertices=1;
									else draw_vertices=0; break;
				case 's':case 'S':
						BG_Text("Saving",0,0,250,0);

						if((out=fopen(model->filename,"wb"))==NULL)
						{
							fprintf(stderr,"can't open mdl file... bye\n");
							exit(1);
						}
						rewind(out);
						write_mdl(out, model);
						fclose(out);
						break;
				case 'p': case 'P': if(paint_mode==1) paint_mode=0; else paint_mode=1; break;
				case 'm': case 'M': if(show_model==1) show_model=0; else show_model=1; break;
				case ',': case '<': if(model->cur_skin==0) model->cur_skin=model->num_skins-1;
									else model->cur_skin-=1;
									draw_bitmap_context(BitMapContext, model);
									break;
				case '.': case '>': model->cur_skin++;
									if(model->cur_skin==model->num_skins) model->cur_skin=0;
									draw_bitmap_context(BitMapContext, model);
									break;
				case '\"': case '\'': model->bcolor++;
							if(model->bcolor>13)model->bcolor=0;
							draw_bitmap_context(BitMapContext, model);
							break;
				case ';': case ':': model->bcolor--;
							if(model->bcolor<0)model->bcolor=13;
							draw_bitmap_context(BitMapContext, model);
							break;

				case '}': case ']': model->tcolor++;
							if(model->tcolor>13)model->tcolor=0;
							draw_bitmap_context(BitMapContext, model);
							break;
				case '{': case '[': model->tcolor--;
							if(model->tcolor<0) model->tcolor=13;
							draw_bitmap_context(BitMapContext, model);
							break;

			}
			}
		update=1;
		refresh=1;
		}

		if((BG_MouseLeft==1)||(BG_MouseX!=oldx)||(BG_MouseY!=oldy))
		{
			oldx=BG_MouseX;
			oldy=BG_MouseY;
			oldr=BG_MouseLeft;
			update=1;
		}
		// if something changed udate changes and redraw
		if(update==1)
		{
			BG_MouseHide();
			// if moving point
			if(BG_MouseLeft==1)
			{
				//point was already selected..
				if(selected==1)
				{
					refresh=1;
					// draw over old position  (and seemed pos)
					BG_PutPixel(model->vertex[selectedindex*3+1],model->vertex[selectedindex*3+2],model->skin[model->cur_skin].bitmap[model->vertex[selectedindex*3+1]+model->vertex[selectedindex*3+2]*model->skinw]);
					if(model->vertex[selectedindex*3]==32)
						BG_PutPixel(model->skinw/2+model->vertex[selectedindex*3+1],model->vertex[selectedindex*3+2],model->skin[model->cur_skin].bitmap[model->skinw/2+model->vertex[selectedindex*3+1]+model->vertex[selectedindex*3+2]*model->skinw]);
					// store the new position
					// if on seem store..
					if((model->vertex[selectedindex*3]==32)&&(BG_MouseX>model->skinw/2))
					{
						model->vertex[selectedindex*3+1]=BG_MouseX-model->skinw/2;
						model->vertex[selectedindex*3+2]=BG_MouseY;
					}
					// if not on seem...
					else
					{
						model->vertex[selectedindex*3+1]=BG_MouseX;
						model->vertex[selectedindex*3+2]=BG_MouseY;
					}
				}
			}
			else selected=0;
			// redraw skin
			if(refresh)
				GrBitBlt(NULL,0,0,BitMapContext,0,0,model->skinw-1,model->skinh-1,GrWRITE);
			//draw 2d polgon mesh
			if(draw_triangles)
			{
				int x1,x2,x3;
				for(i=0;i<model->num_triangles;i++)
				{
					p1=model->triangle[i*4+1];
					p2=model->triangle[i*4+2];
					p3=model->triangle[i*4+3];
					p4=model->triangle[i*4];
					x1=x2=x3=0;
					if((model->vertex[3*p1]==32)&&(p4==0)) x1=model->skinw/2;
					if((model->vertex[3*p2]==32)&&(p4==0)) x2=model->skinw/2;
					if((model->vertex[3*p3]==32)&&(p4==0)) x3=model->skinw/2;
					BG_Line(model->vertex[p1*3+1]+x1,model->vertex[p1*3+2],model->vertex[p2*3+1]+x2,model->vertex[p2*3+2],8);
					BG_Line(model->vertex[p2*3+1]+x2,model->vertex[p2*3+2],model->vertex[p3*3+1]+x3,model->vertex[p3*3+2],8);
					BG_Line(model->vertex[p3*3+1]+x3,model->vertex[p3*3+2],model->vertex[p1*3+1]+x1,model->vertex[p1*3+2],8);
				}
			}
			// check all vertices, if mouse is ontop of one and left
			// button is pushed, select point
			for(i=0;i<model->num_vertices;i++)
			{
				// not on seem
				if(model->vertex[i*3]!=32)
				{
					if((BG_MouseX==model->vertex[i*3+1])&&(BG_MouseY==model->vertex[i*3+2]))
					{
						if(selected==0)
						{
							ontopof=1;
							if(BG_MouseLeft){selectedindex=i;selected=1;}
						}
					}
					else ontopof=0;
				}
				//else if on seem, check back of skin too
				else
				{
					if((BG_MouseX==model->skinw/2+model->vertex[i*3+1])&&(BG_MouseY==model->vertex[i*3+2])
					||(BG_MouseX==model->vertex[i*3+1])&&(BG_MouseY==model->vertex[i*3+2]))
					{
						if(selected==0)
						{
							ontopof=1;
							if(BG_MouseLeft){selectedindex=i;selected=1; }
						}
					}
					else ontopof=0;
				}
				// draw vertices
				if(draw_vertices)
				{
					BG_PutPixel(model->vertex[i*3+1],model->vertex[i*3+2],254-4*ontopof);
					// if seemed draw here too
					if(model->vertex[i*3]==32)
					BG_PutPixel(model->skinw/2+model->vertex[i*3+1],model->vertex[i*3+2],254-4*ontopof);
				}


			}

			BG_MouseShow();
			update=0;
			refresh=0;
		}

	}


	GrDestroyContext(BitMapContext);



	if(draw_3d==0) return 0;
	else if(draw_3d==1) return 1;
	else return 2;  // show help screen


}


draw_bitmap_context(GrContext  *BitMapContext, MDL_model *model)
{
	GrSetContext(BitMapContext);
	for(int j=0;j<model->skinh;j++)
	{
		for(int i=0;i<model->skinw;i++)
		{
			int ccolor;
			ccolor=model->skin[model->cur_skin].bitmap[i+j*model->skinw];
			if((ccolor>=96)&&(ccolor<112))
			{
				if(model->bcolor<8)
					ccolor+=model->bcolor*16-96;
				else {
					ccolor-=96;
					ccolor=15-ccolor;
					ccolor+=model->bcolor*16;
					}
			}
			else if((ccolor>=16)&&(ccolor<32))
			{
				if(model->tcolor<8)
					ccolor+=model->tcolor*16-16;
				else {
					ccolor-=16;
					ccolor=15-ccolor;
					ccolor+=model->tcolor*16;
					}
			}
			//if(ccolor)
			BG_PutPixel(i,j,ccolor);
		}
	}
//	for (int i=0; i<256;i++)
//			BG_PutPixel(i,1,i);
	GrSetContext(NULL);
	// draw bitmap
	GrBitBlt(NULL,0,0,BitMapContext,0,0,model->skinw-1,model->skinh-1,GrWRITE);


}
