#include <CrashPrefs.h>

struct List areafixlist;
ULONG areafixnum,currentareafix;

struct Hook AreaFixHelpHook = { {NULL}, HelpHookEntry,NULL,HELP_AREAFIX};

void SetAreaFix(ULONG num)
{
   if(areafixnum == 0)
   {
      LT_SetAttributes(parthandle,4712,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,11,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,12,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,13,GA_Disabled,TRUE,TAG_END);
   }

   if(num!=-1)
   {
      if(areafixnum)
      {
         LT_SetAttributes(parthandle,11,GA_Disabled,FALSE,TAG_END);
         LT_SetAttributes(parthandle,4712,GA_Disabled,FALSE,TAG_END);
      }
      else
      {
         LT_SetAttributes(parthandle,11,GA_Disabled,TRUE,TAG_END);
         LT_SetAttributes(parthandle,4712,GA_Disabled,TRUE,TAG_END);
      }

      if(num!=0)                 LT_SetAttributes(parthandle,12,GA_Disabled,FALSE,TAG_END);
      else                       LT_SetAttributes(parthandle,12,GA_Disabled,TRUE,TAG_END);

      if(num!=areafixnum-1)      LT_SetAttributes(parthandle,13,GA_Disabled,FALSE,TAG_END);
      else                       LT_SetAttributes(parthandle,13,GA_Disabled,TRUE,TAG_END);
   }
   currentareafix=num;
}

void RefreshAreaFixlist(void)
{
   struct TempNode *tempnode;
   struct AreaFixName *areafix;

   LT_SetAttributes(parthandle,4711,GTLV_Labels,~0,TAG_END);
   FreeTempNodes(&areafixlist);

   areafixnum=0;

   for(areafix=AreaFixList.First;areafix;areafix=areafix->Next)
   {
      if(!(tempnode=(struct TempNode *)AllocMem(sizeof(struct TempNode),MEMF_CLEAR)))
      {
         DisplayBeep(NULL);
         FreeTempNodes(&areafixlist);
         return;
      }
      strcpy(tempnode->buf,areafix->Name);
      tempnode->Node.ln_Name=tempnode->buf;
      AddTail(&areafixlist,(struct Node *)tempnode);
      areafixnum++;
   }

   LT_SetAttributes(parthandle,4711,GTLV_Labels,&areafixlist,TAG_END);
}

BOOL CheckDupeAreaFix(UBYTE *buf,ULONG num)
{
   struct AreaFixName *areafix;
   ULONG c;

   for(areafix=AreaFixList.First,c=0;areafix;areafix=areafix->Next,c++)
      if(stricmp(areafix->Name,buf)==0 && c!=num) break;

   if(areafix)
   {
      rtEZRequestTags("You already have that AreaFix name","_Ok",NULL,NULL,RT_Underscore,'_',
                                                                           RT_Window,partwin,
                                                                           RT_WaitPointer,TRUE,
                                                                           RT_LockWindow, TRUE,
                                                                           TAG_END);

      return(FALSE);
   }

   return(TRUE);
}

void AddAreaFix(void)
{
   struct AreaFixName *areafix;
   UBYTE buf[200];
   BOOL res;

   buf[0]=0;
   res=rtGetString(buf,35,"Add AreaFix name",NULL,RT_Window,partwin,
                                                 RT_WaitPointer, TRUE,
                                                 RT_LockWindow, TRUE,
                                                 TAG_END);

   if(!res)
      return;

   if(!CheckDupeAreaFix(buf,-1))
      return;

   if(areafix=(struct AreaFixName *)AllocMem(sizeof(struct AreaFixName),MEMF_CLEAR))
   {
      jbAddNode(&AreaFixList,(struct jbNode *)areafix);
      strcpy(areafix->Name,buf);
      RefreshAreaFixlist();
      SetAreaFix(areafixnum-1);
      LT_SetAttributes(parthandle,4711,GTLV_Selected,currentareafix,GTLV_MakeVisible,currentareafix,TAG_END);
      saveconfig=TRUE;
   }
   else
   {
      DisplayBeep(NULL);
   }
}

void RemAreaFix(void)
{
   ULONG c,tmp;
   struct AreaFixName *areafix;
   UBYTE buf[100];
   BOOL res;

   areafix=AreaFixList.First;
   for(c=0;c<currentareafix;c++) areafix=areafix->Next;

   sprintf(buf,"Do you really want to remove the AreaFix name \"%s\"?",areafix->Name);

   res=rtEZRequestTags(buf,"_Remove|_Cancel",NULL,NULL,RT_Underscore,'_',
                                                       RT_Window,partwin,
                                                       RT_WaitPointer,TRUE,
                                                       RT_LockWindow, TRUE,
                                                       RTEZ_Flags, EZREQF_CENTERTEXT | EZREQF_NORETURNKEY,
                                                       TAG_END);

   if(!res)
      return;

   tmp=currentareafix;
   jbFreeNode(&AreaFixList,(struct jbNode *)areafix,sizeof(struct AreaFixName));
   RefreshAreaFixlist();
   if(tmp == areafixnum) tmp--;
   SetAreaFix(tmp);
   saveconfig=TRUE;
}

void PartAreaFix(void)
{
   ULONG class,code,tmp;
   struct IntuiMessage *IntuiMessage;
   struct TempNode *tempnode;
   APTR iaddress;
   ULONG c,oldflags;
   struct AreaFixName *areafix;
   BOOL importareafix,areafixremove,allowrescan,forwardpassthru,removewhenfeed,includeforward;
   NewList(&areafixlist);
   currentareafix=-1;

   importareafix=FALSE;
   areafixremove=FALSE;
   allowrescan=FALSE;
   forwardpassthru=FALSE;
   removewhenfeed=FALSE;
   includeforward=FALSE;

   if(cfg_Flags & CFG_IMPORTAREAFIX) importareafix=TRUE;
   if(cfg_Flags & CFG_AREAFIXREMOVE) areafixremove=TRUE;
   if(cfg_Flags & CFG_ALLOWRESCAN) allowrescan=TRUE;
   if(cfg_Flags & CFG_FORWARDPASSTHRU) forwardpassthru=TRUE;
   if(cfg_Flags & CFG_REMOVEWHENFEED) removewhenfeed=TRUE;

   if(cfg_Flags2 & CFG2_INCLUDEFORWARD) includeforward=TRUE;

   parthandle = LT_CreateHandleTags(scr,LH_EditHook,&StrEditHook,LH_RawKeyFilter,FALSE,TAG_DONE);

   if(!parthandle)
   {
      FreeTempNodes(&areafixlist);
      return;
   }

   LT_New(parthandle,
      LA_Type,      VERTICAL_KIND,
      TAG_DONE);

      LT_New(parthandle,
         LA_Type,      VERTICAL_KIND,
         LA_LabelText, "AreaFix names",
         TAG_DONE);

      LT_New(parthandle,
         LA_Type,      VERTICAL_KIND,
         TAG_DONE);

         LT_New(parthandle,
            LA_Type,      STRING_KIND,
            GTST_MaxChars,35,
            LA_Chars,20,
            LA_ID,        4712,
            LAST_Link,    4711,
            GA_Disabled,TRUE,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,       LISTVIEW_KIND,
            LA_Chars,40,
            LALV_LockSize, TRUE,
            LALV_Lines,    4,
            LALV_CursorKey,TRUE,
            LALV_Link,     4712,
            GTLV_Labels,   &areafixlist,
            LA_ID,4711,
            TAG_DONE);

         LT_EndGroup(parthandle);

         LT_New(parthandle,
            LA_Type,      HORIZONTAL_KIND,
            LAGR_SameSize,TRUE,
            TAG_DONE);

            LT_New(parthandle,
               LA_Type,      VERTICAL_KIND,
               LAGR_SameSize,TRUE,
               TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      BUTTON_KIND,
                  LA_LabelText, "Add...",
                  LA_Chars,20,
                  LA_ID,10,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      BUTTON_KIND,
                  LA_LabelText, "Up",
                  GA_Disabled,TRUE,
                  LA_Chars,20,
                  LA_ID,12,
                  TAG_DONE);

            LT_EndGroup(parthandle);

            LT_New(parthandle,
               LA_Type,      VERTICAL_KIND,
               LAGR_SameSize,TRUE,
               TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      BUTTON_KIND,
                  LA_LabelText, "Remove...",
                  LA_Chars,20,
                  GA_Disabled,TRUE,
                  LA_ID,11,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      BUTTON_KIND,
                  LA_LabelText, "Down",
                  LA_Chars,20,
                  GA_Disabled,TRUE,
                  LA_ID,13,
                  TAG_DONE);

            LT_EndGroup(parthandle);

         LT_EndGroup(parthandle);

      LT_EndGroup(parthandle);

      LT_New(parthandle,
         LA_Type,      HORIZONTAL_KIND,
         LA_LabelText, "AreaFix responses",
         TAG_DONE);

         LT_New(parthandle,
            LA_Type,      STRING_KIND,
            LA_Chars,     39,
            LA_LabelText, "Helpfile",
            GTST_MaxChars,39,
            LA_STRPTR,    cfg_AreaFixHelp,
            LAST_Picker,  TRUE,
            LA_ID,        69,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,      INTEGER_KIND,
            LA_Chars,     5,
            LA_LabelText, "Max lines",
            LA_ULONG,     &cfg_AreaFixMaxLines,
            LA_ID,        70,
            TAG_DONE);

      LT_EndGroup(parthandle);

      LT_New(parthandle,
         LA_Type,      HORIZONTAL_KIND,
         LA_LabelText, "Switches",
         TAG_DONE);

         LT_New(parthandle,
            LA_Type,    VERTICAL_KIND,
            TAG_DONE);

            LT_New(parthandle,
               LA_Type,      CHECKBOX_KIND,
               LA_LabelText, "Import AreaFix",
               LA_BOOL,      &importareafix,
               TAG_DONE);

            LT_New(parthandle,
               LA_Type,      CHECKBOX_KIND,
               LA_LabelText, "AreaFix may remove",
               LA_BOOL,      &areafixremove,
               TAG_DONE);

            LT_New(parthandle,
               LA_Type,      CHECKBOX_KIND,
               LA_LabelText, "Allow rescan",
               LA_BOOL,      &allowrescan,
               TAG_DONE);

         LT_EndGroup(parthandle);

         LT_New(parthandle,
            LA_Type,    VERTICAL_KIND,
            TAG_DONE);

            LT_New(parthandle,
               LA_Type,      CHECKBOX_KIND,
               LA_LabelText, "Forward areas pass-through",
               LA_BOOL,      &forwardpassthru,
               TAG_DONE);

            LT_New(parthandle,
               LA_Type,      CHECKBOX_KIND,
               LA_LabelText, "Remove area when feed disconnects",
               LA_BOOL,      &removewhenfeed,
               TAG_DONE);

            LT_New(parthandle,
               LA_Type,      CHECKBOX_KIND,
               LA_LabelText, "Include forward-requestable in lists",
               LA_BOOL,      &includeforward,
               TAG_DONE);

         LT_EndGroup(parthandle);

      LT_EndGroup(parthandle);

   LT_EndGroup(parthandle);

   partwin=LT_Build(parthandle,LAWN_IDCMP,    IDCMP_CLOSEWINDOW|IDCMP_RAWKEY,
                               LAWN_Title,    "AreaFix",
                               WA_Flags,      WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_NEWLOOKMENUS,
                               LAWN_HelpHook, &AreaFixHelpHook,
                               TAG_END);

   if(!partwin)
   {
      LT_DeleteHandle(parthandle);
      DisplayBeep(NULL);
      FreeTempNodes(&areafixlist);
      return;
   }

   RefreshAreaFixlist();

   if(areafixnum)
   {
      LT_SetAttributes(parthandle,4711,GTLV_Selected,0,TAG_END);
      SetAreaFix(0);
   }

   for(;;)
   {
      while(IntuiMessage=(struct IntuiMessage *)LT_GetIMsg(parthandle))
      {
         class=IntuiMessage->Class;
         code=IntuiMessage->Code;
         iaddress=IntuiMessage->IAddress;

         LT_ReplyIMsg(IntuiMessage);

         switch(class)
         {
            case IDCMP_RAWKEY:         if(code == TAB) LT_Activate(parthandle,4712);
                                       break;
            case IDCMP_IDCMPUPDATE:    switch(((struct Gadget *)iaddress)->GadgetID)
                                       {
                                          case 69:
                                            strcmpcpy(cfg_AreaFixHelp,(UBYTE *)LT_GetAttributes(parthandle,69,TAG_END));

                                            if(OpenReq(cfg_AreaFixHelp,40,"Please select file",partwin,FALSE))
                                               saveconfig=TRUE;
                                            LT_SetAttributes(parthandle,69,GTST_String,cfg_AreaFixHelp,TAG_END);
                                            break;
                                       }
                                       break;
            case IDCMP_GADGETUP:       switch(((struct Gadget *)iaddress)->GadgetID)
                                       {
                                          case 10:
                                             AddAreaFix();
                                             break;
                                          case 11:
                                             RemAreaFix();
                                             break;
                                          case 12:
                                             if(currentareafix != 0)
                                             {
                                                tmp=currentareafix;
                                                MoveUp(&AreaFixList,tmp);
                                                RefreshAreaFixlist();
                                                SetAreaFix(tmp-1);
                                                LT_SetAttributes(parthandle,4711,
                                                   GTLV_Selected,currentareafix,
                                                   GTLV_MakeVisible,currentareafix,
                                                   TAG_END);
                                                saveconfig=TRUE;
                                             }
                                             break;
                                          case 13:
                                             if(currentareafix != areafixnum-1)
                                             {
                                                tmp=currentareafix;
                                                MoveDown(&AreaFixList,tmp);
                                                RefreshAreaFixlist();
                                                SetAreaFix(tmp+1);
                                                LT_SetAttributes(parthandle,4711,
                                                   GTLV_Selected,currentareafix,
                                                   GTLV_MakeVisible,currentareafix,
                                                   TAG_END);
                                                saveconfig=TRUE;
                                             }
                                             break;
                                          case 4711:
                                             SetAreaFix(code);
                                             break;
                                          case 4712:
                                             if(CheckDupeAreaFix(getgadgetstring((struct Gadget *)iaddress),currentareafix))
                                             {
                                                areafix=AreaFixList.First;
                                                for(c=0;c<currentareafix;c++) areafix=areafix->Next;
                                                strcpy(areafix->Name,getgadgetstring((struct Gadget *)iaddress));

                                                tempnode=areafixlist.lh_Head;
                                                for(c=0;c<currentareafix;c++) tempnode=tempnode->Node.ln_Succ;

                                                LT_SetAttributes(parthandle,4711,GTLV_Labels,~0,TAG_END);
                                                strcpy(tempnode->buf,getgadgetstring((struct Gadget *)iaddress));
                                                LT_SetAttributes(parthandle,4711,GTLV_Labels,&areafixlist,TAG_END);
                                             }
                                             else
                                             {
                                                LT_Activate(parthandle,4712);
                                             }
                                             break;
                                       }
                                       break;
            case IDCMP_CLOSEWINDOW:    LT_DeleteHandle(parthandle);
                                       parthandle=NULL;
                                       FreeTempNodes(&areafixlist);
                                       oldflags=cfg_Flags;

                                       cfg_Flags&=~(CFG_AREAFIXREMOVE|CFG_ALLOWRESCAN|CFG_IMPORTAREAFIX|CFG_FORWARDPASSTHRU|CFG_REMOVEWHENFEED);
                                       cfg_Flags2&=~(CFG2_INCLUDEFORWARD);

                                       if(importareafix) cfg_Flags|=CFG_IMPORTAREAFIX;
                                       if(areafixremove) cfg_Flags|=CFG_AREAFIXREMOVE;
                                       if(allowrescan) cfg_Flags|=CFG_ALLOWRESCAN;
                                       if(forwardpassthru) cfg_Flags|=CFG_FORWARDPASSTHRU;
                                       if(removewhenfeed) cfg_Flags|=CFG_REMOVEWHENFEED;

                                       if(includeforward) cfg_Flags2|=CFG2_INCLUDEFORWARD;

                                       if(cfg_Flags != oldflags) saveconfig=TRUE;
                                       return;
         }
      }
      WaitPort(partwin->UserPort);
   }
}
