/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* |_o_o|\\ Copyright (c) 1987 The Software Distillery.  All Rights Reserved *
* |. o.| ||          Written by Doug Walker                                 *
* | .  | ||          The Software Distillery                                *
* | o  | ||          235 Trillingham Lane                                   *
* |  . |//           Cary, NC 27511                                         *
* ======             BBS:(919)-471-6436                                     *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "mydebug.h"

#ifdef MYDEBUG
int debug = 0;
#endif

#include "exec/types.h"
#include "exec/memory.h"
#include "intuition/intuition.h"
#include "graphics/gfxbase.h"
#include "stdio.h"

#include "hackicon.h"

extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;

extern struct Menu Titles[];
extern struct Gadget colgads[];
extern struct IntuiText AboutText[];
extern char TextBuffer[];
extern struct Requester NameRequester;
extern struct Gadget Req_gads[];
extern struct Border Req_Bords[];
extern struct IntuiText Load_text, Save_text;

struct Screen   *Screen;
struct Window   *Window;
struct ViewPort *ViewPort;

struct iconfont *fonts[2];
int fontnum = 0;
int hires = 0;

USHORT colormap[16] = {0x0000, 0x000f, 0x00f0, 0x0f00,
                       0x00ff, 0x0f0f, 0x0ff0, 0x0fff,
                       0x0000, 0x000f, 0x00f0, 0x0f00,
                       0x00ff, 0x0f0f, 0x0ff0, 0x0fff
                      };


init()
{
   struct NewScreen *NewScreen;
   struct NewWindow *NewWindow;

     BUG(1, ("init: enter\n"))

   if(!(NewScreen = (struct NewScreen *)
            AllocMem(sizeof(struct NewScreen), MEMF_CHIP | MEMF_CLEAR))
      || !(NewWindow = (struct NewWindow *)
            AllocMem(sizeof(struct NewWindow), MEMF_CHIP | MEMF_CLEAR))
     )
      panic("Not enough memory for screens!\n");

   if(! (IntuitionBase = (struct IntuitionBase *)
              OpenLibrary("intuition.library", I_REV)) )
      panic("Can't open intuition.library!\n");

   if(! (GfxBase = (struct GfxBase *)
              OpenLibrary("graphics.library", I_REV)) )
      panic("Can't open graphics.library!\n");


   NewScreen->Width  = SWIDTH;
   NewScreen->Height = SHEIGHT;
   NewScreen->Depth  = SDEPTH;
   NewScreen->DetailPen = 1;
   NewScreen->BlockPen  = 2;
   NewScreen->ViewModes = HIRES;
   NewScreen->Type   = CUSTOMSCREEN;
   NewScreen->DefaultTitle  = (UBYTE *)"HackIcon II - Copyright (c) 1987 The Software Distillery";

   Screen = (struct Screen *) OpenScreen(NewScreen);
BUG(9, ("init: Screen open\n"))

   FreeMem(NewScreen, sizeof(struct NewScreen));
BUG(9, ("init: newscreen mem freed\n"))

   NewWindow->Width  = SWIDTH;
   NewWindow->Height = SHEIGHT;
   NewWindow->DetailPen = 1;
   NewWindow->BlockPen  = 2;
   NewWindow->IDCMPFlags  = (MOUSEBUTTONS  | MENUPICK | GADGETUP);
   NewWindow->Flags = (SMART_REFRESH | BACKDROP | BORDERLESS | ACTIVATE);
   NewWindow->Title = NULL;
   NewWindow->Screen = Screen;
   NewWindow->MinWidth  =
   NewWindow->MaxWidth  = SWIDTH;
   NewWindow->MinHeight =
   NewWindow->MaxHeight = SHEIGHT;
   NewWindow->Type = CUSTOMSCREEN;

   Window = (struct Window *)OpenWindow(NewWindow);
BUG(9, ("init: Window open\n"))

   FreeMem(NewWindow, sizeof(struct NewWindow));
BUG(9, ("init: newwindow mem freed\n"))

   ViewPort = (struct ViewPort *)ViewPortAddress(Window);

   LoadRGB4(ViewPort, colormap, 16);

   DisplayLabels();

BUG(9, ("init: setting menu labels\n"))
BUGGETC(9)
   SetMenuStrip(Window, Titles);

   BUG(1, ("init: exit\n"))
   return(0);
}

clean(forced)
int forced;
{
   int i;

   BUG(1, ("clean: Enter\n"))

   if(!forced)
   {
      for(i=0; i<MAXFONTS && fonts[i]; i++)
      {
         if(fonts[i]->flags & CHANGED)
         {
            AboutText[8].IText = fonts[i]->filename;
            if(!AutoRequest(Window, &AboutText[8], &AboutText[11], 
               &AboutText[12], 0, 0, 430, 90))
               return(1);
         }
      }
   }
   CloseWindow(Window);
   CloseScreen(Screen);
   CloseLibrary(GfxBase);
   CloseLibrary(IntuitionBase);

   for(i=0; i<MAXFONTS && fonts[i]; i++)
      FreeMem(fonts[i], sizeof(struct iconfont));

   BUG(1, ("clean: Exit\n"))

   return(0);
}

char *GetName(load)
int load;
{
   ULONG Class;
   USHORT Code;
   struct Gadget *Gadget;
   struct IntuiMessage *imsg;

   BUG(1, ("GetName: Enter\n"))
   
   if(!load && fonts[fontnum]) strcpy(TextBuffer, fonts[fontnum]->filename);
   else strcpy(TextBuffer, "Characters");

   InitRequester(&NameRequester);
   NameRequester.LeftEdge = 10;
   NameRequester.TopEdge = 20;
   NameRequester.Width = 220;
   NameRequester.Height = 90;
   NameRequester.ReqGadget = Req_gads;
   NameRequester.ReqBorder = Req_Bords;
   NameRequester.ReqText = (load ? &Load_text : &Save_text);
   NameRequester.BackFill = 1;

   Request(&NameRequester, Window);

   while(1)
   {
      if(!(imsg = (struct IntuiMessage *)GetMsg(Window->UserPort)))
      {
         WaitPort(Window->UserPort);
         continue;
      }
      Class  = imsg->Class;
      Code   = imsg->Code;
      Gadget = (struct Gadget *)imsg->IAddress;
      ReplyMsg(imsg);
BUG(1, ("GetName: Got message, Class=%d, Code=%d\n", Class, Code))

      if(Class == GADGETUP)
      {
BUG(1, ("GetName: GADGETUP, GadgetID=%d\n", Gadget->GadgetID))
         if(Gadget->GadgetID == G_RCANCEL)
            return(NULL);
         else if(Gadget->GadgetID == G_ROK)
            return(TextBuffer[0] ? TextBuffer : NULL);
      }
   }
   
   return(NULL);
}

WhichIcon(x, y)
short x, y;
{
   int row, col;

   BUG(1, ("WhichIcon: Enter, pos=(%d, %d)\n", (int)x, (int)y))

   if((y-IMYTOP)%IMYSKIP<8) row = (y - IMYTOP) / IMYSKIP;
   else
   {
      BUG(5, ("WhichIcon: bad row, returning -1\n"))
      return(-1);
   }

   if((x-IMXLEFT)%IMXSKIP<8) col = (x - IMXLEFT) / IMXSKIP;
   else
   {
      BUG(5, ("WhichIcon: bad col, returning -1\n"))
      return(-1);
   }

   BUG(5, ("WhichIcon: Exit, row %d col %d returning %d", row, col, row*IMNCOLS + col))

   return(row*IMNCOLS + col);
}

SetFont()
{
   int start;
   start = fontnum;
   while(1)
   {
      if(++fontnum >= MAXFONTS) fontnum = 0;
      if(fontnum == start)
      {
         DisplayBeep((struct SCREEN *)NULL);
         return(1);
      }
      if(fonts[fontnum]) break;
   };
   DrawImage(Window->RPort, fonts[fontnum]->images, 0, 0);
   SetWindowTitles(Window, fonts[fontnum]->filename, fonts[fontnum]->filename);

   return(0);
}

AboutHackicon()
{
   if(!AutoRequest(Window, AboutText, &AboutText[5], &AboutText[6], 0, 0, 
               410, 90))
      while(!AutoRequest(Window, &AboutText[7], &AboutText[5], &AboutText[6],
            0, 0, 410, 90));
   return(0);
}

USHORT heximagedata[] =
{
  0x6000, 0x9000, 0x9000, 0x9000, 0x6000,   /* 0 */
  0x4000, 0xc000, 0x4000, 0x4000, 0xe000,   /* 1 */
  0xe000, 0x1000, 0x6000, 0x8000, 0xf000,   /* 2 */
  0xe000, 0x1000, 0x6000, 0x1000, 0xe000,   /* 3 */
  0xa000, 0xa000, 0xf000, 0x2000, 0x2000,   /* 4 */
  0xf000, 0x8000, 0xe000, 0x1000, 0xe000,   /* 5 */
  0x6000, 0x8000, 0xe000, 0x9000, 0x6000,   /* 6 */
  0xf000, 0x1000, 0x2000, 0x4000, 0x4000,   /* 7 */
  0x6000, 0x9000, 0x6000, 0x9000, 0x6000,   /* 8 */
  0x6000, 0x9000, 0x7000, 0x1000, 0x6000,   /* 9 */
  0x6000, 0x9000, 0xf000, 0x9000, 0x9000,   /* A */
  0xe000, 0x9000, 0xe000, 0x9000, 0xe000,   /* B */
  0x7000, 0x8000, 0x8000, 0x8000, 0x7000,   /* C */
  0xe000, 0x9000, 0x9000, 0x9000, 0xe000,   /* D */
  0xf000, 0x8000, 0xe000, 0x8000, 0xf000,   /* E */
  0xf000, 0x8000, 0xe000, 0x8000, 0x8000    /* F */
};


DisplayLabels()
{
   struct IntuiText Htext;
   struct Image Himage;
   int i, x, y;
   char string[2];

   Himage.Width = Himage.Height = 5;
   Himage.Depth = 1;
   Himage.PlanePick = 0x1;
   Himage.PlaneOnOff = 0x0;
   Himage.NextImage = NULL;
   Htext.IText      = string;
   string[1]       = '\0';
   Htext.ITextFont  = NULL;
   Htext.FrontPen   = 1;
   Htext.BackPen    = 0;
   Htext.DrawMode   = JAM1;
   Htext.NextText   = NULL;

   for(i=0, y=IMYTOP+10; i<256 && y < SHEIGHT-IHEIGHT; y+=IMYSKIP)
   {
      for(x=IMXLEFT-1; x < SWIDTH-IWIDTH && i<256; x +=IMXSKIP, i++)
      {
         if(i<33 || i > 126)
         {
            Himage.LeftEdge = x; Himage.TopEdge = y;
            Himage.ImageData = heximagedata+(5*((0xf0 & (UBYTE) i) >> 4));
            DrawImage(Window->RPort, &Himage, 0, 0);
            Himage.LeftEdge += 6; Himage.TopEdge += 3;
            Himage.ImageData = heximagedata+(5*((0x0f & (UBYTE) i)));
            DrawImage(Window->RPort, &Himage, 0, 0);
         }
         else
         {
            Htext.LeftEdge = x; Htext.TopEdge = y; *string = (UBYTE) i;
            PrintIText(Window->RPort, &Htext, 0, 0);
         }
      }
   }

   return(0);
}

panic(string, a1)
char *string, *a1;
{
   clean(1);
   printf(string, a1);
   exit(1);
   return(0);
}

void main(argc, argv)
int argc;
char *argv[];
{
   struct IntuiMessage *imsg;
   int i, which;
   ULONG Class;
   USHORT Code;
   int MouseX, MouseY;

#ifdef MYDEBUG
   if(argc > 1 && argv[1][0] == '-' && argv[1][1] == 'd')
   {
      debug = argv[1][2] - '0';
      argc--; argv++;
   }
 #endif
 
   init();

   for(; argc > 1; argc--, argv++)
   {
      switch(argv[1][0])
      {
         case '-':
            switch(argv[1][1])
            {
               case 'f':  /* characters filename specification */
               case 'F':
                  argc--; argv++;  /* FORCE the next parm to be name */
                  if(argc > 1) LoadFont(argv[1], -1);
                  else LoadFont("characters", -1);
                  break;

               case 'h':  /* Hi-res mode */
               case 'H':
                  colgads[7].NextGadget = &colgads[8];
                  hires = 1;
                  break;

               default:
                  printf("Unrecognized option '%s'\n", argv[1]);
                  printf("Usage: HackIcon [-f] filename [ [-f] filename] [-h]\n");
                  clean(1);
                  exit(1);
            }
            break;

         default:
            LoadFont(argv[1], -1);
            break;
      }
   }

   BUG(1, ("main: Entry"))

   while(1)
   {
      if(!(imsg = (struct IntuiMessage *)GetMsg(Window->UserPort)))
      {
         WaitPort(Window->UserPort);
         continue;
      }
      Class  = imsg->Class;
      Code   = imsg->Code;
      MouseX = imsg->MouseX;
      MouseY = imsg->MouseY;
      ReplyMsg(imsg);

      switch(Class)
      {
         case MOUSEBUTTONS:
            BUG(5, ("main: case MOUSEBUTTONS\n"))
            if(Code == SELECTDOWN)
               which = WhichIcon(MouseX, MouseY);
            else if(which >= 0 && which == WhichIcon(MouseX, MouseY))
               EditIcon(which);
            break;

         case MENUPICK:
            BUG(5, ("main: case MENUPICK\n"))
            if(Code == MENUNULL) break;

            BUG(8, ("main: menunum = %d\n", MENUNUM(Code)))
            if((i = MENUNUM(Code)) > 0)
            {
               AboutHackicon();
               break;
            }

            BUG(8, ("main: itemnum = %d\n", ITEMNUM(Code)))
            i = ITEMNUM(Code);
            switch(i)
            {
               case M_LOAD:
                  LoadFont(GetName(1), -1);
                  break;

               case M_SAVE:
                  SaveFont(NULL);
                  break;

               case M_SAVEAS:
                  SaveFont(GetName(0), -1);
                  break;

               case M_COLORS:
                  SetColors();
                  break;

               case M_ALTFONT:
                  SetFont();
                  break;

               case M_QUIT:
                  if(!clean(0)) exit(0);
                  break;
                  
               case M_COPY:
                  CopyIcon(0);
                  break;

               case M_MCOPY:
                  CopyIcon(1);
                  break;

               default:
                  break;
            }
            break;

         default:
            break;
      }
   }
   exit(1);
}
