#include "struct.h"
#include "plot.h"

struct Window *OpenWindow();
struct InputEvent *Intuition();
struct Screen *OpenScreen();
int WrtPlt();

struct RastPort *rp;
struct ViewPort *vp;
struct Window *window;
struct IntuiMessage *msg;
struct Screen *screen;

struct NewScreen newscreen = {
	0,0,			/* start pos.*/
	MAXHORIZ,MAXVERT,4,	/* width height depth (4 bit planes) */
	0,1,			/* detail pen, block pen */
	HIRES | LACE,	 	/* viewing mode (640x400 interlaced) */
	CUSTOMSCREEN,		/* screen type */
	NULL,			/* font */
	"mp",			/* screen title */
	NULL			/* gadget pointer */
	};

struct NewWindow newwindow = {
	0,0,					/* Starting corner */
	MAXHORIZ,MAXVERT,			/* Width, height */
	1,14,					/* detail, block pens */
	MENUPICK | MOUSEMOVE | MOUSEBUTTONS,	/* IDCMP flags */
	ACTIVATE | BORDERLESS | NOCAREREFRESH | REPORTMOUSE,
	NULL,					/* Pointer to first gadget */
	NULL,					/* Pointer to checkmark */
	NULL,					/* title */
	NULL,					/* screen pointer */
	NULL,					/* bitmap pointer */
	0,0,0,0,				/* sizing limits */
	CUSTOMSCREEN				/* type of screen */
	};


void InitColors()
{
   SetRGB4(vp,0,15,10,5);   SetRGB4(vp,1,0,0,0);    SetRGB4(vp,2,15,15,15);
   SetRGB4(vp,3,15,0,0);    SetRGB4(vp,4,0,0,0);    SetRGB4(vp,5,15,0,0);
   SetRGB4(vp,6,0,12,0);    SetRGB4(vp,7,0,5,15);   SetRGB4(vp,8,13,13,0);
   SetRGB4(vp,9,0,13,13);   SetRGB4(vp,10,15,0,15); SetRGB4(vp,11,10,10,0);
   SetRGB4(vp,12,8,8,8);    SetRGB4(vp,13,5,5,0);   SetRGB4(vp,14,0,10,15);
   SetRGB4(vp,15,15,8,0);
}

/********/
InitWind()
{
   screen = OpenScreen(&newscreen);
   newwindow.Screen = screen; window = OpenWindow(&newwindow);
   rp = window->RPort; vp = &window->WScreen->ViewPort;
   SetDrMd(rp,JAM1); SetAPen(rp,1);
   InitColors(); return(1);
}


/*** MENUS **********************************************************/
#define MICFlags (ITEMENABLED | ITEMTEXT | HIGHCOMP | COMMSEQ)
#define MIFlags (ITEMENABLED | ITEMTEXT | HIGHCOMP)

/*** MENU 1 ***/
struct IntuiText M_text19 = {1,14,JAM2,0,0,NULL,"XYRegionLock ",NULL};
struct MenuItem	M_item19 = {
   NULL, 0, 9*CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MIFlags,
   0L, (APTR)&M_text19, NULL, NULL, NULL, 0};
#define MI_XYREGIONLOCK 9

struct IntuiText M_text18OFF = {1,14,JAM2,0,0,NULL,"YRegionLock ",NULL};
struct IntuiText M_text18ON = {1,14,JAM2,0,0,NULL,"YRegionLOCK ",NULL};
struct MenuItem	M_item18 = {
   &M_item19, 0, 8*CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MIFlags,
   0L, (APTR)&M_text18OFF, NULL, NULL, NULL, 0};
#define MI_YREGIONLOCK 8

struct IntuiText M_text17OFF = {1,14,JAM2,0,0,NULL,"XRegionLock ",NULL};
struct IntuiText M_text17ON = {1,14,JAM2,0,0,NULL,"XRegionLOCK ",NULL};
struct MenuItem	M_item17 = {
   &M_item18, 0, 7*CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MIFlags,
   0L, (APTR)&M_text17OFF, NULL, NULL, NULL, 0};
#define MI_XREGIONLOCK 7

struct IntuiText M_text16 = {1,14,JAM2,0,0,NULL,"White BG     ",NULL};
struct MenuItem	M_item16 = {
   &M_item17, 0, 6*CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text16, NULL, 'l', NULL, 0};
#define MI_WHITEBG 6

struct IntuiText M_text15 = {1,14,JAM2,0,0,NULL,"Axes         ",NULL};
struct MenuItem	M_item15 = {
   &M_item16, 0, 5*CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text15, NULL, 'a', NULL, 0};
#define MI_AXES 5

struct IntuiText M_text14 = {1,14,JAM2,0,0,NULL,"Grid         ",NULL};
struct MenuItem	M_item14 = {
   &M_item15, 0, 4*CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text14, NULL, 'g', NULL, 0};
#define MI_GRID 4

struct IntuiText M_text13 = {1,14,JAM2,0,0,NULL,"NewData      ",NULL};
struct MenuItem	M_item13 = {
   &M_item14, 0, 3*CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text13, NULL, 'n', NULL, 0};
#define MI_NEWDATA 3

struct IntuiText M_text12 = {1,14,JAM2,0,0,NULL,"FullPlot     ",NULL};
struct MenuItem	M_item12 = {
   &M_item13, 0, 2*CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text12, NULL, 'f', NULL, 0};
#define MI_FULLPLOT 2

struct IntuiText M_text11 = {1,14,JAM2,0,0,NULL,"Zoom         ",NULL};
struct MenuItem	M_item11 = {
   &M_item12, 0, CHARHEIGHT, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text11, NULL, 'z', NULL, 0};
#define MI_ZOOM 1

struct IntuiText M_text10 = {1,14,JAM2,0,0,NULL,"CrossHair     ",NULL};
struct MenuItem	M_item10 = {
   &M_item11, 0, 0, CHARWIDTH*14 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text10, NULL, 'h', NULL, 0};
#define MI_XHAIR 0

struct Menu Menu1 = {
   NULL, CHARWIDTH*12 + COMMWIDTH, 0, CHARWIDTH*14, CHARHEIGHT, MENUENABLED,
   "Options     ", &M_item10};
#define M_OPTIONS 1

/*** MENU 0 ***/
struct IntuiText M_text03 = {1,14,JAM2,0,0,NULL,"Quit        ",NULL};
struct MenuItem	M_item03 = {
   NULL, 0, 3*CHARHEIGHT, CHARWIDTH*12 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text03, NULL, 'q', NULL, 0};
#define MI_QUIT 3

struct IntuiText M_text02 = {1,14,JAM2,0,0,NULL,"Mk mCADFile ",NULL};
struct MenuItem	M_item02 = {
   &M_item03, 0, 2*CHARHEIGHT, CHARWIDTH*12 + COMMWIDTH, CHARHEIGHT, MIFlags,
   0L, (APTR)&M_text02, NULL, NULL, NULL, 0};
#define MI_MKMCADFILE 2

struct IntuiText M_text01 = {1,14,JAM2,0,0,NULL,"Mk PlotFile ",NULL};
struct MenuItem	M_item01 = {
   &M_item02, 0, CHARHEIGHT, CHARWIDTH*12 + COMMWIDTH, CHARHEIGHT, MIFlags,
   0L, (APTR)&M_text01, NULL, NULL, NULL, 0};
#define MI_MKPLOTFILE 1

struct IntuiText M_text00 = {1,14,JAM2,0,0,NULL,"Replot      ",NULL};
struct MenuItem	M_item00 = {
   &M_item01, 0, 0, CHARWIDTH*12 + COMMWIDTH, CHARHEIGHT, MICFlags,
   0L, (APTR)&M_text00, NULL, 'r', NULL, 0};
#define MI_REPLOT 0

struct Menu Menu0 = {
   &Menu1, 0, 0, CHARWIDTH*12+COMMWIDTH, CHARHEIGHT, MENUENABLED,
   "  Project   ", &M_item00};
#define M_PROJECT 0
/***************************************************************************/

/*************/
void InitMenu()
{SetMenuStrip(window,&Menu0); ShowTitle(screen,FALSE);}


/************/
void CleanUp()
{ClearMenuStrip(window); CloseWindow(window); CloseScreen(screen);}


/************************/
void AttrOnOff(Pict, item)
struct Pict *Pict;
int item;
{
   ClearMenuStrip(window);
   switch(item) {
   case MI_XREGIONLOCK:
      M_item17.ItemFill = (APTR)(Pict->XRegionLock ? &M_text17ON : &M_text17OFF);
      break;
   case MI_YREGIONLOCK:
      M_item18.ItemFill = (APTR)(Pict->YRegionLock ? &M_text18ON : &M_text18OFF);
      break;
   default: break;
   }
   SetMenuStrip(window, &Menu0);
}


/**************************************************************************/
void PToU();

USHORT InvisPtr[] = {
   0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0,
   0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0};

static short XHair = FALSE;
static short WhiteBG = FALSE;

/*****************/
void PutXHair(x,y)
short x,y;
{Move(rp,0,y); Draw(rp,MAXHORIZ,y); Move(rp,x,0); Draw(rp,x,MAXVERT);}

/**************************/
void GetXHair(x,y)
short *x, *y;
{SetPointer(window,InvisPtr,9,9,0,0); SetDrMd(rp,COMPLEMENT); PutXHair(*x,*y);}

/***********************/
void KillXHair(x,y)
short x,y;
{ClearPointer(window); PutXHair(x,y); SetDrMd(rp,JAM1);}

/*****************************/
void RubberBox(x1, y1, x2, y2)
short *x1, *y1, *x2, *y2;
{
   Move(rp,x1,y1);
   if (XHair) {Draw(rp,x1,y2); Move(rp,x1,y1); Draw(rp,x2,y1);}
   else {Draw(rp,x1,y2); Draw(rp,x2,y2); Draw(rp,x2,y1); Draw(rp,x1,y1);}
}

#define NO_OBJECT 0
#define REGION 1
#define LINE 2
#define BOX 3

/*************/
CheckUser(Pict)
struct Pict *Pict;
{
   ULONG class;
   USHORT code;
   int retval = NOACTION, MouseMoved;
   short x, y, x0, y0, x1, y1;
   short RubberObj = NO_OBJECT, RubberBand = FALSE;
   FFP XMin, YMin, XMax, YMax;
   struct PlotRegion *Reg;

   InitMenu();
   AttrOnOff(Pict, MI_XREGIONLOCK);
   AttrOnOff(Pict, MI_YREGIONLOCK);
   x = y = 0;
   if (XHair) {GetXHair(&x,&y); x1 = x; y1 = y;}
   if (WhiteBG) SetRGB4(vp,0,15,15,15);
   do {
      Wait(1 << window->UserPort->mp_SigBit);

      while (msg = (struct IntuiMessage *) GetMsg(window->UserPort) ) {
         class = msg->Class;
         MouseMoved = (class == MOUSEMOVE);
         code = msg->Code; x = msg->MouseX; y = msg->MouseY;
         ReplyMsg(msg);

         if ((class == MENUPICK) && (code != MENUNULL)) {
            switch (MENUNUM(code)) {
            case M_PROJECT:
               switch(ITEMNUM(code)) {
               case MI_REPLOT:      retval = REPLOT; break;
               case MI_QUIT:        retval = QUIT; break;
               case MI_MKPLOTFILE:  WrtPlt(Pict); break;
               case MI_MKMCADFILE:  To_mCAD(Pict); break;
               default: break;
               }
               break;
            case M_OPTIONS:
               switch (ITEMNUM(code)) {
               case MI_XHAIR:
                  if (XHair = !XHair) {GetXHair(&x,&y); x1=x; y1=y;}
                  else KillXHair(x1,y1);
                  break;
               case MI_ZOOM:        RubberObj = REGION; break;
               case MI_NEWDATA:     retval = GETHOWTO; break;
               case MI_FULLPLOT:    retval = GETDATALIMITS; break;
               case MI_GRID:        Pict->Grid = !Pict->Grid; break;
               case MI_AXES:        Pict->Axes = !Pict->Axes; break;
               case MI_WHITEBG:
                  if (WhiteBG = !WhiteBG) SetRGB4(vp,0,15,15,15);
                  else SetRGB4(vp,0,15,10,5);
                  break;
               case MI_XYREGIONLOCK:
                  Pict->XRegionLock=Pict->YRegionLock=TRUE;
                  AttrOnOff(Pict, MI_XREGIONLOCK);
                  AttrOnOff(Pict, MI_YREGIONLOCK);
                  break;
               case MI_YREGIONLOCK:
                  Pict->YRegionLock=!Pict->YRegionLock;
                  AttrOnOff(Pict, MI_YREGIONLOCK);
                  break;
               case MI_XREGIONLOCK:
                  Pict->XRegionLock=!Pict->XRegionLock;
                  AttrOnOff(Pict, MI_XREGIONLOCK);
                  break;
               default: break;
               }
               break;

            default: break;

            } /* switch */
         } /* if ((class == MENUPICK) ...*/
         else if (class == MOUSEBUTTONS) {
               switch (code) {
               case SELECTUP: break;
               case SELECTDOWN:
                  if (RubberObj && !RubberBand) { /* BEGIN RUBBERBAND */
                     RubberBand = TRUE; x0 = x1 = x; y0 = y1 = y;
                     SetDrMd(rp,COMPLEMENT); window->Flags |= RMBTRAP;
                     if (RubberObj == BOX || RubberObj == REGION)
                        RubberBox(x0,y0,x,y);
                  }
                  else { /* END RUBBERBAND */
                     RubberBand = FALSE;
                     if (RubberObj == BOX || RubberObj == REGION) {
                        RubberBox(x0,y0,x1,y1);
                        if (RubberObj == REGION) {
                           PToU(Pict,min(x0,x),MAXVERT-max(y0,y),&XMin,&YMin);
                           PToU(Pict,max(x0,x),MAXVERT-min(y0,y),&XMax,&YMax);
                           Reg = Pict->CurrReg;
                           if (!Pict->XRegionLock)
                              {Reg->XMin = XMin; Reg->XMax = XMax;}
                           if (!Pict->YRegionLock)
                              {Reg->YMin = YMin; Reg->YMax = YMax;}
                           retval = REPLOT;
                        }
                     }
                     if (!XHair) SetDrMd(rp,JAM1);
                     window->Flags &= 0xFFFFFFFF ^ RMBTRAP;
                     RubberObj = NO_OBJECT;
                     /* Draw object if applicable */
                  }
                  break;
               case MENUDOWN: /* ABORT RUBBERBAND */
                  RubberBand = FALSE; window->Flags &= 0xFFFFFFFF ^ RMBTRAP;
                  if (RubberObj == BOX || RubberObj == REGION)
                     RubberBox(x0,y0,x1,y1);
                  break;
               default: break;
            } /* switch (code) */
            break;
         } /* else if (class == MENUBUTTONS) */
      } /* while */
      
      if (MouseMoved && ((x1!=x) || (y1!=y)) ) {
         if (XHair)
               {PutXHair(x1,y1); PutXHair(x,y);}
         if (RubberBand) {
            if (RubberObj == BOX || RubberObj == REGION)
               {RubberBox(x0,y0,x1,y1); RubberBox(x0,y0,x,y);}
         }
         x1 = x; y1 = y;
      }
   } while(retval == NOACTION);

   CleanUp();
   return(retval);
}
