#include "ToolManager.h"

/* Structures for window */
extern UBYTE WindowTitle[];
extern struct NewWindow nw;
extern struct TagItem wtags[];
#define WTAG_WIDTH 0
#define WTAG_HEIGHT 1
#define WTAG_PUBSCR 3
#define WDRAGBARLEN 60       /* Width of Close & Drag gadget */
static struct Window *w=NULL;
static struct AppWindow *aw;
static struct MsgPort *wp;
static ULONG ww,wh;          /* Window width & height */
static struct Screen *pubsc; /* Workbench screen */

/* Structures for window gadgets */
static void *vi;             /* Visual information is a *PRIVATE* data field! */
static struct Gadget *gl;    /* Gadget list */
static char StatusText[]="Active Tools: 00"; /* Text gadget text */
static struct Gadget *lvgad;                 /* ListView gadget */
#define LVGAD_ID 1
static char ButtonText[]="Remove Tool";      /* Button gadget text */
#define BUGAD_ID 2

/* Create status line */
static void PrintStatusLine(void)
{
 StatusText[14]=ToolCount/10+'0'; /* Hack */
 StatusText[15]=ToolCount%10+'0';
}

/* Create all status window gadgets */
static BOOL CreateWindowGadgets(void)
{
 struct NewGadget ng;
 struct Gadget *g;
 struct TextAttr *ta=pubsc->Font;
 struct TextFont *f;              /* Window font */
 struct RastPort tmprp;           /* RastPort for font-sensitive trick */
 UWORD width,fheight;

 /* Open window font */
 if (!(f=OpenFont(ta))) return(FALSE);
 fheight=f->tf_YSize; /* Font height */

 /* Initialize temporary RastPort */
 InitRastPort(&tmprp);
 SetFont(&tmprp,f);

 /* Calculate window width */
 ww=TextLength(&tmprp,WindowTitle,strlen(WindowTitle))+WDRAGBARLEN;

 /* Create gadget list */
 gl=NULL;
 g=CreateContext(&gl);

 /* 1. gadget: Text, status line */
 PrintStatusLine();
 width=TextLength(&tmprp,StatusText,sizeof(StatusText)-1);
 ng.ng_LeftEdge=(ww-width)/2;
 ng.ng_TopEdge=INTERHEIGHT;
 ng.ng_Width=width;
 ng.ng_Height=fheight;
 ng.ng_GadgetText=StatusText;
 ng.ng_TextAttr=ta;
 ng.ng_Flags=PLACETEXT_IN;
 ng.ng_VisualInfo=vi;
 ng.ng_UserData=0;
 g=CreateGadget(TEXT_KIND,g,&ng,TAG_DONE);
 g->GadgetText->DrawMode=JAM2; /* Argh, why doesn't exist a tag for this? */

 /* 2. gadget: ListView, tool list */
 ng.ng_LeftEdge=WDRAGBARLEN/2;
 ng.ng_TopEdge+=g->Height+INTERHEIGHT;
 ng.ng_Width=ww-WDRAGBARLEN;
 ng.ng_Height=7*fheight;
 ng.ng_GadgetText=NULL;
 ng.ng_GadgetID=LVGAD_ID;
 lvgad=g=CreateGadget(LISTVIEW_KIND,g,&ng,
                      GTLV_Labels,&ToolList,
                      GTLV_ShowSelected,NULL,
                      TAG_DONE);

 /* 3. gadget: Button, remove tool */
 ng.ng_TopEdge+=g->Height+fheight+2*INTERHEIGHT;
 ng.ng_Width=TextLength(&tmprp,ButtonText,sizeof(ButtonText)-1)+INTERWIDTH;
 ng.ng_Height=fheight+INTERHEIGHT;
 ng.ng_GadgetText=ButtonText;
 ng.ng_GadgetID=BUGAD_ID;
 g=CreateGadget(BUTTON_KIND,g,&ng,TAG_DONE);

 /* Calculate window height */
 wh=ng.ng_TopEdge+g->Height+INTERHEIGHT;

 /* Close window font */
 CloseFont(f);

 /* All gadgets created! */
 if (g) return(TRUE);

 /* Something went wrong.... */
 FreeGadgets(gl);
 return(FALSE);
}

/* Open status window */
ULONG OpenStatusWindow(void)
{
 if (!(pubsc=LockPubScreen("Workbench"))) /* Lock Workbench screen */
  goto osw1;

 if (!(vi=GetVisualInfo(pubsc,TAG_DONE))) /* Get visual information */
  goto osw2;

 if (!CreateWindowGadgets())              /* Create Gadgets */
  goto osw3;

 /* Open window */
 wtags[WTAG_WIDTH ].ti_Data=ww;
 wtags[WTAG_HEIGHT].ti_Data=wh;
 wtags[WTAG_PUBSCR].ti_Data=pubsc;
 if (!(w=OpenWindowTagList(&nw,wtags)))
  goto osw4;
 wp=w->UserPort; /* Retrieve window port */

 /* Circumvent an intuition.library bug. See AutoDocs for LockPubScreen() */
 UnlockPubScreen(NULL,pubsc);
 pubsc=NULL;

 /* Notify Workbench about window */
 if (!(aw=AddAppWindow(NULL,NULL,w,MyMP,NULL)))
  goto osw5;

 /* Add gadget list to window */
 AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
 RefreshGList(gl,w,NULL,(UWORD) -1);
 GT_RefreshWindow(w,NULL);

 /* Window open! */
 return(1L<<wp->mp_SigBit);

 /* Something went wrong.... */
osw5: CloseWindow(w);
      w=NULL;
osw4: FreeGadgets(gl);
osw3: FreeVisualInfo(vi);
osw2: if (pubsc) UnlockPubScreen(NULL,pubsc);
osw1: return(0);
}

/* Refresh status window gadgets */
void RefreshStatusWindow(void)
{
 PrintStatusLine();
 RefreshGList(gl,w,NULL,2); /* Refresh only the first two gadgets */
}

/* If the window is open, detach tool list from ListView gadget */
void DetachToolList(void)
{
 if (w) GT_SetGadgetAttrs(lvgad,w,NULL,GTLV_Labels,-1,TAG_DONE);
}

/* If the window is open, attach tool list to ListView gadget */
void AttachToolList(void)
{
 if (w) GT_SetGadgetAttrs(lvgad,w,NULL,GTLV_Labels,&ToolList,TAG_DONE);
}

/* Handle window events */
BOOL HandleWindowEvent(void)
{
 static WORD lvord=-1;      /* ListView gadget ordinal number */
 BOOL rc=FALSE;             /* True if window close event */
 struct IntuiMessage *msg;

 while (msg=GT_GetIMsg(wp)) /* Pre-process Intuition messages */
  {
   switch (msg->Class)
    {
     case INTUITICKS:       /* Intuition tick received */
      break;
     case CLOSEWINDOW:      /* User clicked the close gadget */
      rc=TRUE;
      break;
     case REFRESHWINDOW:    /* Window must be refreshed */
      GT_BeginRefresh(w);
      GT_EndRefresh(w,TRUE);
      break;
     case GADGETUP:         /* User released a gadget */
      switch(((struct Gadget *) msg->IAddress)->GadgetID)
       {
        case LVGAD_ID:      /* User selected a ListView item */
         lvord=msg->Code;   /* Retrieve the ordinal number of the item */
         break;
        case BUGAD_ID:      /* User selected the button gadget */
         if (lvord>=0)      /* Is the ordinal number valid? */
          {                 /* Yes, search tool and remove it */
           WORD i=0;        /* Counter */
           struct ToolNode *tn;

           /* Scan tool list until the ordinal number is reached */
           for (tn=GetHead(&ToolList); tn; tn=GetSucc(tn),i++)
            if (i>=lvord) break;

           /* Remove tool from list */
           DetachToolList();
           RemToolNode(tn);
           AttachToolList();

           /* Refresh Gadgets */
           RefreshStatusWindow();
           lvord=-1;        /* invalidate ordinal number */
          }
         break;
       }
      break;
    }
   GT_ReplyIMsg(msg); /* Reply pre-processed message */
  }

 return rc;
}

/* Close status window */
void CloseStatusWindow(void)
{
 RemoveAppWindow(aw);
 CloseWindow(w);
 w=NULL;
 FreeGadgets(gl);    /* Release allocated resources */
 FreeVisualInfo(vi);
}
