/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* |_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"

#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 IntuiText MiscText[];
extern struct Menu Titles[], EditTitles[], ORCTitles[];
extern struct Gadget colgads[];

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

extern struct Border Borders[];

extern struct iconfont *fonts[2];
extern int fontnum,hires;
extern USHORT colormap[];

char *hexchars = "0123456789ABCDEF";

void DrawEdit(EditWindow, tempdata)
struct Window *EditWindow;
USHORT *tempdata;
{
   short x, y, ix, iy, im, mask, xmask;
   static int colornum[16]    = {0, 8, 4, 12, 2, 10, 6, 14,
                                 1, 9, 5, 13, 3, 11, 7, 15};
   int tmpint;

   for(x=EDXLEFT, ix=0; ix<IWIDTH; x+=ELWIDTH, ix++)
   {
      xmask = 0x8000 >> ix;
      for(y=EDYTOP, iy=0; iy<IHEIGHT; y+=ELHEIGHT, iy++)
      {
         tmpint = iy;
         for(mask=im=0; im<IDEPTH; im++, tmpint+=IHEIGHT)
         {
            mask |= ((xmask & tempdata[tmpint]) >> (12-ix+im));
         }
         SetAPen(EditWindow->RPort,colornum[mask]);
         RectFill(EditWindow->RPort, x, y, x+ELWIDTH-1, y+ELHEIGHT-1);
      }
   }
BUG(1, ("DrawEdit: Exit\n"))
}

void FlipX(data)
register USHORT *data;
{
   int offset, x;
   USHORT tmpdata[ILENGTH];

   movmem(data, tmpdata, ILENGTH*sizeof(USHORT));
   setmem(data, ILENGTH*sizeof(USHORT), 0);
   for(offset = 0; offset < ILENGTH; offset++)
   {
      for(x=0; x<IWIDTH; x++)
      {
         if(tmpdata[offset] & (0x8000 >> x))
         data[offset] |= (0x8000 >> (IWIDTH-1 - x));
      }
   }
}

void FlipY(data)
register USHORT *data;
{
   int depth, offset, y;
   USHORT tmpdata[ILENGTH];
   
   movmem(data, tmpdata, ILENGTH*sizeof(USHORT));
   setmem(data, ILENGTH*sizeof(USHORT), 0);
   for(offset=depth=0; depth<IDEPTH; depth++, offset+=IHEIGHT)
      for(y=0; y<IHEIGHT; y++)
         data[offset+y] = tmpdata[offset+IHEIGHT-1-y];
}

void Rotate(data, plus)
register USHORT *data;
int plus;
{
   USHORT mask;
   int depth, off1, off2, x, y;
   USHORT tmpdata[ILENGTH];

   movmem(data, tmpdata, ILENGTH*sizeof(USHORT));
   setmem(data, ILENGTH*sizeof(USHORT), 0);
   for(depth=off1=0; depth<IDEPTH; depth++, off1+=IHEIGHT)
   {
      mask = (plus ? 0x8000 >> (IWIDTH-1): 0x8000);
      for(off2=off1, y=0; y<IHEIGHT; off2++, y++)
      {
         for(x=0; x<IWIDTH; x++) 
	 {
	    if(tmpdata[off1+x] & mask)
               data[off2] |= (plus ? (0x8000 >> x)  
                                   :(0x8000 >> (IWIDTH-1-x) ) );
         }
         mask = (plus ? mask << 1 : mask >> 1);
      }
   }
}

void UDShift(data, up)
register USHORT *data;
int up;
{
   register int end, incr, y, offset;
   int start;

   if(up)
   {
      start = 0;
      end   = IHEIGHT-1;
      incr  = 1;
   }
   else
   {
      start = IHEIGHT-1;
      end   = 0;
      incr  = -1;
   }

   for(offset=0; offset<ILENGTH; offset+=8)
   {
      for(y=start; y!=end; y+=incr)
         data[offset + y] = data[offset + y + incr];

      data[offset + y] = 0;
   }
}

void LRShift(data, left)
register USHORT *data;
int left;
{
   int i;
   
   if(left) for(i=0; i<ILENGTH; i++) data[i] <<= 1;
   else     for(i=0; i<ILENGTH; i++)
   {
      data[i] >>= (16 - IWIDTH + 1);
      data[i] <<= (16 - IWIDTH);
   }
}


EditIcon(which)
int which;
{
   register struct Image *tempimage, *update;
   register USHORT *tempdata;

   struct NewWindow *NewWindow;
   struct Window *EditWindow;
   struct Gadget *Gadget;
   struct IntuiMessage *imsg;
   short draw, inum, tmpint;
   char WindowTitle[10];
   int editmode;

   USHORT x, y, Code, curcolor;
   ULONG Class, mask;

   BUG(1, ("EditIcon: Enter, # %d\n", which))

   editmode = 1;
   curcolor = colormap[0];
   if(!fonts[fontnum]) LoadFont("Characters", -1);
   if(fonts[fontnum]->firstchar > which) fonts[fontnum]->firstchar = which;
   if(fonts[fontnum]->lastchar  < which) fonts[fontnum]->lastchar  = which;

   /* Disable Menus */
   ClearMenuStrip(Window);

   if(!(NewWindow = (struct NewWindow *)
            AllocMem(sizeof(struct NewWindow), MEMF_CHIP | MEMF_CLEAR))
   || !(tempimage = (struct Image *)
            AllocMem(sizeof(struct Image), MEMF_CHIP | MEMF_CLEAR))
   || !(tempdata = (USHORT *)
            AllocMem(ILENGTH*sizeof(USHORT), MEMF_CHIP | MEMF_CLEAR))
     )
   {
      AutoRequest(Window, &MiscText[3], NULL, &MiscText[2], 0, 0, 410, 90);
      return(1);
   }

   NewWindow->LeftEdge = SWIDTH/4;
   NewWindow->TopEdge = SHEIGHT/4;
   NewWindow->Width  = CESWIDTH;
   NewWindow->Height = CESHEIGHT;
   NewWindow->DetailPen = 1;
   NewWindow->BlockPen  = 2;
   NewWindow->IDCMPFlags  = (MOUSEBUTTONS  | MOUSEMOVE | GADGETUP | MENUPICK);
   NewWindow->Flags = (SMART_REFRESH | ACTIVATE | REPORTMOUSE | WINDOWDRAG);
#if 0
   NewWindow->Title = (UBYTE *)"Edit Window";
#else
   NewWindow->Title = WindowTitle;
   strcpy(NewWindow->Title, "Edit ' '");
   if(which>33 && which<126) 
      NewWindow->Title[6] = which;
   else
   {
      NewWindow->Title[5] = '$';
      NewWindow->Title[6] = hexchars[(UBYTE)((0xf0 & (UBYTE)(which)) >> 4)];
      NewWindow->Title[7] = hexchars[(UBYTE)(0x0f & which)];
   }
#endif
   NewWindow->Screen = Screen;
   NewWindow->MinWidth  =
   NewWindow->MaxWidth  = SWIDTH/2;
   NewWindow->MinHeight =
   NewWindow->MaxHeight = SHEIGHT/2;
   NewWindow->Type = CUSTOMSCREEN;
   NewWindow->FirstGadget = colgads;

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

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

   LoadRGB4(ViewPortAddress(EditWindow), colormap, 16);
BUG(9, ("EditIcon: Colors loaded\n"))

   ORCTitles[0].NextMenu = EditTitles;
   SetMenuStrip(EditWindow, ORCTitles);
BUG(9, ("EditIcon: Menus set\n"))

   movmem((char *)(fonts[fontnum]->idata+(which*ILENGTH)),
          (char *)tempdata,
          ILENGTH*sizeof(USHORT));
BUG(9, ("EditIcon: icon data moved\n"))

   tempimage->LeftEdge = EDXLEFT - 3*IWIDTH;
   tempimage->TopEdge  = EDYTOP + (EDHEIGHT-IHEIGHT)/2;
   tempimage->Width    = IWIDTH;
   tempimage->Height   = IHEIGHT;
   tempimage->Depth    = IDEPTH;
   tempimage->ImageData = tempdata;
   tempimage->PlanePick = 0x0F;
   tempimage->PlaneOnOff= 0x00;
   tempimage->NextImage = NULL;
BUG(9, ("EditIcon: tempimage initialized\n"))

   DrawBorder(EditWindow->RPort, Borders, 0, 0);
   if(hires) DrawBorder(EditWindow->RPort, &Borders[1], PLXWIDTH+3, 0);
   DrawImage(EditWindow->RPort, tempimage, 0, 0);
   DrawEdit(EditWindow, tempdata);

   draw = 0;

   while(editmode)
   {
      if(!(imsg = (struct IntuiMessage *)GetMsg(EditWindow->UserPort)))
      {
         WaitPort(EditWindow->UserPort);
         continue;
      }
      Class  = imsg->Class;
      Code   = imsg->Code;
      x      = imsg->MouseX;
      y      = imsg->MouseY;
      Gadget = (struct Gadget *)imsg->IAddress;
      ReplyMsg(imsg);
BUG(9, ("EditIcon: Message class is %d\n", Class))

      switch(Class)
      {

         case MOUSEBUTTONS:
            BUG(1, ("EditIcon: case MOUSEBUTTONS\n"))
            if(Code == SELECTUP)
            {
               draw = 0;
               break;
            }
            draw = 1;
            /* Fall through to MOUSEMOVE */

         case MOUSEMOVE:
            if(!draw
            || x < EDXLEFT || x >= (EDXLEFT+EDWIDTH)
            || y < EDYTOP  || y >= (EDYTOP+EDHEIGHT)) break;

            mask = 0x8000 >> (x = (x - EDXLEFT)/ELWIDTH);
            tmpint = y = (y - EDYTOP)/ELHEIGHT;

            for(inum=0; inum<IDEPTH; inum++, tmpint+=IHEIGHT)
            {
               if(curcolor & (0x0001 << inum) ) tempdata[tmpint] |= mask;
               else tempdata[tmpint] &= (~mask);
            }
            DrawImage(EditWindow->RPort, tempimage, 0, 0);
            x = x*ELWIDTH + EDXLEFT;
            y = y*ELHEIGHT + EDYTOP;
            SetAPen(EditWindow->RPort, curcolor);
            RectFill(EditWindow->RPort, x, y, x+ELWIDTH-1, y+ELHEIGHT-1);

            break;

         case GADGETUP:
            curcolor = Gadget->GadgetID;
            BUG(5, ("EditIcon: Color gadget # %d\n", curcolor))
            break;
            
         case MENUPICK:
            BUG(5, ("EditIcon: case MENUPICK\n"))
            if(Code == MENUNULL) break;

BUG(8, ("EditIcon: menu=%d, item=%d, sub=%d\n", MENUNUM(Code),ITEMNUM(Code), SUBNUM(Code)))

            if(!MENUNUM(Code))
            {
               switch(ITEMNUM(Code))
               {
                  case ME_SAVE:
                     BUG(5, ("EditIcon: Save\n"))
                     movmem((char *)tempdata,
                            (char *)(fonts[fontnum]->idata+(which*ILENGTH)),
                            ILENGTH*sizeof(USHORT));
                     update = fonts[fontnum]->images + which;
                     update->NextImage = NULL;
                     DrawImage(Window->RPort, update, 0, 0);
                     fonts[fontnum]->flags |= CHANGED;
                     if(which != 255) update->NextImage = update+1;
                     editmode = 0;
                     break;

                  case ME_QUIT:
                     BUG(5, ("EditIcon: Cancel\n"))
                     editmode = 0;
                     break;
                     
                  case ME_RESET:
                     BUG(5, ("EditIcon: Reset\n"))
                     movmem((char *)(fonts[fontnum]->idata+(which*ILENGTH)),
                            (char *)tempdata,
                            ILENGTH*sizeof(USHORT));
                     DrawImage(EditWindow->RPort, tempimage, 0, 0);
                     DrawEdit(EditWindow, tempdata);
                     break;
               }
               break;
            }
            switch(ITEMNUM(Code))
            {
               case ME_FLIP:
                  switch(SUBNUM(Code))
                  {
                     case ME_XFLIP:
                        FlipX(tempdata);
                        break;
                     case ME_YFLIP:
                        FlipY(tempdata);
                        break;
                  }
                  break;

               case ME_ROTATE:
                  switch(SUBNUM(Code))
                  {
                     case ME_180ROT:
                        Rotate(tempdata, 1);
                     case ME_POSROT:
                        Rotate(tempdata, 1);
                        break;
                     case ME_NEGROT:
                        Rotate(tempdata, 0);
                        break;
                  }
                  break;

               case ME_SHIFT:
                  switch(SUBNUM(Code))
                  {
                     case ME_LSHIFT:
                        LRShift(tempdata, 1);
                        break;

                     case ME_RSHIFT:
                        LRShift(tempdata, 0);
                        break;
                  
                     case ME_USHIFT:
                        UDShift(tempdata, 1);
                        break;
                  
                     case ME_DSHIFT:
                        UDShift(tempdata, 0);
                        break;
                  }
                  break;
                  
            }
            DrawImage(EditWindow->RPort, tempimage, 0, 0);
            DrawEdit(EditWindow, tempdata);
            break;

         default:
            BUG(1, ("EditIcon: Unknown Class = %d\n", Class))
            break;
      }
   }

   /* Clear the regular window's messages */
   while(imsg = (struct IntuiMessage *)GetMsg(Window->UserPort))
      ReplyMsg(imsg);

   /* Enable Menus */
   ClearMenuStrip(EditWindow);
   SetMenuStrip(Window, Titles);

   CloseWindow(EditWindow);
   FreeMem(tempdata, ILENGTH*sizeof(USHORT));
   FreeMem(tempimage, sizeof(struct Image));

   BUG(1, ("EditIcon: Exit\n"))
   return(0);
}


