#include <CrashTickPrefs.h>

struct Hook AreasHelpHook = { {NULL}, HelpHookEntry,NULL,(APTR)HELP_AREAS};

struct List Areas_TempList;
struct List Areas_TempNodeList;
struct TempNode *Areas_CurrentNode;
struct TempNode *Areas_CurrentNodeNode;
ulong Areas_Activepage;
ulong Areas_Selectmode;

uchar *Areas_Nodeflags[4];
uchar *Areas_Pagenames[4];
uchar *Areas_Selectmodes[3];

uchar Areas_Akabuf[40];
uchar Areas_Groupbuf[120];

void ChangeAreas(void);

extern APTR mempool;

int CheckDupeArea(uchar *name,struct Area *currentarea)
{
   struct Area *area;

   for(area=(struct Area *)config.AreaList.First;area;area=area->Next)
      if(stricmp(name,area->Name)==0 && area!=currentarea) return(FALSE);

   return(TRUE);
}

void Areas_UpdateList(void)
{
   struct TempNode *tempnode;
   struct Area *area;
   ulong num;

   LV_DetachList(parthandle,4000);
   FreeTempNodes(&Areas_TempList);
   NewList(&Areas_TempList);

   num=0;

   for(area=(struct Area *)config.AreaList.First;area;area=area->Next)
   {
      if(tempnode=AllocCleared(sizeof(struct TempNode)))
      {
         strcpy(tempnode->buf,area->Name);
         tempnode->Node.ln_Name=tempnode->buf;
         tempnode->UserData=area;
         tempnode->num=num;

         num++;

         AddTail(&Areas_TempList,(struct Node *)tempnode);
      }
   }

   LV_AttachList(parthandle,4000,&Areas_TempList);
}

void Areas_ChangedNum(void)
{
   LV_ChangedNum(parthandle,4000,&Areas_TempList);

   if(!Areas_TempList.lh_Head->ln_Succ)
   {
      LT_SetAttributes(parthandle,1,GA_Disabled,TRUE,TAG_END);

      LT_SetAttributes(parthandle,10,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);
      LT_SetAttributes(parthandle,14,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,15,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,16,GA_Disabled,TRUE,TAG_END);

      LT_SetAttributes(parthandle,20,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,21,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,25,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,26,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,27,GA_Disabled,TRUE,TAG_END);

      LT_SetAttributes(parthandle,30,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,31,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,32,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,33,GA_Disabled,TRUE,TAG_END);

      OffMenu(partwin,FULLMENUNUM(0,0,0));
      OffMenu(partwin,FULLMENUNUM(0,2,0));
      OffMenu(partwin,FULLMENUNUM(1,0,0));
      OffMenu(partwin,FULLMENUNUM(1,2,0));
      OffMenu(partwin,FULLMENUNUM(1,4,0));
   }
   else
   {
      LT_SetAttributes(parthandle,1,GA_Disabled,FALSE,TAG_END);

      LT_SetAttributes(parthandle,10,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,11,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,12,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,13,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,14,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,15,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,16,GA_Disabled,FALSE,TAG_END);

      LT_SetAttributes(parthandle,20,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,21,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,25,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,26,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,27,GA_Disabled,FALSE,TAG_END);

      LT_SetAttributes(parthandle,30,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,31,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,32,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,33,GA_Disabled,FALSE,TAG_END);

      OnMenu(partwin,FULLMENUNUM(0,0,0));
      OnMenu(partwin,FULLMENUNUM(0,2,0));
      OnMenu(partwin,FULLMENUNUM(1,0,0));
      OnMenu(partwin,FULLMENUNUM(1,2,0));
      OnMenu(partwin,FULLMENUNUM(1,4,0));
   }
}

void Areas_MakeNode(struct TickNode *ticknode,struct TempNode *tn)
{
   uchar buf[40];

   PrintFull4D(&ticknode->ConfigNode->Node,buf);

   if(ticknode->Flags & TICKNODE_READONLY)
      sprintf(tn->buf,"!%s",buf);

   else if(ticknode->Flags & TICKNODE_WRITEONLY)
      sprintf(tn->buf,"@%s",buf);

   else
      sprintf(tn->buf,"%s",buf);
}

void Areas_UpdateNodeList(void)
{
   ulong c;
   struct Area *area;
   struct TickNode *ticknode;
   struct TempNode *tn;
   
   area=(struct Area *)Areas_CurrentNode->UserData;

   if(area->TickNodes.First)
   {
      LT_SetAttributes(parthandle,20,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,21,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,27,GA_Disabled,FALSE,TAG_END);
   }
   else
   {
      LT_SetAttributes(parthandle,20,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,21,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,27,GA_Disabled,TRUE,TAG_END);
   }

   LT_SetAttributes(parthandle,20,GTLV_Labels,~0,TAG_END);
   FreeTempNodes(&Areas_TempNodeList);

   c=0;

   for(ticknode=(struct TickNode *)area->TickNodes.First;ticknode;ticknode=ticknode->Next)
   {
      if(tn=AllocCleared(sizeof(struct TempNode)))
      {
         Areas_MakeNode(ticknode,tn);
         tn->UserData=ticknode;
         tn->num=c;
         tn->Node.ln_Name=tn->buf;
         AddTail(&Areas_TempNodeList,(struct Node *)tn);

         c++;
      }
   }

   LT_SetAttributes(parthandle,20,GTLV_Labels,&Areas_TempNodeList,TAG_END);
}

void Areas_SetCurrentNode(ulong num)
{
   ulong c;
   struct Area *area;
   struct TickNode *ticknode;

   if(!Areas_TempNodeList.lh_Head->ln_Succ)
   {
      Areas_CurrentNodeNode=NULL;
      return;
   }

   area=Areas_CurrentNode->UserData;

   Areas_CurrentNodeNode=(struct TempNode *)Areas_TempNodeList.lh_Head;

   for(c=0;c<num;c++)
      Areas_CurrentNodeNode=(struct TempNode *)Areas_CurrentNodeNode->Node.ln_Succ;

   LT_SetAttributes(parthandle,20,GTLV_Selected,num,TAG_END);

   if(num == 0)
      LT_SetAttributes(parthandle,20,GTLV_MakeVisible,num,TAG_END);

   ticknode=Areas_CurrentNodeNode->UserData;

   if(ticknode->Flags & TICKNODE_READONLY)
      LT_SetAttributes(parthandle,21,GTCY_Active,1,TAG_END);

   else if(ticknode->Flags & TICKNODE_WRITEONLY)
      LT_SetAttributes(parthandle,21,GTCY_Active,2,TAG_END);

   else
      LT_SetAttributes(parthandle,21,GTCY_Active,0,TAG_END);
}

void Areas_SetCurrent(ulong num)
{
   ulong c;
   struct Area *area;

   if(!Areas_TempList.lh_Head->ln_Succ)
   {
      LV_SetCurrent(parthandle,4000,&Areas_TempList,NULL);
      Areas_CurrentNode=NULL;
      return;
   }

   Areas_CurrentNode=(struct TempNode *)Areas_TempList.lh_Head;

   for(c=0;c<num;c++)
      Areas_CurrentNode=(struct TempNode *)Areas_CurrentNode->Node.ln_Succ;

   LV_SetCurrent(parthandle,4000,&Areas_TempList,Areas_CurrentNode);

   area=Areas_CurrentNode->UserData;

   if(Areas_Activepage == 0)
   {
      LT_SetAttributes(parthandle,10,GTCB_Checked,FALSE,TAG_END);
      LT_SetAttributes(parthandle,14,GTCB_Checked,FALSE,TAG_END);
      LT_SetAttributes(parthandle,15,GTCB_Checked,FALSE,TAG_END);

      if(area->Flags & AREA_UNCONFIRMED)
         LT_SetAttributes(parthandle,10,GTCB_Checked,TRUE,TAG_END);

      PrintFull4D(&area->Aka->Node,Areas_Akabuf);
      LT_SetAttributes(parthandle,11,GTTX_Text,Areas_Akabuf,TAG_END);

      LT_SetAttributes(parthandle,12,GTST_String,area->Directory,TAG_END);

      LT_SetAttributes(parthandle,13,GTST_String,area->AreaCommand,TAG_END);

      if(area->Flags & AREA_IGNORESEENBY)
         LT_SetAttributes(parthandle,14,GTCB_Checked,TRUE,TAG_END);

      if(area->Flags & AREA_NOREPLACE)
         LT_SetAttributes(parthandle,15,GTCB_Checked,TRUE,TAG_END);

      LT_SetAttributes(parthandle,16,GTST_String,area->UserData,TAG_END);
   }

   if(Areas_Activepage == 1)
   {
      Areas_UpdateNodeList();
      Areas_SetCurrentNode(0);
   }

   if(Areas_Activepage == 2)
   {
      LT_SetAttributes(parthandle,30,GTCB_Checked,FALSE,TAG_END);
      LT_SetAttributes(parthandle,31,GTCB_Checked,FALSE,TAG_END);

      if(area->Flags & AREA_MANDATORY)
         LT_SetAttributes(parthandle,30,GTCB_Checked,TRUE,TAG_END);

      if(area->Flags & AREA_DEFREADONLY)
         LT_SetAttributes(parthandle,31,GTCB_Checked,TRUE,TAG_END);

      LT_SetAttributes(parthandle,32,GTST_String,area->Description,TAG_END);

      if(area->Group == 0)
         strcpy(Areas_Groupbuf,getString(PREFS_NO_GROUP));

      else
         sprintf(Areas_Groupbuf,"%lc: %s",
            area->Group,config.cfg_GroupNames[area->Group-'A']);

      LT_SetAttributes(parthandle,33,GTTX_Text,Areas_Groupbuf,TAG_END);
   }
}

void MakeDirectory(UBYTE *dest,ULONG destsize,UBYTE *defdir,UBYTE *areaname)
{
   ULONG c,d;

   d=0;
   for(c=0;c<strlen(defdir) && d!=destsize-1;c++)
   {
      if(defdir[c]=='%' && (defdir[c+1]|32)=='a')
      {
         strncpy(&dest[d],areaname,destsize-1-d);
         dest[destsize-1]=0;
         d=strlen(dest);
         c++;
      }
      else dest[d++]=defdir[c];
   }
   dest[d]=0;
}

void Areas_UpdateConfig(void)
{
   struct Area *area;
   ulong newflags,oldflags;

   if(!Areas_CurrentNode)
      return;

   area=Areas_CurrentNode->UserData;

   if(Areas_Activepage == 0)
   {
      newflags=0;
      oldflags=area->Flags & (AREA_UNCONFIRMED|AREA_IGNORESEENBY|AREA_NOREPLACE);
      area->Flags&=~(AREA_UNCONFIRMED|AREA_IGNORESEENBY|AREA_NOREPLACE);

      if(LT_GetAttributes(parthandle,10,TAG_END))
         newflags|=AREA_UNCONFIRMED;

      if(LT_GetAttributes(parthandle,14,TAG_END))
         newflags|=AREA_IGNORESEENBY;

      if(LT_GetAttributes(parthandle,15,TAG_END))
         newflags|=AREA_NOREPLACE;

      if(newflags != oldflags)
         config.configchanged=TRUE;

      area->Flags|=newflags;

      strcmpcpy(area->Directory,(uchar *)LT_GetAttributes(parthandle,12,TAG_END));
      strcmpcpy(area->AreaCommand,(uchar *)LT_GetAttributes(parthandle,13,TAG_END));
      strcmpcpy(area->UserData,(uchar *)LT_GetAttributes(parthandle,16,TAG_END));
   }

   if(Areas_Activepage == 2)
   {
      newflags=0;
      oldflags=area->Flags & (AREA_MANDATORY|AREA_DEFREADONLY);
      area->Flags&=~(AREA_MANDATORY|AREA_DEFREADONLY);

      area->Flags&=~(AREA_MANDATORY|AREA_DEFREADONLY);

      if(LT_GetAttributes(parthandle,30,TAG_END))
         newflags|=AREA_MANDATORY;

      if(LT_GetAttributes(parthandle,31,TAG_END))
         newflags|=AREA_DEFREADONLY;

      if(newflags != oldflags)
         config.configchanged=TRUE;

      area->Flags|=newflags;

      strcmpcpy(area->Description,(uchar *)LT_GetAttributes(parthandle,32,TAG_END));
   }
}

void Areas_Add(void)
{
   BOOL res;
   struct Area *area;
   UBYTE buf[80];
   struct TempNode *tn;
   short kg;

   buf[0]=0;

   kg=TRUE;

   while(kg)
   {
      res=rtGetString(buf,79,getString(PREFS_LIST_ADD),NULL,
               RTGS_TextFmt,getString(PREFS_AREAS_ADD),
               RTGS_Flags, GSREQF_CENTERTEXT,
               RT_Window,  partwin,
               RT_WaitPointer, TRUE,
               RT_LockWindow, TRUE,
               RT_Underscore,'_',
               TAG_END);

      if(!res)
         return;

      if(CheckDupeArea(buf,NULL))
      {
         kg=FALSE;
      }
      else
      {
         RequestError(partwin,getString(PREFS_AREAS_ALREADY_HAS),
            buf);
      }
   }

   if(!(area=AllocCleared(sizeof(struct Area))))
   {
      DisplayBeep(NULL);
      return;
   }

   strcpy(area->Name,buf);
   area->Aka=(struct Aka *)config.AkaList.First;
   MakeDirectory(area->Directory,80,config.cfg_AutoAddDir,buf);
   jbNewList(&area->TickNodes);
   jbAddNode(&config.AreaList,(struct jbNode *)area);
   Areas_UpdateList();

   tn=(struct TempNode *)Areas_TempList.lh_TailPred;

   Areas_ChangedNum();
   Areas_SetCurrent(tn->num);
   config.configchanged=TRUE;
}

void Areas_AddNode(void)
{
   ulong res;
   struct List list;
   struct ConfigNode *cnode;
   struct TempNode *tn;
   struct TickNode *ticknode;
   struct Area *area;
   ulong c;

   NewList(&list);

   area=Areas_CurrentNode->UserData;
   c=0;

   for(cnode=(struct ConfigNode *)config.CNodeList.First;cnode;cnode=cnode->Next)
   {
      for(ticknode=(struct TickNode *)area->TickNodes.First;ticknode;ticknode=ticknode->Next)
         if(ticknode->ConfigNode == cnode) break;

      if(!ticknode)
      {
         if(Areas_Selectmode == 0 || CheckFlags(area->Group,cnode->ReadOnlyGroups) || CheckFlags(area->Group,cnode->FullAccessGroups) || CheckFlags(area->Group,cnode->WriteOnlyGroups))
         {
            if(tn=AllocCleared(sizeof(struct TempNode)))
            {
               PrintFull4D(&cnode->Node,tn->buf);
               tn->UserData=cnode;
               tn->num=c;
               tn->Node.ln_Name=tn->buf;
               AddTail(&list,(struct Node *)tn);

               c++;
            }
         }
      }
   }

   res=AskList(&list,getString(PREFS_ASKLIST_SELECT_NODE),partwin);

   if(res == -1)
   {
      FreeTempNodes(&list);
      return;
   }

   tn=(struct TempNode *)list.lh_Head;

   for(c=0;c<res;c++)
      tn=(struct TempNode *)tn->Node.ln_Succ;

   cnode=tn->UserData;
   FreeTempNodes(&list);

   if(!(ticknode=AllocCleared(sizeof(struct TickNode))))
      return;

   ticknode->ConfigNode=cnode;

   if(CheckFlags(area->Group,cnode->ReadOnlyGroups) || (area->Flags & AREA_DEFREADONLY))
      ticknode->Flags = TICKNODE_READONLY;

   if(CheckFlags(area->Group,cnode->WriteOnlyGroups))
      ticknode->Flags = TICKNODE_WRITEONLY;

   jbAddNode(&area->TickNodes,(struct jbNode *)ticknode);
   Areas_UpdateNodeList();

   tn=(struct TempNode *)Areas_TempNodeList.lh_TailPred;

   Areas_SetCurrentNode(tn->num);
   config.configchanged=TRUE;
}

void Areas_Duplicate(void)
{
   BOOL res;
   struct Area *area,*oldarea;
   struct TickNode *ticknode,*oldticknode;
   UBYTE buf[80];
   struct TempNode *tn;
   BOOL kg;

   oldarea=Areas_CurrentNode->UserData;

   strcpy(buf,oldarea->Name);
   kg=TRUE;

   while(kg)
   {
      res=rtGetString(buf,79,getString(PREFS_LIST_ADD),NULL,
               RTGS_TextFmt,getString(PREFS_AREAS_ADD),
               RTGS_Flags, GSREQF_CENTERTEXT,
               RT_Window,  partwin,
               RT_WaitPointer, TRUE,
               RT_LockWindow, TRUE,
               RT_Underscore,'_',
               TAG_END);

      if(!res)
         return;

      if(CheckDupeArea(buf,NULL))
      {
         kg=FALSE;
      }
      else
      {
         RequestError(partwin,getString(PREFS_AREAS_ALREADY_HAS),
            buf);
      }
   }

   if(!(area=AllocCleared(sizeof(struct Area))))
   {
      DisplayBeep(NULL);
      return;
   }

   area->Aka=oldarea->Aka;
   area->Group=oldarea->Group;
   strcpy(area->Name,buf);
   strcpy(area->Directory,oldarea->Directory);
   strcpy(area->Description,oldarea->Description);
   strcpy(area->AreaCommand,oldarea->AreaCommand);

   jbNewList(&area->TickNodes);

   for(oldticknode=(struct TickNode *)oldarea->TickNodes.First;oldticknode;oldticknode=oldticknode->Next)
   {
      if(ticknode=AllocCleared(sizeof(struct TickNode)))
      {
         ticknode->Flags=oldticknode->Flags;
         ticknode->ConfigNode=oldticknode->ConfigNode;
         jbAddNode(&area->TickNodes,(struct jbNode *)ticknode);
      }
   }

   jbAddNode(&config.AreaList,(struct jbNode *)area);
   Areas_UpdateList();

   tn=(struct TempNode *)Areas_TempList.lh_TailPred;

   Areas_ChangedNum();
   Areas_SetCurrent(tn->num);
   config.configchanged=TRUE;
}

void Areas_Remove(void)
{
   struct Area *area;
   UBYTE buf[200];
   BOOL res;
   ULONG tmp;

   area=Areas_CurrentNode->UserData;

   sprintf(buf,getString(PREFS_AREAS_REM),area->Name);

   res=rtEZRequestTags(buf,getString(PREFS_TXT_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=Areas_CurrentNode->num;

   if(!Areas_CurrentNode->Node.ln_Succ->ln_Succ)
      tmp--;

   jbFreeList(&area->TickNodes,sizeof(struct TickNode));
   jbFreeNode(&config.AreaList,(struct jbNode *)Areas_CurrentNode->UserData,sizeof(struct Area));

   Areas_UpdateList();
   Areas_ChangedNum();
   Areas_SetCurrent(tmp);

   config.configchanged=TRUE;
}

void Areas_RemoveGroup(void)
{
   struct Area *area,*area2;
   uchar group;

   group=AskGroup(partwin,NULL);

   if(group == -1)
      return;

   area=(struct Area *)config.AreaList.First;

   while(area)
   {
      area2=area->Next;

      if(area->Group == group)
      {
         jbFreeList(&area->TickNodes,sizeof(struct TickNode));
         jbFreeNode(&config.AreaList,(struct jbNode *)area,sizeof(struct Area));
      }

      area=area2;
   }

   Areas_UpdateList();
   Areas_ChangedNum();
   Areas_SetCurrent(0);

   config.configchanged=TRUE;
}

struct SortStat
{
   struct SortStat *Next;
   UBYTE buf[200];
   struct Area *area;
};

int CompareAlpha(struct SortStat **s1, struct SortStat **s2)
{
   return(stricmp((*s1)->buf,(*s2)->buf));
}

void Areas_Sort(void)
{
   struct jbList SortList;
   struct Area *area;
   ULONG nc,alloc;
   struct SortStat *ss,**buf,**work;
   BOOL res;

   res=rtEZRequestTags(getString(PREFS_AREAS_SORT_HOW),getString(PREFS_AREAS_SORT_GAD),NULL,NULL,
         RT_Underscore,'_',
         RT_Window,partwin,
         RT_WaitPointer,TRUE,
         RT_LockWindow, TRUE,
         TAG_END);

   if(!res)
      return;

   jbNewList(&SortList);

   for(area=(struct Area *)config.AreaList.First;area;area=area->Next)
   {
      if(!(ss=(struct SortStat *)AllocCleared(sizeof(struct SortStat))))
      {
         jbFreeList(&SortList,sizeof(struct SortStat));
         return;
      }

      if(res == 1)
      {
            sprintf(ss->buf,"%s",area->Name);
      }
      else
      {
         if(area->Group)
            sprintf(ss->buf,"%lc%s",area->Group,area->Name);

         else
            sprintf(ss->buf," %s",area->Name);
      }

      ss->area=area;

      jbAddNode(&SortList,(struct jbNode *)ss);
   }

   nc=0;

   for(ss=(struct SortStat *)SortList.First;ss;ss=ss->Next)
      nc++;

   if(nc==0)
      return;

   alloc=nc*4;

   if(!(buf=(struct SortStat **)LibAllocPooled(mempool,alloc)))
   {
      jbFreeList(&SortList,sizeof(struct SortStat));
      return;
   }

   work=buf;

   for(ss=(struct SortStat *)SortList.First;ss;ss=ss->Next)
      *work++=ss;

   qsort(buf,nc,4,CompareAlpha);

   jbNewList(&config.AreaList);

   for(work=buf;nc--;)
   {
      jbAddNode(&config.AreaList,(struct jbNode *)(*work)->area);
      work++;
   }

   LibFreePooled(mempool,buf,alloc);
   jbFreeList(&SortList,sizeof(struct SortStat));

   Areas_UpdateList();
   Areas_SetCurrent(0);
   config.configchanged=TRUE;
}

UBYTE Areas_Findbuf[100];

ulong Areas_FindNext(struct List *l);

ulong Areas_Find(struct List *l)
{
   BOOL res;

   res=rtGetString(Areas_Findbuf,99,getString(PREFS_FINDREQ),NULL,
            RT_Window,      partwin,
            RT_WaitPointer, TRUE,
            RT_LockWindow,  TRUE,
            TAG_END);

   if(!res)
      return(-1);

   return Areas_FindNext(l);
}

ulong Areas_FindNext(struct List *l)
{
   struct Node *n;
   struct TempNode *tn;
   UBYTE findtemp[100];
   UBYTE tagtemp[100];

   if(!Areas_Findbuf[0])
      return Areas_Find(l);

   n=(struct Node *)Areas_CurrentNode;
   n=n->ln_Succ;

   MakeSmall(Areas_Findbuf,findtemp);

   while(n->ln_Succ)
   {
      MakeSmall(n->ln_Name,tagtemp);

      if(strstr(tagtemp,findtemp))
         break;

      else
         n=n->ln_Succ;
   }

   if(n->ln_Succ)
   {
      tn=(struct TempNode *)n;
      return tn->num;
   }
   else
   {
      DisplayBeep(NULL);
      return(-1);
   }
}

ulong Areas_FindUnconfirmed(struct List *l)
{
   struct Node *n;
   struct TempNode *tn;
   struct Area *area;

   n=(struct Node *)Areas_CurrentNode;
   n=n->ln_Succ;

   while(n->ln_Succ)
   {
      tn=(struct TempNode *)n;
      area=tn->UserData;

      if(area->Flags & AREA_UNCONFIRMED)
         break;

      else
         n=n->ln_Succ;
   }

   if(n->ln_Succ)
   {
      tn=(struct TempNode *)n;
      return tn->num;
   }
   else
   {
      DisplayBeep(NULL);
      return(-1);
   }
}

#define IMPORTDESC_FILEBONE 1
#define IMPORTDESC_TEXTFILE 2

void SetDescription(uchar *areaname,uchar *desc,BOOL update)
{
   struct Area *area;

   for(area=(struct Area *)config.AreaList.First;area;area=area->Next)
      if(stricmp(area->Name,areaname)==0) break;

   if(area)
   {
      if(area->Description[0]==0 || update)
         mystrncpy(area->Description,desc,80);
   }
}

void strip(UBYTE *str)
{
   int c;
   for(c=strlen(str)-1;str[c] < 33 && c>=0;c--) str[c]=0;
}

void Areas_ImportDesc(int type)
{
   uchar descfile[100],buf[300],area[100],desc[100];
   BOOL update;
   BPTR fh;
   ulong res,d;

   descfile[0]=0;

   if(!OpenReq(descfile,99,getString(PREFS_REQ_SELECT_FILE),partwin,FALSE))
      return;

   update=FALSE;

   res=rtEZRequestTags(getString(PREFS_AREAS_IMPDESC_UPDATE),getString(PREFS_AREAS_IMPDESC_REQTEXT),NULL,NULL,
         RT_Underscore,'_',
         RT_Window,partwin,
         RT_WaitPointer,TRUE,
         RT_LockWindow, TRUE,
         TAG_END);

   if(!res)
      return;

   if(res == 1)
      update=TRUE;

   if(!(fh=Open(descfile,MODE_OLDFILE)))
   {
      sprintf(buf,getString(PREFS_ERR_FAILED_OPEN_READ),descfile);

      rtEZRequestTags(buf,getString(PREFS_TXT_OK),NULL,NULL,
         RT_Underscore,'_',
         RT_Window,partwin,
         RTEZ_Flags, EZREQF_CENTERTEXT,
         TAG_END);

      return;
   }

   LT_LockWindow(partwin);

   while(FGets(fh,buf,299))
   {
      strip(buf);

      if(buf[0] != 0)
      {
         switch(type)
         {
            case IMPORTDESC_FILEBONE:
               jbcpos=0;

               if(jbstrcpy(area,buf,100) && stricmp(area,"Area")==0)
               {
                  jbstrcpy(area,buf,100);
                  jbstrcpy(desc,buf,100); /* Skip level */
                  jbstrcpy(desc,buf,100); /* Skip flags */

                  while(buf[jbcpos]==32 || buf[jbcpos]==9) jbcpos++;

                  d=0;

                  while(d!=99 && buf[jbcpos]!=0)
                     desc[d++]=buf[jbcpos++];

                  desc[d]=0;

                  if(desc[0]!=0)
                  {
                     /* Now we've got everything we need */
                     SetDescription(area,desc,update);
                  }
               }
               break;

            case IMPORTDESC_TEXTFILE:
               jbcpos=0;

               jbstrcpy(area,buf,100);

               while(buf[jbcpos]==32 || buf[jbcpos]==9) jbcpos++;

               d=0;

               while(d!=99 && buf[jbcpos]!=0)
                  desc[d++]=buf[jbcpos++];

               desc[d]=0;

               if(desc[0]!=0)
                 SetDescription(area,desc,update);

               break;
         }
      }
   }

   Close(fh);
   LT_UnlockWindow(partwin);

   Areas_SetCurrent(Areas_CurrentNode->num);
   config.configchanged=TRUE;
}

struct NewMenu areanewmenus[] = { {NM_TITLE,"",NULL,0,0,NULL},                     /* >Edit               */
                                  {NM_ITEM, "",NULL,0,0,NULL},                     /* Duplicate...        */
                                  {NM_ITEM, (STRPTR)NM_BARLABEL,NULL,0,0,NULL},    /* ~~~~~~~~~~~~~~~~~~~ */
                                  {NM_ITEM, "",NULL,0,0,NULL},                     /* Remove group...     */
                                  {NM_ITEM, (STRPTR)NM_BARLABEL,NULL,0,0,NULL},    /* ~~~~~~~~~~~~~~~~~~~ */
                                  {NM_ITEM, "",NULL,0,0,NULL},                     /* Import descriptions */
                                  {NM_SUB, "",NULL,0,0,NULL},                      /*  From FILEBONE.NA   */
                                  {NM_SUB, "",NULL,0,0,NULL},                      /*  From textfile      */
                                  {NM_ITEM, (STRPTR)NM_BARLABEL,NULL,0,0,NULL},    /* ~~~~~~~~~~~~~~~~~~~ */
                                  {NM_ITEM, "",NULL,0,0,NULL},                     /* Change areas...     */

                                  {NM_TITLE,"",NULL,0,0,NULL},                     /* >Find            */
                                  {NM_ITEM, "",NULL,0,0,NULL},                     /* Find...          */
                                  {NM_ITEM, "",NULL,0,0,NULL},                     /* Find next        */
                                  {NM_ITEM, (STRPTR)NM_BARLABEL,NULL,0,0,NULL},    /* ~~~~~~~~~~~~~~~~ */
                                  {NM_ITEM, "",NULL,0,0,NULL},                     /* Find unconfirmed */

                                  {NM_END,  "",NULL,0,0,NULL}};

void PartAreas(void)
{
   struct IntuiMessage *IntuiMessage;
   APTR iaddress;
   ULONG class,code,qualifier;
   struct Area *area;
   struct Menu *areamenus;
   struct MenuItem *menuitem;
   struct Aka *aka;
   ulong num,tmp;
   uchar group;
   struct TickNode *ticknode;

   if(!config.AkaList.First)
   {
      rtEZRequestTags(getString(PREFS_SECTION_AKA_NEEDED),getString(PREFS_TXT_PROCEED),NULL,NULL,
         RT_Underscore,'_',
         RT_Window,partwin,
         RTEZ_Flags, EZREQF_CENTERTEXT,
         TAG_END);

      return;
   }

   Areas_Activepage=0;
   Areas_Selectmode=0;

   Areas_Nodeflags[0]=getString(PREFS_NODEACCESS_FULL);
   Areas_Nodeflags[1]=getString(PREFS_NODEACCESS_NOHATCH);
   Areas_Nodeflags[2]=getString(PREFS_NODEACCESS_HATCHONLY);
   Areas_Nodeflags[3]=NULL;

   Areas_Pagenames[0]=getString(PREFS_AREAS_PAGE_GENERAL);
   Areas_Pagenames[1]=getString(PREFS_AREAS_PAGE_NODES);
   Areas_Pagenames[2]=getString(PREFS_AREAS_PAGE_RAID);
   Areas_Pagenames[3]=NULL;

   Areas_Selectmodes[0]=getString(PREFS_SELECTMODE_ALL);
   Areas_Selectmodes[1]=getString(PREFS_SELECTMODE_ACCESS);
   Areas_Selectmodes[2]=NULL;

   NewList(&Areas_TempList);
   NewList(&Areas_TempNodeList);

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

   if(!parthandle)
      return;

   areanewmenus[0].nm_Label   = getString(PREFS_EDITMENU_EDIT);

   areanewmenus[1].nm_CommKey = getString(PREFS_EDITMENU_DUP);
   areanewmenus[1].nm_Label   = getString(PREFS_EDITMENU_DUP)+2;

   areanewmenus[3].nm_CommKey = getString(PREFS_EDITMENU_AREAS_REMGROUP);
   areanewmenus[3].nm_Label   = getString(PREFS_EDITMENU_AREAS_REMGROUP)+2;

   areanewmenus[5].nm_Label   = getString(PREFS_EDITMENU_AREAS_IMPORT);
   areanewmenus[6].nm_Label   = getString(PREFS_EDITMENU_AREAS_FILEBONE);
   areanewmenus[7].nm_Label   = getString(PREFS_EDITMENU_AREAS_TEXTFILE);

   areanewmenus[9].nm_CommKey = getString(PREFS_EDITMENU_AREAS_CHANGE);
   areanewmenus[9].nm_Label   = getString(PREFS_EDITMENU_AREAS_CHANGE)+2;

   areanewmenus[10].nm_Label   = getString(PREFS_FINDMENU_TITLE);

   areanewmenus[11].nm_CommKey = getString(PREFS_FINDMENU_FIND);
   areanewmenus[11].nm_Label   = getString(PREFS_FINDMENU_FIND)+2;

   areanewmenus[12].nm_CommKey = getString(PREFS_FINDMENU_FINDNEXT);
   areanewmenus[12].nm_Label   = getString(PREFS_FINDMENU_FINDNEXT)+2;

   areanewmenus[14].nm_CommKey = getString(PREFS_FINDMENU_UNCONFIRMED);
   areanewmenus[14].nm_Label   = getString(PREFS_FINDMENU_UNCONFIRMED)+2;

   areamenus=LT_LayoutMenus(parthandle,areanewmenus,
         GTMN_FrontPen,        0L,
         GTMN_TextAttr,        scr->Font,
         GTMN_NewLookMenus,    TRUE,
         LH_MenuGlyphs,        TRUE,
         TAG_DONE);

	if(!areamenus)
   {
      DisplayBeep(NULL);
      LT_DeleteHandle(parthandle);
      return;
   }

   LT_New(parthandle,
      LA_Type, HORIZONTAL_KIND,
      LA_LabelID, PREFS_AREAS_AREAS,
      TAG_DONE);

      LT_New(parthandle,
         LA_Type,      VERTICAL_KIND,
         TAG_DONE);

         LV_CreateListView(parthandle,12,4000);

         LT_New(parthandle,
            LA_Type,      BUTTON_KIND,
            LA_LabelID,   PREFS_AREAS_SORT,
            LA_Chars,     15,
            LA_ID,        1,
            TAG_DONE);

      LT_EndGroup(parthandle);

      LT_New(parthandle,
         LA_Type,      VERTICAL_KIND,
         TAG_DONE);

         LT_New(parthandle,
            LA_Type,      HORIZONTAL_KIND,
            TAG_DONE);

            LT_New(parthandle,
               LA_LabelID,       PREFS_PAGE,
               LA_Type,          CYCLE_KIND,
               LA_Chars,         30,
               LA_ID,            100,
               GTCY_Labels,      Areas_Pagenames,
               TAG_DONE);

         LT_EndGroup(parthandle);

         LT_New(parthandle,
             LA_Type,      VERTICAL_KIND,
             LA_ID,        99,
             LAGR_ActivePage,0,
             TAG_DONE);

            LT_New(parthandle,
               LA_Type,      VERTICAL_KIND,
               TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      VERTICAL_KIND,
                  LA_LabelID,   PREFS_AREAS_PAGE_GENERAL,
                  TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_UNCONFIRMED,
                     LA_Type,          CHECKBOX_KIND,
                     LA_ID,            10,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_AKA,
                     LA_Chars,         20,
                     LA_Type,          TEXT_KIND,
                     LATX_Picker,      TRUE,
                     GTTX_Border,      TRUE,
                     LA_ID,            11,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_DIR,
                     LA_Chars,         20,
                     LA_Type,          STRING_KIND,
                     GTST_MaxChars,    79,
                     LAST_Picker,      TRUE,
                     LA_ID,            12,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_COMMAND,
                     LA_Chars,         20,
                     LA_Type,          STRING_KIND,
                     GTST_MaxChars,    99,
                     LA_ID,            13,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_IGNORESEENBY,
                     LA_Type,          CHECKBOX_KIND,
                     LA_ID,            14,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_NOREPLACE,
                     LA_Type,          CHECKBOX_KIND,
                     LA_ID,            15,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_USERDATA,
                     LA_Chars,         20,
                     LA_Type,          STRING_KIND,
                     GTST_MaxChars,    39,
                     LA_ID,            16,
                     TAG_DONE);

               LT_EndGroup(parthandle);

            LT_EndGroup(parthandle);

            LT_New(parthandle,
               LA_Type,      VERTICAL_KIND,
               TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      VERTICAL_KIND,
                  LA_LabelID,   PREFS_AREAS_PAGE_NODES,
                  TAG_DONE);

                  LT_New(parthandle,
                     LA_Type,      VERTICAL_KIND,
                     TAG_DONE);

                     LT_New(parthandle,
                        LA_Type,       LISTVIEW_KIND,
                        LA_Lines,      9,
                        LALV_Link,     NIL_LINK,
                        LA_Chars,      31,
                        LALV_LockSize, TRUE,
                        LA_ID,         20,
                        TAG_DONE);

                  LT_EndGroup(parthandle);

                  LT_New(parthandle,
                     LA_Type,          CYCLE_KIND,
                     GTCY_Labels,      Areas_Nodeflags,
                     LA_ID,            21,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_Type,          XBAR_KIND,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_Type,          CYCLE_KIND,
                     GTCY_Labels,      Areas_Selectmodes,
                     LA_ID,            25,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_Type,      HORIZONTAL_KIND,
                     TAG_DONE);

                     LT_New(parthandle,
                        LA_Type,    BUTTON_KIND,
                        LA_LabelID, PREFS_AREAS_ADDGAD,
                        LA_Chars,   15,
                        LA_ID,      26,
                        TAG_DONE);

                     LT_New(parthandle,
                        LA_Type,    BUTTON_KIND,
                        LA_LabelID, PREFS_AREAS_REMOVEGAD,
                        LA_Chars,   15,
                        LA_ID,      27,
                        TAG_DONE);

                  LT_EndGroup(parthandle);

               LT_EndGroup(parthandle);

            LT_EndGroup(parthandle);

            LT_New(parthandle,
               LA_Type,      VERTICAL_KIND,
               TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      VERTICAL_KIND,
                  LA_LabelID,   PREFS_AREAS_PAGE_RAID,
                  TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_MANDATORY,
                     LA_Type,          CHECKBOX_KIND,
                     LA_ID,            30,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_DEFREADONLY,
                     LA_Type,          CHECKBOX_KIND,
                     LA_ID,            31,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_DESC,
                     LA_Chars,         20,
                     LA_Type,          STRING_KIND,
                     GTST_MaxChars,    79,
                     LA_ID,            32,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_LabelID,       PREFS_AREAS_GROUP,
                     LA_Chars,         20,
                     LA_Type,          TEXT_KIND,
                     LATX_LockSize,    TRUE,
                     LATX_Picker,      TRUE,
                     GTTX_Border,      TRUE,
                     LA_ID,            33,
                     TAG_DONE);

               LT_EndGroup(parthandle);

            LT_EndGroup(parthandle);

         LT_EndGroup(parthandle);

      LT_EndGroup(parthandle);

   LT_EndGroup(parthandle);

   partwin=LT_Build(parthandle,LAWN_IDCMP,    IDCMP_CLOSEWINDOW|IDCMP_RAWKEY,
                               LAWN_Parent,   mainwin,
                               LAWN_HelpHook, &AreasHelpHook,
                               LAWN_Title,    getString(PREFS_BUTTON_AREAS),
                               WA_Flags,      WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_NEWLOOKMENUS,
                               LAWN_Menu,     areamenus,
                               TAG_END);

   if(!partwin)
   {
      LT_DeleteHandle(parthandle);
	   FreeMenus(areamenus);
      DisplayBeep(NULL);
      return;
   }

   Areas_UpdateList();
   Areas_SetCurrent(0);
   Areas_ChangedNum();

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

         LT_ReplyIMsg(IntuiMessage);

         switch(class)
         {
            case IDCMP_RAWKEY:         if(code == RAWKEY_TAB) LT_Activate(parthandle,4000+LV_STRING);
                                       break;


            case IDCMP_IDCMPUPDATE:    if(Areas_CurrentNode)
                                       {
                                          area=Areas_CurrentNode->UserData;

                                          switch(((struct Gadget *)iaddress)->GadgetID)
                                          {
                                             case 11:
                                                if(aka=AskAka(partwin))
                                                {
                                                   area->Aka=aka;
                                                   Areas_SetCurrent(Areas_CurrentNode->num);
                                                   config.configchanged=TRUE;
                                                }
                                                break;

                                             case 12:
                                               Areas_UpdateConfig();

                                               if(OpenReqDir(area->Directory,79,getString(PREFS_REQ_SELECT_DIR),partwin))
                                                   config.configchanged=TRUE;

                                               LT_SetAttributes(parthandle,12,GTST_String,area->Directory,TAG_END);
                                               break;

                                             case 20:
                                                if(Areas_CurrentNodeNode)
                                                {
                                                   ticknode=Areas_CurrentNodeNode->UserData;

                                                   if(ticknode->Flags & TICKNODE_WRITEONLY)
                                                      ticknode->Flags=0;

                                                   else if(ticknode->Flags == 0)
                                                      ticknode->Flags = TICKNODE_READONLY;

                                                   else if(ticknode->Flags & TICKNODE_READONLY)
                                                      ticknode->Flags = TICKNODE_WRITEONLY;

                                                   Areas_MakeNode(ticknode,Areas_CurrentNodeNode);
                                                   Areas_SetCurrentNode(Areas_CurrentNodeNode->num);
                                                   config.configchanged=TRUE;
                                                }
                                                break;

                                             case 33:
                                               group=AskGroup(partwin,getString(PREFS_NO_GROUP));

                                               if(group != -1)
                                               {
                                                   area->Group=group;
                                                   Areas_UpdateConfig();
                                                   Areas_SetCurrent(Areas_CurrentNode->num);
                                                   config.configchanged=TRUE;
                                               }
                                               break;
                                          }
                                       }
                                       break;

            case IDCMP_GADGETUP:       /* No current node necessary */

                                       switch(((struct Gadget *)iaddress)->GadgetID)
                                       {
                                          case 25:
                                             Areas_Selectmode=code;
                                             break;

                                          case 100:
                                             Areas_UpdateConfig();
                                             LT_SetAttributes(parthandle,99,LAGR_ActivePage,code,TAG_END);
                                             Areas_Activepage=code;

                                             if(Areas_CurrentNode)
                                                Areas_SetCurrent(Areas_CurrentNode->num);

                                             else
                                                Areas_SetCurrent(0);

                                             break;

                                          case 4000+LV_ADD:
                                             Areas_UpdateConfig();
                                             Areas_Add();
                                             break;
                                       }

                                       /* Current node necessary */

                                       if(Areas_CurrentNode)
                                       {
                                          area=Areas_CurrentNode->UserData;

                                          switch(((struct Gadget *)iaddress)->GadgetID)
                                          {
                                             case 1:
                                                Areas_UpdateConfig();
                                                Areas_Sort();
                                                break;

                                             case 20:
                                                Areas_SetCurrentNode(code);
                                                break;

                                             case 21:
                                                if(Areas_CurrentNodeNode)
                                                {
                                                   ticknode=Areas_CurrentNodeNode->UserData;

                                                   if(code == 0)
                                                      ticknode->Flags=0;

                                                   if(code == 1)
                                                      ticknode->Flags = TICKNODE_READONLY;

                                                   if(code == 2)
                                                      ticknode->Flags = TICKNODE_WRITEONLY;

                                                   Areas_MakeNode(ticknode,Areas_CurrentNodeNode);
                                                   Areas_SetCurrentNode(Areas_CurrentNodeNode->num);
                                                   config.configchanged=TRUE;
                                                }
                                                break;

                                             case 26:
                                                Areas_AddNode();
                                                break;

                                             case 27:
                                                if(Areas_CurrentNodeNode)
                                                {
                                                   tmp=Areas_CurrentNodeNode->num;

                                                   if(!Areas_CurrentNodeNode->Node.ln_Succ->ln_Succ)
                                                      tmp--;

                                                   jbFreeNode(&area->TickNodes,(struct jbNode *)Areas_CurrentNodeNode->UserData,sizeof(struct TickNode));

                                                   Areas_UpdateNodeList();
                                                   Areas_SetCurrentNode(tmp);

                                                   config.configchanged=TRUE;
                                                }
                                                break;

                                             case 4000+LV_LIST:
                                                Areas_UpdateConfig();
                                                Areas_SetCurrent(code);
                                                break;

                                             case 4000+LV_STRING:
                                                if(CheckDupeArea(getgadgetstring((struct Gadget *)iaddress),area))
                                                {
                                                   LV_DetachList(parthandle,4000);
                                                   strcpy(Areas_CurrentNode->buf,getgadgetstring((struct Gadget *)iaddress));
                                                   strcpy(area->Name,getgadgetstring((struct Gadget *)iaddress));
                                                   LV_AttachList(parthandle,4000,&Areas_TempList);
                                                   config.configchanged=TRUE;
                                                }
                                                else
                                                {
                                                   RequestError(partwin,getString(PREFS_AREAS_ALREADY_HAS),
                                                      getgadgetstring((struct Gadget *)iaddress));

                                                   LT_Activate(parthandle,4000+LV_STRING);
                                                }
                                                break;

                                             case 4000+LV_REMOVE:
                                                Areas_Remove();
                                                break;

                                             case 4000+LV_UP:
                                                LV_MoveUp(parthandle,4000,&Areas_TempList,Areas_CurrentNode,&config.AreaList);
                                                config.configchanged=TRUE;
                                                break;

                                             case 4000+LV_DOWN:
                                                LV_MoveDown(parthandle,4000,&Areas_TempList,Areas_CurrentNode,&config.AreaList);
                                                config.configchanged=TRUE;
                                                break;
                                          }
                                      }
                                      break;

            case IDCMP_MENUPICK:      num=code;
                                      while(num!=MENUNULL)
                                      {
                                          if(Areas_CurrentNode)
                                          {
                                             area=Areas_CurrentNode->UserData;

                                             if(MENUNUM(num)==0 && ITEMNUM(num)==0)
                                             {
                                                Areas_UpdateConfig();
                                                Areas_Duplicate();
                                             }

                                             if(MENUNUM(num)==0 && ITEMNUM(num)==2)
                                             {
                                                Areas_UpdateConfig();
                                                Areas_RemoveGroup();
                                             }

                                             if(MENUNUM(num)==0 && ITEMNUM(num)==4)
                                             {
                                                Areas_UpdateConfig();

                                                if(SUBNUM(num)==0)
                                                   Areas_ImportDesc(IMPORTDESC_FILEBONE);

                                                else
                                                   Areas_ImportDesc(IMPORTDESC_TEXTFILE);
                                             }

                                             if(MENUNUM(num)==0 && ITEMNUM(num)==6)
                                             {
                                                Areas_UpdateConfig();
                                                LT_LockWindow(partwin);
                                                ChangeAreas();
                                                LT_UnlockWindow(partwin);
                                                Areas_SetCurrent(0);
                                             }

                                             if(MENUNUM(num)==1 && ITEMNUM(num)==0)
                                             {
                                                Areas_UpdateConfig();
                                                tmp=Areas_Find(&Areas_TempList);

                                                if(tmp != -1)
                                                   Areas_SetCurrent(tmp);
                                             }

                                             if(MENUNUM(num)==1 && ITEMNUM(num)==1)
                                             {
                                                Areas_UpdateConfig();
                                                tmp=Areas_FindNext(&Areas_TempList);

                                                if(tmp != -1)
                                                   Areas_SetCurrent(tmp);
                                             }

                                             if(MENUNUM(num)==1 && ITEMNUM(num)==3)
                                             {
                                                Areas_UpdateConfig();
                                                tmp=Areas_FindUnconfirmed(&Areas_TempList);

                                                if(tmp != -1)
                                                   Areas_SetCurrent(tmp);
                                             }

                                             menuitem=ItemAddress(areamenus,num);
                                             num=menuitem->NextSelect;
                                          }
                                      }
                                      break;

            case IDCMP_CLOSEWINDOW:   Areas_UpdateConfig();
                                      ClearMenuStrip(parthandle->Window);
                                      LT_DeleteHandle(parthandle);
                                      FreeMenus(areamenus);
                                      parthandle=NULL;

                                      FreeTempNodes(&Areas_TempList);
                                      FreeTempNodes(&Areas_TempNodeList);
                                      return;

         }
      }
      WaitPort(partwin->UserPort);
   }
}

