#include "list.h"
#include <graphics/gfxmacros.h>
#include "menu.h"

#ifndef DEBUG
#include <proto/all.h>
#endif


USHORT chip is_PropEndData[] =
   {
   0x0000, 0x8000,    /* ................#............... */
   0x7ffe, 0x0000,    /* .##############................. */
   0x7ffe, 0x0000,    /* .##############................. */
   0x8000, 0x0000,    /* #............................... */

   0x0000, 0x0000,    /* ................................ */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x2aaa, 0x8000,    /* ..#.#.#.#.#.#.#.#............... */
   };

USHORT chip is_PropArrowsData[] =
   {
   0x0000, 0x8000,    /* ................#............... */
   0x7ffe, 0x0000,    /* .##############................. */
   0x7ffe, 0x0000,    /* .##############................. */
   0x7e7e, 0x0000,    /* .######..######................. */
   0x7c3e, 0x0000,    /* .#####....#####................. */
   0x781e, 0x0000,    /* .####......####................. */
   0x7ffe, 0x0000,    /* .##############................. */
   0x7ffe, 0x0000,    /* .##############................. */
   0x0000, 0x0000,    /* ................................ */
   0x7ffe, 0x0000,    /* .##############................. */
   0x7ffe, 0x0000,    /* .##############................. */
   0x0000, 0x0000,    /* ................................ */
   0x7ffe, 0x0000,    /* .##############................. */
   0x7ffe, 0x0000,    /* .##############................. */
   0x781e, 0x0000,    /* .####......####................. */
   0x7c3e, 0x0000,    /* .#####....#####................. */
   0x7e7e, 0x0000,    /* .######..######................. */
   0x7ffe, 0x0000,    /* .##############................. */
   0x7ffe, 0x0000,    /* .##############................. */
   0x8000, 0x0000,    /* #............................... */

   0x0000, 0x0000,    /* ................................ */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0180, 0x8000,    /* .......##.......#............... */
   0x03c0, 0x8000,    /* ......####......#............... */
   0x07e0, 0x8000,    /* .....######.....#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x07e0, 0x8000,    /* .....######.....#............... */
   0x03c0, 0x8000,    /* ......####......#............... */
   0x0180, 0x8000,    /* .......##.......#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x0000, 0x8000,    /* ................#............... */
   0x2aaa, 0x8000,    /* ..#.#.#.#.#.#.#.#............... */
   };

/* === Read Only Data ================================================== */

static USHORT chip Close1Data[] =
   {
   0xffff,    /* ################ */
   0xc003,    /* ##............## */
   0xcff3,    /* ##..########..## */
   0xcff3,    /* ##..########..## */
   0xcff3,    /* ##..########..## */
   0xcff3,    /* ##..########..## */
   0xc003,    /* ##............## */
   0xffff,    /* ################ */

   0x0000,    /* ................ */
   0x3ffc,    /* ..############.. */
   0x300c,    /* ..##........##.. */
   0x300c,    /* ..##........##.. */
   0x300c,    /* ..##........##.. */
   0x300c,    /* ..##........##.. */
   0x3ffc,    /* ..############.. */
   0x0000,    /* ................ */
   };

static USHORT chip Close2Data[] =
   {
   0xffff,    /* ################ */
   0xc003,    /* ##............## */
   0xc3c3,    /* ##....####....## */
   0xcdb3,    /* ##..##.##.##..## */
   0xcdb3,    /* ##..##.##.##..## */
   0xc3c3,    /* ##....####....## */
   0xc003,    /* ##............## */
   0xffff,    /* ################ */

   0x0000,    /* ................ */
   0x3ffc,    /* ..############.. */
   0x3c3c,    /* ..####....####.. */
   0x324c,    /* ..##..#..#..##.. */
   0x324c,    /* ..##..#..#..##.. */
   0x3c3c,    /* ..####....####.. */
   0x3ffc,    /* ..############.. */
   0x0000,    /* ................ */
   };

static USHORT chip Depth1Data[] =
   {
   0xffff,    /* ################ */
   0xc03f,    /* ##........###### */
   0xcf3f,    /* ##..####..###### */
   0xcc03,    /* ##..##........## */
   0xc003,    /* ##............## */
   0xfc03,    /* ######........## */
   0xfc03,    /* ######........## */
   0xffff,    /* ################ */

   0x0000,    /* ................ */
   0x3fc0,    /* ..########...... */
   0x30c0,    /* ..##....##...... */
   0x33fc,    /* ..##..########.. */
   0x3ffc,    /* ..############.. */
   0x03fc,    /* ......########.. */
   0x03fc,    /* ......########.. */
   0x0000,    /* ................ */
   };

static USHORT chip Depth2Data[] =
   {
   0xffff,    /* ################ */
   0xc03f,    /* ##........###### */
   0xc03f,    /* ##........###### */
   0xc003,    /* ##............## */
   0xc0f3,    /* ##......####..## */
   0xfcf3,    /* ######..####..## */
   0xfc03,    /* ######........## */
   0xffff,    /* ################ */

   0x0000,    /* ................ */
   0x3fc0,    /* ..########...... */
   0x3fc0,    /* ..########...... */
   0x3ffc,    /* ..############.. */
   0x3f0c,    /* ..######....##.. */
   0x030c,    /* ......##....##.. */
   0x03fc,    /* ......########.. */
   0x0000,    /* ................ */
   };

static USHORT chip SizeData[] =
   {
   0xfcff,    /* ######..######## */
   0xf3ff,    /* ####..########## */
   0xccff,    /* ##..##..######## */
   0x30ff,    /* ..##....######## */
   0xffff,    /* ################ */

   0x0300,    /* ......##........ */
   0x0c00,    /* ....##.......... */
   0x3300,    /* ..##..##........ */
   0xcf00,    /* ##..####........ */
   0x0000,    /* ................ */
   };

static struct   Image   Close1    = { 0,0, 16,8, 2, Close1Data, 0x03,0x00, NULL };
static struct   Image   Close2    = { 0,0, 16,8, 2, Close2Data, 0x03,0x00, NULL };
static struct   Image   Depth1    = { 0,0, 16,8, 2, Depth1Data, 0x03,0x00, NULL };
static struct   Image   Depth2    = { 0,0, 16,8, 2, Depth2Data, 0x03,0x00, NULL };
static struct   Gadget  SystemGadgets[] =
   {
      { &SystemGadgets[1], -19, 1, 16, 8, GRELRIGHT | GADGIMAGE | GADGHCOMP, RELVERIFY,
        SYSGADGET | WUPFRONT, (APTR)&Depth1, NULL, NULL, NULL, NULL, 0, NULL },
      { &SystemGadgets[2], -39, 1, 16, 8, GRELRIGHT | GADGIMAGE | GADGHCOMP, RELVERIFY,
        SYSGADGET | WDOWNBACK, (APTR)&Depth2, NULL, NULL, NULL, NULL, 0, NULL },
      { NULL, 4, 1, 16, 8, GADGIMAGE | GADGHIMAGE, RELVERIFY,
        SYSGADGET | CLOSE, (APTR)&Close1, (APTR)&Close2, NULL, NULL, NULL, 0, NULL },
   };

struct   Border   st_LRBorder[] =
   {
      { 0, 0, BLACK, 0, JAM1, 4, NULL, NULL },   /* Window Border     */
      { 0, 0, BLACK, 0, JAM1, 5, NULL, NULL },   /* Window Border     */
      { 0, 0, BLUE,  0, JAM1, 2, NULL, NULL },   /* Prop left border  */
   };

struct   Box      st_LRBox[] =
   {
      { NULL, 1, 0,   0,10, BLACK, BLACK, WHITE, 0, NULL, NULL }, /* Title */
/*
      { NULL,  0,0,  62,13,  BLUE, WHITE, BLACK, BLACK, "Cancel", BOX_SHADING },
      { NULL, 17,0,  62,13, YELLW, WHITE, BLACK, BLACK, "Ok",     BOX_SHADING },
*/
      { NULL,  0,0,   0, 0,  BLUE, WHITE,     0, BLACK, "",       BOX_SHADING }     /* Display background */
   };

struct   Image    st_LRImage[] =
   {
      { 0,0, 17, 4, SYSPLANES, is_PropEndData,    0x03, 0x00, NULL },
      { 0,0, 17,20, SYSPLANES, is_PropArrowsData, 0x03, 0x00, NULL },
      { 0,0, 17, 4, SYSPLANES, is_PropEndData,    0x03, 0x00, NULL },
   };


struct   Gadget   st_LRGadget[FILEIO_GADGETS] =
   {
      { NULL, 0,0, 0,10, GRELWIDTH | GADGHNONE, TOPBORDER,
         SYSGADGET | WDRAGGING, NULL, NULL, NULL, NULL, NULL, NULL, NULL, },
      { NULL, 19,0, 58,11, GADGHCOMP, RELVERIFY,
         BOOLGADGET, NULL, NULL, NULL, NULL, NULL, OPENGADGET_CANCEL, NULL, },
      { NULL, 19,0, 58,11, GADGHCOMP, RELVERIFY,
         BOOLGADGET, NULL, NULL, NULL, NULL, NULL, OPENGADGET_OK, NULL, },
      { NULL, 0,0, 14,7, GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
         BOOLGADGET, NULL, NULL, NULL, NULL, NULL, OPENGADGET_UPGADGET, NULL, },
      { NULL, 0,0, 14,7, GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
         BOOLGADGET, NULL, NULL, NULL, NULL, NULL, OPENGADGET_DOWNGADGET, NULL, },
      { NULL, 0,0, 10,0, GADGIMAGE | GADGHNONE, GADGIMMEDIATE | RELVERIFY | FOLLOWMOUSE,
         PROPGADGET, NULL, NULL, NULL, NULL, NULL, OPENGADGET_PROPGADGET, NULL, },
      { NULL, OPENSELECT_LEFT,OPENSELECT_TOP, 0,0, GADGHNONE, GADGIMMEDIATE,
         BOOLGADGET, NULL, NULL, NULL, NULL, NULL, OPENGADGET_SELECTNAME, NULL, },
   };

struct NewWindow st_LRnw =
      {
      0,0,
      0,0,
      BLUE, WHITE,
      GADGETUP | GADGETDOWN | MOUSEMOVE | CLOSEWINDOW | MENUPICK,
      BORDERLESS | SMART_REFRESH | ACTIVATE | NOCAREREFRESH,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
      0,0,
      0,0,
      WBENCHSCREEN,
      };

struct TextAttr  LRSafeFont          = { (UBYTE *)"topaz.font", TOPAZ_EIGHTY, 0, 0 };
struct IntuiText st_LROpenSelectText = { 3, WHITE, JAM2, 1, 0, &LRSafeFont, NULL, NULL, };
struct Image     st_LRPropImage      = { 1, 0, 8, 0, SYSPLANES, NULL, 0x00, WHITE, NULL, };

UBYTE  LRDefaultReqTitle[]   = "iSup Lists Requester";
USHORT LR_Pattern[]          = /* { 0x7f7f, 0x3f3f, 0xdfdf, 0xffff, 0xfdfd, 0xf9f9, 0xf7f7, 0xffff };*/
   {
   0x7b9c,    /* .####.###..###.. */
   0xda7b,    /* ##.##.#..####.## */
   0x3327,    /* ..##..##..#..### */
   0xe5af,    /* ###..#.##.#.#### */
   0x5eac,    /* .#.####.#.#.##.. */
   0xd96a,    /* ##.##..#.##.#.#. */
   0x6b6b,    /* .##.#.##.##.#.## */
   0x1de7,    /* ...###.####..### */
   };

BOOL
ls_AllocateData(list)
register struct ListSupport *list;
{
   register USHORT i;
   SHORT d_width, d_height, width, height;

   d_width  = (list->MaxChars-1)*8 + 6;
   d_height = list->MaxLines*OPEN_LINEHEIGHT;
   width    = d_width + 45;
   height   = d_height + 12 + 14;

   if (  !(list->OpenSelectText = New(struct IntuiText, list->MaxLines))
      || !(list->LRBorder       = New(struct Border,    FILEIO_BORDERS))
      || !(list->LRBox          = New(struct Box,       FILEIO_BOXES))
      || !(list->LRImage        = New(struct Image,     FILEIO_IMAGES))
      || !(list->LRGadget       = New(struct Gadget,    FILEIO_GADGETS))
      )
      {
      ls_DeleteData(list);
      return(FALSE);
      }

   CopyMem(st_LRBorder, list->LRBorder, sizeof(struct Border)*FILEIO_BORDERS);
   for(i=1; i<FILEIO_BORDERS; i++) list->LRBorder[i].NextBorder = &list->LRBorder[i-1];
   CopyMem(st_LRBox, list->LRBox, sizeof(struct Box)*FILEIO_BOXES);
   for(i=1; i<FILEIO_BOXES; i++) list->LRBox[i].NextBox = &list->LRBox[i-1];
   CopyMem(st_LRImage, list->LRImage, sizeof(struct Image)*FILEIO_IMAGES);
   for(i=1; i<FILEIO_IMAGES; i++) list->LRImage[i].NextImage = &list->LRImage[i-1];

   for(i=0; i<FILEIO_BORDERS; i++)
   if ( !(list->LRBorder[i].XY = New(SHORT, list->LRBorder[i].Count*2)) )
      {
      ls_DeleteData(list);
      return(FALSE);
      }
   list->LRBorder[0].XY[0]  = list->LRBorder[0].XY[2]  = 1;
   list->LRBorder[0].XY[1]  = list->LRBorder[0].XY[7]  = 10;
   list->LRBorder[0].XY[3]  = list->LRBorder[0].XY[5]  = height-1;
   list->LRBorder[0].XY[4]  = list->LRBorder[0].XY[6]  = width-2;

   list->LRBorder[1].XY[0]  = list->LRBorder[1].XY[1]  =
   list->LRBorder[1].XY[2]  = list->LRBorder[1].XY[7]  =
   list->LRBorder[1].XY[8]  = list->LRBorder[1].XY[9]  = 0;
   list->LRBorder[1].XY[3]  = list->LRBorder[1].XY[5]  = height-1;
   list->LRBorder[1].XY[4]  = list->LRBorder[1].XY[6]  = width-1;

   list->LRBorder[2].XY[0]  = list->LRBorder[2].XY[2]  = width-34;
   list->LRBorder[2].XY[1]  = OPENSELECT_TOP-1;
   list->LRBorder[2].XY[3]  = OPENSELECT_TOP+d_height+4;

   list->LRBox[0].Width    = width-2;
/*   list->LRBox[1].LeftEdge = width-81;
   list->LRBox[1].TopEdge  = list->LRBox[2].TopEdge  = height - 17; */
   list->LRBox[1].LeftEdge = OPENSELECT_LEFT-5;
   list->LRBox[1].TopEdge  = OPENSELECT_TOP-1;
   list->LRBox[1].Width    = d_width+29;
   list->LRBox[1].Height   = d_height+4;

   if (list->ReqTitle) list->LRBox[0].Text = list->ReqTitle;
   else list->LRBox[0].Text = LRDefaultReqTitle;

   list->LRImage[0].LeftEdge = list->LRImage[1].LeftEdge = list->LRImage[2].LeftEdge = width-31;
   list->LRImage[0].TopEdge  = OPENSELECT_TOP+1;
   list->LRImage[1].TopEdge  = OPENSELECT_TOP+6;
   list->LRImage[2].TopEdge  = OPENSELECT_TOP+d_height-3;

   CopyMem(st_LRGadget, list->LRGadget, sizeof(struct Gadget)*FILEIO_GADGETS);
   for(i=2; i<FILEIO_GADGETS; i++) list->LRGadget[i].NextGadget = &list->LRGadget[i-1];

   if (  !(list->LRGadget[OPENGADGET_PROPGADGET].SpecialInfo  = (APTR)New(struct PropInfo, 1))
      || !(list->LRGadget[OPENGADGET_PROPGADGET].GadgetRender = (APTR)New(struct Image, 1))
      )
      {
      ls_DeleteData(list);
      return(FALSE);
      }
   OpenPropInfo->Flags = FREEVERT | PROPBORDERLESS;

   Clone(&st_LRPropImage, OpenPropImage);

   /* let's hide the Ok and Cancel gadgets below the big display */
   list->LRGadget[1].TopEdge  = list->LRGadget[2].TopEdge  = height-20;
   /* the others are visible and active */
   list->LRGadget[3].LeftEdge = list->LRGadget[4].LeftEdge = width-30;
   list->LRGadget[3].TopEdge  = OPENSELECT_TOP+7;
   list->LRGadget[4].TopEdge  = OPENSELECT_TOP+18;
   list->LRGadget[5].LeftEdge = width-28;
   list->LRGadget[5].TopEdge  = OPENSELECT_TOP+26;
   list->LRGadget[5].Height   = d_height-29;
   list->LRGadget[6].Width    = d_width;
   list->LRGadget[6].Height   = d_height;

   for (i=0; i<list->MaxLines; i++)
       {
       Clone(&st_LROpenSelectText, &list->OpenSelectText[i]);
       list->OpenSelectText[i].TopEdge = 1+(OPEN_LINEHEIGHT*i);
       if (i) list->OpenSelectText[i].NextText = &list->OpenSelectText[i-1];
       if (!(list->OpenSelectText[i].IText = New(UBYTE, list->MaxChars)))
          {
          ls_DeleteData(list);
          return(FALSE);
          }
   }
   return(TRUE);
}

VOID
ls_DeleteData(list)
register struct ListSupport *list;
{
   register USHORT i;
   SHORT d_height;

   if (list->LRGadget)
      {
      CheckDelete(OpenPropInfo, 1);
      CheckDelete(OpenPropImage, 1);
      Delete(list->LRGadget, FILEIO_GADGETS);
      }

   if (list->LRBorder)
      {
      for(i=0; i<FILEIO_BORDERS; i++)
         {
         CheckDelete(list->LRBorder[i].XY, list->LRBorder[i].Count*2);
         }
      Delete(list->LRBorder, FILEIO_BORDERS);
      }
   CheckDelete(list->LRBox,   FILEIO_BOXES);
   CheckDelete(list->LRImage, FILEIO_IMAGES);

   if (list->OpenSelectText)
      {
      for(i=0; i<list->MaxLines; i++)
         CheckDelete(list->OpenSelectText[i].IText, list->MaxChars);
      Delete(list->OpenSelectText, list->MaxLines);
      }
}

BOOL ls_StartRequester(list, window, x, y)
struct    ListSupport *list;
struct    Window  *window;
SHORT x, y;
{
   SHORT    width, height;
   struct   NewWindow   *nw;

   width    = (list->MaxChars-1)*OPEN_LINEHEIGHT + 6 + 45;
   height   = list->MaxLines*OPEN_LINEHEIGHT + 12 + 14;

   if (!(nw = New(struct NewWindow, 1))) return(FALSE);
   Clone(&st_LRnw, nw);
/*   if (window && FlagIsSet(list->Flags, LR_AUTO_CENTER))
      {
      x = window->LeftEdge + (window->Width - width)/2;
      y = 10 + window->TopEdge + (window->Height-11 - height)/2;
      } */
   nw->LeftEdge = x;
   nw->TopEdge  = y;
   nw->Width    = width;
   nw->Height   = height;
/*   nw->Screen   = window? window->WScreen : IntuitionBase->FirstScreen;
   is_BindWindowToScreen(nw); */
   list->LRWindow = (struct Window *)OpenWindow(nw);
   Delete(nw, 1);
   if (!list->LRWindow) return(FALSE);
   SetMenuStrip(list->LRWindow, &Menu1);

   SetAPen (list->LRWindow->RPort, WHITE);
   SetBPen (list->LRWindow->RPort, BLACK);
   SetAfPt (list->LRWindow->RPort, LR_Pattern, 3);
   RectFill(list->LRWindow->RPort, 0,0, list->LRWindow->Width-1, list->LRWindow->Height-1 );
   SetAfPt (list->LRWindow->RPort, NULL, 0);

   if (FlagIsClear(list->Flags, LR_DRAG_BAR_OFF))
      AddGadget(list->LRWindow, &list->LRGadget[OPENGADGET_DRAG], (USHORT) ~0);
   AddGList(list->LRWindow, &list->LRGadget[FILEIO_GADGETS-1], (USHORT) ~0, -1, 0);
   DrawBox(list->LRWindow->RPort, &list->LRBox[FILEIO_BOXES-1], 0,0);
   DrawBorder(list->LRWindow->RPort, &list->LRBorder[FILEIO_BORDERS-1], 0,0);
   DrawImage (list->LRWindow->RPort, &list->LRImage[FILEIO_IMAGES-1], 0,0);

   if (FlagIsClear(list->Flags, LR_GOOD_LISTNAMES)) ls_WarmStartFileIO(list);
   else
      {
      list->OpenClickSeconds = list->OpenClickMicros = 0;
      ls_InitOpenProp(list, TRUE);
      ls_StuffSelectNames(list, 2);
      }
   return(TRUE);
}

VOID ls_EndRequester(list)
struct     ListSupport *list;
{
   if (!list) return;
   if (list->LRWindow)
      {
      while (FlagIsSet( list->LRWindow->Flags, WINDOWREFRESH )) Delay( 10 ); /* if intuition use it */
      ModifyIDCMP( list->LRWindow, NULL );
      RemoveGList(list->LRWindow, &list->LRGadget[FILEIO_GADGETS-1], -1);
      if (FlagIsClear(list->Flags, LR_DRAG_BAR_OFF))
         RemoveGadget(list->LRWindow, &list->LRGadget[OPENGADGET_DRAG]);
      ClearMenuStrip(list->LRWindow);
      CloseWindow(list->LRWindow);
      list->LRWindow = NULL;
      }
}
