struct ArpBase *ArpBase;
struct IconBase *IconBase;
struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;
struct Window *w;
struct Screen *s;
struct RastPort *rp;
struct BitMap picbm;
struct ViewPort *vp;
jmp_buf jmpsave;
BPTR dfh;
int picx0[MAXPICS+1], picy0[MAXPICS+1];
char picbuf[PICBUFSIZE];
int maincolor, mx, my, button, minundo, npic;

struct NewScreen ns= {
0,SCRNY,640,256-SCRNY,DEPTH,
0,1,
HIRES,
CUSTOMSCREEN,
NULL,
NULL,
NULL,
NULL,
};

#define IFLAGS (RAWKEY | MOUSEBUTTONS | MENUPICK | DISKINSERTED)

struct NewWindow nw= {
  0, 0,			/* LeftEdge, TopEdge	*/
  640, 256-SCRNY,	/* Width, Height	*/
  0, 1,			/* DetailPen, BlockPen	*/
  IFLAGS,		/* IDCMPFlags		*/
  SMART_REFRESH | ACTIVATE | BORDERLESS | GIMMEZEROZERO | REPORTMOUSE,
			/* Flags		*/
  NULL,			/* FirstGadget		*/
  NULL,			/* CheckMark		*/
  NULL,			/* Title		*/
  NULL,			/* Screen		*/
  NULL,			/* BitMap		*/
  50, 40,		/* MinWidth, MinHeight	*/
  640, 200,		/* MaxWidth, MaxHeight	*/
  CUSTOMSCREEN,		/* Type			*/
};

char *lastname=NULL;

struct Process *thistask;
APTR oldwind;

struct Menu *mymenu;

main (argc,argv)
char *argv[];
{
register int i,pic,n0,n1,x,y;
char temp[80];

ArpBase=(struct ArpBase *)OpenLibrary("arp.library", 0);
IntuitionBase=(struct IntuitionBase *)ArpBase->IntuiBase;
GfxBase=(struct GfxBase *)ArpBase->GfxBase;
fatalcheck(ArpBase,"Can't open arp.library");
IconBase=(struct IconBase *)OpenLibrary("icon.library", 0);
fatalcheck(IconBase,"Can't open icon.library");
sprintf(temp,"CON:0/0/640/%ld/Graph",SCRNY);
fatalcheck(dfh=Open(temp,MODE_NEWFILE),"Can't open CON:");
fatalcheck(s=nw.Screen= OpenScreen(&ns),"Can't open screen");
fatalcheck(w = OpenWindow(&nw),"Can't open window");
rp=w->RPort;
vp= & (s->ViewPort);
InitBitMap(&picbm,DEPTH,SIZEX,SIZEY);
FOR (i,0,DEPTH-1) picbm.Planes[i]=picbuf+i*(PICBUFSIZE/DEPTH);
thistask=(struct Process *)FindTask(0);
oldwind=thistask->pr_WindowPtr;
thistask->pr_WindowPtr=(APTR)w;
loadrgb("Graph.rgb");
createpics();
FOR (i,0,NCOLS-1) {
	SetAPen(rp,i);
	RectFill(rp,i*PALX,PALY,i*PALX+(PALX-1),256);
	}
setcol(1);
for (i=1,pic=2; i<argc && i<npic; i++)
	pic+=doload(argv[i],pic);
mymenu=(struct Menu *)newmenu("Project");
	newitem("New    ");
	newitem("Open   ");
		setcommand('O');
	newitem("Save as");
		setcommand('A');
	newitem("Quit   ");
		setcommand('Q');
newmenu("Edit");
	newitem("Line ");
	newitem("Box  ");
	newitem("Block");
newmenu("Specials");
	newitem("All color");
	newitem("Change   ");
	newitem("Fill     ");
		setcommand('F');
	newitem("Not      ");
	newitem("MirrorX  ");
	newitem("MirrorY  ");
newmenu("Pictures");
	newitem("Move  ");
	newitem("OR    ");
	newitem("AND   ");
	newitem("XOR   ");
	newitem("Impose");
newmenu("Scroll");
	newitem("Up   ");
		setcommand('I');
	newitem("Down ");
		setcommand('M');
	newitem("Left ");
		setcommand('J');
	newitem("Right");
		setcommand('K');
newmenu("RGB");
	newitem("Select  ");
	newitem("Load    ");
	newitem("Save    ");
	newitem("Save  as");
SetMenuStrip(w, mymenu);
setjmp(jmpsave);
for (;;) {
    STDCOL;
    ClearPointer(w);
    getim();
    if (button) {
	if (my>PALY) setcol(ReadPixel(rp,mx,my));
	else if (n0=isinpic(mx,my,1)) {
		FPrintf(dfh,"Move from %ld",n0);
		while (button) getim();
		n1=isinpic(mx,my,0);
		if (n1 && n0!=n1) {
			picmove(picx0[n0],picy0[n0],picx0[n1],picy0[n1]);
			FPrintf(dfh," to %ld\n",n1);
			}
		else FPrintf(dfh,"...Aborted\n");
		}
	else {
		ModifyIDCMP(w,IFLAGS | MOUSEMOVE);
		while (button && ISOK((x=BTOLX(mx))-LITX0,(y=BTOLY(my))-LITY0)) {
			BOTHPLOT(x,y);
			getim();
			}
		ModifyIDCMP(w,IFLAGS);
		}
	}
    }
}

clall(retcode)
{
if (w) {
	ClearMenuStrip(w);
	thistask->pr_WindowPtr=oldwind;
	CloseWindow(w);
	}
if (s) CloseScreen(s);
if (dfh) Close(dfh);
if (IconBase) CloseLibrary((struct Library *)IconBase);
if (ArpBase) CloseLibrary((struct Library *)ArpBase);
exit(0);
}

error(msg,fatal)
char *msg;
{
if (fatal) { Printf("\n\n   *** Fatal: %s ***\n\n",msg); clall(20); }
display(msg);
longjmp(jmpsave,0);
}

getpoint(s,px,py)
char *s;
int *px,*py;
{
int x,y;

display(s);
x=*px, y=*py;
while ( button) getim();
while (!button) getim();
x=BTOLX(mx), y=BTOLY(my);
if ( x<LITX0 || x>LITX1 ) longjmp(jmpsave,0);
if ( y<LITY0 || y>LITY1 ) longjmp(jmpsave,0);
*px=x, *py=y;
}

getim()
{
struct IntuiMessage *m;
int class, code;

WaitPort(w->UserPort);
m=(struct IntuiMessage *)GetMsg(w->UserPort);
class=m->Class;
code =m->Code;
mx=m->MouseX;
my=m->MouseY;
ReplyMsg((struct Message *)m);
if ( (class==RAWKEY) && (code==0x45) ) longjmp(jmpsave,0);
if (class==MOUSEBUTTONS) {
	if (code==SELECTUP  ) button=0;
	if (code==SELECTDOWN) button=1;
	}
if (class==MENUPICK && code!=MENUNULL)
	menuaction(MENUNUM(code)*10+ITEMNUM(code));
}

edit(n,name,fun)
char *name;
void (*fun)();
{
int x0,y0,x1,y1;
char str[80];

saveundo();
sprintf(str,"%s from",name);
getpoint(str,&x0,&y0);
BOTHPLOT(x0,y0);
sprintf(str,"%s to",name);
getpoint(str,&x1,&y1);
(*fun)(x0,y0,x1,y1);
updatebig();
}

menuaction(n)
{
int line(), box(), block();

switch(n) {
	case 00: allcol(0);		break;
	case 01: oopen();		break;
	case 02: osaveas();		break;
	case 03: oquit();		break;

	case 10: edit(1,"Line" ,line );	break;
	case 11: edit(2,"Box"  ,box  );	break;
	case 12: edit(3,"Block",block);	break;

	case 20: allcol(maincolor);	break;
	case 21: ochange();		break;
	case 22: ofill();		break;
	case 23: onot();		break;
	case 24: omirx();		break;
	case 25: omiry();		break;

	case 30: error("Just drag!",0);	break;
	case 31: combine(0xee);		break;
	case 32: combine(0x88);		break;
	case 33: combine(0x66);		break;
	case 34: combine(0x00);		break;

	case 40: scroll( 0, 1);		break;
	case 41: scroll( 0,-1);		break;
	case 42: scroll( 1, 0);		break;
	case 43: scroll(-1, 0);		break;

	case 50: DoColorWindow(s, 20, 20, 1, 1); break;
	case 51: orgbload();		break;
	case 52: orgbsave();		break;
	case 53: orgbsaveas();		break;

	default: error("menu switch",1);
	}
}

struct IntuiText body={ 0, 1, JAM2,  24,  8, NULL, "Are you sure ?", NULL };
struct IntuiText pos ={ 0, 1, JAM2,   5,  3, NULL, "Quit"	   , NULL };
struct IntuiText neg ={ 0, 1, JAM2,   5,  3, NULL, "Cancel"	   , NULL };

oquit()
{
if (AutoRequest(w,&body,&pos,&neg,0,0,200,60)) clall(0);
}
