/*
 *   This is the main routine from BlitLab.
 */
#include "structures.h"
/*
 *   Here are all the globals we use.  (Yuck!  Globals!)
 */
struct Window *mywindow ;
struct GfxBase *GfxBase ;
struct IntuitionBase *IntuitionBase ;
struct RastPort *myrp ;
char strings[900] ;
char *bufarr[MAXGADG] ;
long gvals[MAXGADG] ;
struct Gadget *gadgets[MAXGADG] ;
char errorbuf[140] ;
short *realbits ;
struct blitregs blitregs ;
int errortitle ;
/*
 *   Externals we use:
 */
extern int blitsafe() ;
/*
 *   Some statics to this module.
 */
static int updatethem ;
/*
 *   Errors go through here.  Currently, we write to the CLI window.
 *   Later, we will write to the title bar of the window.
 */
error(s)
char *s ;
{
   if (mywindow == NULL || *s == '!')
      printf("blitlab: %s\n", s) ;
   else {
      SetWindowTitles(mywindow, s, -1L) ;
      errortitle = 1 ;
   }
   if (*s == '!')
      cleanup() ;
}
/*
 *   This routine handles a gadget selection.
 */
handlegadget(gp)
register struct Gadget *gp ;
{
   static int gocount = 0 ;

   if (errortitle == 1) {
      SetWindowTitles(mywindow, BANNER, -1L) ;
      errortitle = 0 ;
   }
   if (bufarr[gp->GadgetID] == NULL)
   switch(gp->GadgetID) {
      case GDGPNTREG:
      case GDGCLRSET:
      case GDGLINE:
      case GDGDESC:
      case GDGFCI:
      case GDGIFE:
      case GDGEFE:
      case GDGUSEA:
      case GDGUSEB:
      case GDGUSEC:
      case GDGUSED:
      case GDGOVF:
      case GDGSIGN:
         flipgadg(gp->GadgetID) ;
         break ;
      case GDGCALC:
         parseall() ;
         updatethem = 0 ;
         if (!blitsafe()) {
            error("Blit unsafe.") ;
         }
         break ;
      case GDGSETUP:
         setupline() ;
         parseall() ;
         break ;
      case GDGGO:
         gocount += 2 ;
         parseall() ;
         updatethem = 0 ;
         if (!blitsafe()) {
            if (gocount < 3)
               error("Blit unsafe---hit again to override") ;
            else {
               doblit() ;
               updatebits() ;
            }
         } else {
            doblit() ;
            updatebits() ;
         }
         break ;
      default:
         error("! bad value in gadget switch") ;
         break ;
   }
   if (gocount > 0)
      gocount-- ;
}
/*
 *   The main routine, no arguments.  Sets things up, and then goes
 *   through the standard Intuition message loop.
 *
 *   It may look like I'm setting message to NULL and checking it and
 *   everything all over, but that is so I can introduce interruptibility
 *   into some operations later, if I choose.
 */
main() {
   struct IntuiMessage *message = NULL ;
   int x, y ;
   int mousemoved = 0 ;
   int getouttahere = 0 ;
   int selectdown = 0 ;
   int bam ;
   int ox, oy ;

   initialize() ;
   while (1) {
      mousemoved = 0 ;
      bam = 0 ;
      if (message == NULL)
         WaitPort(mywindow->UserPort) ;
      while (message || (message = 
                       (struct IntuiMessage *)GetMsg(mywindow->UserPort))) {
         x = message->MouseX ;
         y = message->MouseY ;
         if (message->Class == MOUSEMOVE) {
            ReplyMsg(message) ;
            message = NULL ;
            mousemoved = 1 ;
         } else {
            if (message->Class == MOUSEBUTTONS) {
               selectdown = (message->Code == SELECTDOWN) ;
               bam = 1 ;
            } else if (message->Class == GADGETDOWN || 
                       message->Class == GADGETUP) {
               updatethem = 1 ;
               handlegadget((struct Gadget *)(message->IAddress)) ;
            } else if (message->Class == CLOSEWINDOW) {
               getouttahere = 1 ;
            } else
               error("! undefined message class") ;
            ReplyMsg(message) ;
            message = NULL ;
         }
      }
      if (getouttahere)
         break ;
      if (updatethem) {
         parseall() ;
         updatethem = 0 ;
      }
      x = (x - HBITSTART) / 6 ;
      y = (y - VBITSTART) / 3 ;
      if (y < 32 && x < 96 && x >= 0 && y >= 0) {
         if (gvals[GDGPNTREG]) {
            if (bam) {
               if (selectdown) {
                  ox = x ;
                  oy = y ;
               } else {
                  preg(ox, oy, x, y, (int)gvals[GDGCLRSET]) ;
               }
            }
         } else {
            if (selectdown)
               pdot(x, y, (int)gvals[GDGCLRSET]) ;
         }
         if (message != NULL || (message = 
               (struct IntuiMessage *)GetMsg(mywindow->UserPort))) ;
         else
            updatepos(x, y) ;
      }      
   }
   cleanup() ;
}
