#include "stdafx.h"
#include "orb.h"
char *ibuf;
char *names[]={"line","box","arc","dotline","dotarc"};
char fname[127]="noname";
char pname[127]="test.bmp";
struct thing
{
	int x1,y1,x2,y2;
	int t;	// type - line, box, arc, dotline, dotarc
	int c;	// colour
	int a1,a2;
};

int numt=0,curt=0;
int grid=0,snap=0;
thing t[1024];
int pal[256][3];

void drawpal()
{
	int c1,x,y;
//WIN32TODO 
	/*
	outp(0x3c8,0);
	for (c1=0;c1<768;c1++) outp(0x3c9,pal[0][c1]);
	for (y=0;y<8;y++)
	{
		for (x=0;x<32;x++)
		{
			_setcolor(x+y*32);
			_rectangle(_GFILLINTERIOR,x*20,400+y*10,x*20+20,410+y*10);
		}
	}
	*/
}

void load(char *name=fname)
{

	FILE *fi=fopen(name,"rb");
	if (!fi) return;
	fread(&numt,1,4,fi);
	//fread(t,numt,sizeof(thing),fi);
	for (int c1=0;c1<numt;c1++)
	{
		fread(&t[c1].x1,5,4,fi);
		t[c1].c=255;
		//fread(&t[c1].c,1,4,fi);
		fread(&t[c1].a1,2,4,fi);
	}
	fclose(fi);
	curt=0;
}

void save(char *name=fname)
{

	FILE *fi=fopen(name,"wb");
	if (!fi) return;
	fwrite(&numt,1,4,fi);

	fwrite(t,numt,sizeof(thing),fi);
	fclose(fi);
}

void line(int x1,int y1,int x2,int y2)
{
	_moveto(x1,y1);
	_lineto(x2,y2);
}

void rectangle(int x1,int y1,int x2,int y2)
{
	_moveto(x1,y1);
	_lineto(x1,y2);
	_lineto(x2,y2);
	_lineto(x2,y1);
	_lineto(x1,y1);
}


int calcx(thing *t, int a)
{
	return t->x1+(t->x2-t->x1)/2*(1+cos(a*PI/32));
}

int calcy(thing *t, int a)
{
	return t->y1+(t->y2-t->y1)/2*(1+sin(a*PI/32));
}


void drawt(thing *t, int cm)
{
	int c1;
	_setcolor(cm*t->c);
	switch (t->t)
	{
	case 0:
		line(t->x1,t->y1,t->x2,t->y2);
		break;
	case 1:
		if (t->a1) for (c1=0;c1<=t->a1;c1++) line(t->x1+float(t->x2-t->x1)/t->a1*c1,t->y1,t->x1+float(t->x2-t->x1)/t->a1*c1,t->y2);
		if (t->a2) for (c1=0;c1<=t->a2;c1++) line(t->x1,t->y1+float(t->y2-t->y1)/t->a2*c1,t->x2,t->y1+float(t->y2-t->y1)/t->a2*c1);
		break;
	case 2:
		for (c1=t->a1*2;c1<t->a2*2+1;c1++) line(calcx(t,c1),calcy(t,c1),calcx(t,c1+1),calcy(t,c1+1));
		break;
	case 3:
		for (c1=0;c1<t->a2;c1++) line(t->x1+float(t->x2-t->x1)/t->a2*c1,
									  t->y1+float(t->y2-t->y1)/t->a2*c1,
									  t->x1+float(t->x2-t->x1)/t->a2*(c1+0.5),
									  t->y1+float(t->y2-t->y1)/t->a2*(c1+0.5));
		break;
	case 4:
		for (c1=t->a1*2;c1<t->a2*2+1;c1+=2) line(calcx(t,c1),calcy(t,c1),calcx(t,c1+1),calcy(t,c1+1));
		break;
	}
}

void draw(int c2, int cm=1)
{
	int c1;
	for (c1=0;c1<numt;c1++) drawt(t+c1,cm);
	_setcolor(c2);
	thing *tt=t+curt;
	if (curt<numt)
	{
		rectangle(tt->x1,tt->y1,tt->x2,tt->y2);
		rectangle(tt->x1-2,tt->y1-2,tt->x1+2,tt->y1+2);
	}
}

int mx,my,mb;

void	getmouse()
{
	union REGS regs;
	memset(&regs,0,sizeof(regs));
	regs.w.ax=0x0003;
	int386(0x33,&regs,&regs);
	mx=regs.w.cx;
	my=regs.w.dx*2.4;
	mb=regs.w.bx;

}

void	drawmouse()
{
	_setplotaction(_GXOR);
	line(0,my,640,my);
	line(mx,0,mx,480);
	_setplotaction(_GPSET);
}

void	hilitecol(int c1)
{
	int x=(c1&31);
	int y=(c1/32);
	_setplotaction(_GXOR);
	_setcolor(255);
	rectangle(x*20+1,401+y*10,x*20+18,408+y*10);
	_setplotaction(_GPSET);
}


void	showmouse()
{
	union REGS regs;
	memset(&regs,0,sizeof(regs));
	regs.w.ax=0x0001;
	int386(0x33,&regs,&regs);
}

void	hidemouse()
{
	union REGS regs;
	memset(&regs,0,sizeof(regs));
	regs.w.ax=0x0002;
	int386(0x33,&regs,&regs);
}

void	initmouse()
{
	union REGS regs;
	memset(&regs,0,sizeof(regs));
	regs.w.ax=0x0000;
	int386(0x33,&regs,&regs);
}

void text(char *s, int x=-1, int y=-1, int c=-1)
{
	if (x>=0 && y>=0) _settextposition(y,x);
	if (c>=0) _settextcolor(c);
	_outtext(s);
}

void preview(int readpic=1)
{
	FILE *fi=fopen(pname,"rb");
	if (!fi) return;
	fseek(fi,54,SEEK_SET);
	//if (readpic) _setvideomode(_VRES256COLOR);
	int c1;
	char buf[320];
	for (c1=0;c1<256;c1++)
	{
		char r,g,b,a;
		fread(&b,1,1,fi);
		fread(&g,1,1,fi);
		fread(&r,1,1,fi);
		fread(&a,1,1,fi);
		pal[c1][0]=r/4;
		pal[c1][1]=g/4;
		pal[c1][2]=b/4;

	}
	drawpal();
	if (!readpic)
	{
		fclose(fi);
		return;
	}
	for (c1=199;c1>=0;c1--)
	{
		fread(buf,320,1,fi);
		for (int c2=0;c2<320;c2++) {
			_setcolor(buf[c2]);
			_setpixel(c2*2,c1*2);_setpixel(c2*2+1,c1*2);
			_setpixel(c2*2,c1*2+1);_setpixel(c2*2+1,c1*2+1);
		}
	}
	fclose(fi);
	if (!ibuf) delete [] ibuf;
	ibuf=new char[_imagesize(0,0,640,400)];
	_getimage(0,0,640,400,ibuf);
	curt=numt;
	draw(0);
	getch();

	drawpal();
}

int getfname( char *ff, char *fname)
{
	_setcolor(255);
	_settextcolor(255);
	printf("\n\n!!!!!!!do you really want to %s?\n\n",ff);
	char ch;
	do
	{

		ch=toupper(getch());
		if (ch==27) return 0;
		if (ch=='N') return 0;
	} while (ch!='Y');
	printf("current file name = %s\npress return to keep this or enter a new one:\n",fname);
	char fname2[164];
	gets(fname2);
	if (strlen(fname2)!=0) strcpy(fname,fname2);
	return 1;
}

void translate(int a)
{
	getmouse();
	int omx,omy,c1;
	do
	{
		omx=mx;
		omy=my;
		getmouse();
		draw(0,0);
		for (c1=a;c1<numt;c1++)
		{
			t[c1].x1+=(mx-omx);
			t[c1].x2+=(mx-omx);
			t[c1].y1+=(my-omy);
			t[c1].y2+=(my-omy);
		}
		draw(0);
		delay(100);
	} while (mb==0 && (!kbhit()));
	do
	{
		getmouse();
	} while (mb);
	while (kbhit()) getch();
}

void clear()
{
	//_setvideomode(_VRES256COLOR);
	//return;
	_setcolor(0);
	_rectangle(_GFILLINTERIOR,0,0,640,480);
}

int main(int argc, char *argv)
{
	//do{printf("%d\n",getch());} while (1==1);
	_setvideomode(_VRES256COLOR);
	_setvideomode(_VRES256COLOR);
	initmouse();
	int c1,c2;
	int quit=0;
	grid=1;
	snap=1;
//WIN32TODO 	outp(0x3c7,0);for (c1=0;c1<768;c1++) pal[0][c1]=inp(0x3c9);
	pal[255][0]=pal[255][1]=pal[255][2]=63;
	drawpal();
	int lastc=255;
	while (quit<2)
	{
		if (ibuf) _putimage(0,0,ibuf,_GPSET);
		_setcolor(0);
		_rectangle(_GFILLINTERIOR,0,0,640,16);
		if (quit) text("quit?",0,0,14);
		if (grid) text("grid",7,0,14);
		if (snap) text("snap",12,0,14);
		char str[128];
		if (curt>numt) curt=numt;if (curt<0) curt=0;
		sprintf(str,"%4d/%4d (%s)  parms: %4d - %4d",curt+1,numt, names[t[curt].t],t[curt].a1,t[curt].a2);
		text(str,20,0,12);
		_setcolor(255);
		if (grid) for (c1=8;c1<640;c1+=8)
		for (c2=8;c2<400;c2+=8) _setpixel(c1,c2);
		rectangle(0,0,639,400);
		draw(14);
		hilitecol(t[curt].c);
		do
		{
			drawmouse();
			delay(50);
			drawmouse();
			getmouse();
		} while (mb==0 && !kbhit());
		hilitecol(t[curt].c);
		_setcolor(0);
		draw(0,0);

		if (kbhit())
		{
			char ch=getch();
			if (ch==0)
			{
				ch=getch();
				switch (ch)
				{
				case 'K':
					t[curt].a1--;
					break;
				case 'M':
					t[curt].a1++;
					break;
				case 'H':
					t[curt].a2--;
					break;
				case 'P':
					t[curt].a2++;
					break;
				case 60:
					if (getfname("save",fname)) save();
					clear();
					drawpal();
					break;
				case 61:
					if (getfname("load",fname)) load();
					clear();
					drawpal();
					break;
				case 63:
					if (getfname("preview",pname)) preview(1);
					clear();
					drawpal();
					break;
				case 64:
					if (getfname("set palette",pname)) preview(0);
					clear();
					drawpal();
					break;
				case 65:
					delete [] ibuf;
					ibuf=NULL;
					break;

				}
				ch=0;
			}
			else switch (toupper(ch))
			{
			case 'M':
				translate(0);
				break;
			case 'N':
				translate(curt);
				break;
			case 'L':
				if (t[curt].t==0) t[curt].t=3; else
				t[curt].t=0;
				break;
			case 'B':
				t[curt].t=1;
				break;
			case 'C':
				if (t[curt].t==2) t[curt].t=4; else
				t[curt].t=2;
				t[curt].a1=0;
				t[curt].a2=32;
				break;
			case 'A':
				if (t[curt].t==2) t[curt].t=4; else
				t[curt].t=2;
				break;
			case 'D':
				if (t[curt].t==0) t[curt].t=3; else
				if (t[curt].t==3) t[curt].t=0; else
				if (t[curt].t==2) t[curt].t=4; else
				if (t[curt].t==4) t[curt].t=2;
				break;
			case '+':
				if (curt<numt) curt++;
				break;
			case '-':
				if (curt>0) curt--;
				break;
			case 27:
				quit++;
				break;
			case 'S':
				snap=!snap;
				break;
			case 'G':
				_setcolor(0);
				if (grid) for (c1=8;c1<640;c1+=8)
				for (c2=8;c2<400;c2+=8) _setpixel(c1,c2);
				grid=!grid;
				break;

			case 8:
				if (curt<numt) {memmove(&t[curt],&t[curt+1],sizeof(thing)*(numt-curt));numt--;}
				break;
			}
			if (ch!=27) quit=0;
		}
		if (mb==1 && my>400)
		{

			while (mb==1)
			{
				getmouse();
				t[curt].c=(mx/20)+((my-400)/10)*32;
				if (t[curt].c<0) t[curt].c=0;
				if (t[curt].c>255) t[curt].c=255;
				hilitecol(t[curt].c);
				delay(50);
				hilitecol(t[curt].c);
				lastc=t[curt].c;
			}

		}
		if (mb==1 && my<=400)
		{
			int d1=SQR(t[curt].x1-mx)+SQR(t[curt].y1-my);
			int d2=SQR(t[curt].x2-mx)+SQR(t[curt].y2-my);
			if (curt>=numt || (d1>256 && d2>256))
			{
				curt=numt;
				numt++;
				if (snap) {mx&=~7;my&=~7;}
				t[curt].t=0;
				t[curt].a1=0;
				t[curt].a2=8;
				t[curt].x1=mx;
				t[curt].y1=my;
				t[curt].x2=mx;
				t[curt].y2=my;
				t[curt].c=lastc;
			}
			draw(0);


			while (mb==1)
			{
				getmouse();
				_setcolor(0);
				drawt(t+curt,0);
				if (snap) {mx&=~7;my&=~7;}
				if (d1<d2) {t[curt].x1=mx;t[curt].y1=my;}
				else {t[curt].x2=mx;t[curt].y2=my;}
				drawt(t+curt,1);
				delay(70);
			}




		}
	}
	_setvideomode(3);
	return 0;
}
