#include <CrashPrefs.h>

STRPTR nodegroups[]={"General","Groups","Areas","AreaFix","Banned",NULL};
STRPTR nodeseenby[]={"Normal","None","Tiny",NULL};

STRPTR *nodeareaflags[]={"Normal","Read-only","Write-only","Feed",NULL};

STRPTR *nodeaddmodes[]={"Select from: All","Select from: With access",NULL};

STRPTR *nodewhenremoved[]={"Do nothing","Send AreaFix msg","Send text msg","AreaFix + text",NULL};

struct List tmp_nodelist;
struct List nodegrouplist;
struct List nodeareaslist;
struct List notnodeareaslist;
struct List notnodeareasaccesslist;
struct List nodepackerslist;
struct List nodebannedlist;
struct List notnodebannedlist;

STRPTR  *nodegroupflags[]={"No access","Access","Read-only access",NULL};

ULONG nodesnum,currentnode,currentnodegroup;
ULONG nodeareasnum,currentnodearea;
ULONG nodebannednum,currentnodebanned;

struct ConfigNode *nodenode;

BOOL CheckFlags(UBYTE group,UBYTE *node);

struct Hook NodesHelpHook = { {NULL}, HelpHookEntry,NULL,HELP_NODES};

struct Menu *nodemenus;

struct NewMenu nodenewmenus[] = {
   {NM_TITLE,"Edit","",0,0,NULL},
   {NM_ITEM, "Duplicate node...","D",0,0,NULL},
   {NM_ITEM, (STRPTR)NM_BARLABEL,NULL,0,0,NULL},
   {NM_ITEM, "Add mandatory and new areas...","M",0,0,NULL},
   {NM_END,  "","",0,0,NULL}};

void RefreshNodeGrouplist(void)
{
   struct TempNode *tempnode;
   ULONG c;
   UBYTE *add;

   LT_SetAttributes(parthandle,5711,GTLV_Labels,~0,TAG_END);
   FreeTempNodes(&nodegrouplist);

   for(c=0;c<26;c++)
   {
      if(!(tempnode=(struct TempNode *)AllocMem(sizeof(struct TempNode),MEMF_CLEAR)))
      {
         DisplayBeep(NULL);
         FreeTempNodes(&nodegrouplist);
         return;
      }

      add="";
      
      if(CheckFlags('A'+c,nodenode->AddGroups))
         add="@";

      if(CheckFlags('A'+c,nodenode->Groups))
      {
         if(CheckFlags('A'+c,nodenode->ReadOnlyGroups))
            sprintf(tempnode->buf,"%s!%lc: %s",add,'A'+c,cfg_GroupNames[c]);

         else
            sprintf(tempnode->buf,"%s*%lc: %s",add,'A'+c,cfg_GroupNames[c]);
      }

      else
         sprintf(tempnode->buf,"%s%lc: %s",add,'A'+c,cfg_GroupNames[c]);

      tempnode->Node.ln_Name=tempnode->buf;
      AddTail(&nodegrouplist,(struct Node *)tempnode);
   }

   LT_SetAttributes(parthandle,5711,GTLV_Labels,&nodegrouplist,TAG_END);
}

void RefreshNodelist(void)
{
   struct ConfigNode *cnode;
   struct TempNode *tempnode;

   LT_SetAttributes(parthandle,4711,GTLV_Labels,~0,TAG_END);

   FreeTempNodes(&tmp_nodelist);
   nodesnum=0;

   for(cnode=CNodeList.First;cnode;cnode=cnode->Next)
   {
      if(!(tempnode=(struct TempNode *)AllocMem(sizeof(struct TempNode),MEMF_CLEAR)))
      {
         DisplayBeep(NULL);
         FreeTempNodes(&tmp_nodelist);
         return;
      }

      sprintf(tempnode->buf,"%lu:%lu/%lu.%lu",cnode->Node.Zone,cnode->Node.Net,cnode->Node.Node,cnode->Node.Point);
      tempnode->Node.ln_Name=tempnode->buf;
      tempnode->UserData=cnode;
      AddTail(&tmp_nodelist,(struct Node *)tempnode);
      nodesnum++;
   }
   LT_SetAttributes(parthandle,4711,GTLV_Labels,&tmp_nodelist,TAG_END);
}

void RefreshNodeAreaslist(void)
{
   struct TossNode *tossnode;
   struct Area *area;
   struct TempNode *tnode;

   LT_SetAttributes(parthandle,6711,GTLV_Labels,~0,TAG_END);

   FreeTempNodes(&nodeareaslist);
   FreeTempNodes(&notnodeareaslist);
   nodeareasnum=0;

   for(area=AreaList.First;area;area=area->Next)
   {
      if(!(area->Flags & AREA_BAD) &&
         !(area->Flags & AREA_NETMAIL) &&
         !(area->Flags & AREA_DEFAULT))
      {
         for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
            if(tossnode->ConfigNode == nodenode) break;

         if(!(tnode=(struct TempNode *)AllocMem(sizeof(struct TempNode),MEMF_CLEAR)))
         {
            FreeTempNodes(&nodeareaslist);
            FreeTempNodes(&notnodeareaslist);
            DisplayBeep(NULL);
            return;
         }

         if(tossnode)
         {
            if(tossnode->Flags & TOSSNODE_READONLY) strcat(tnode->buf,"!");
            if(tossnode->Flags & TOSSNODE_WRITEONLY) strcat(tnode->buf,"@");
            if(tossnode->Flags & TOSSNODE_FEED) strcat(tnode->buf,"%");

            strcat(tnode->buf,area->Tagname);

            tnode->Node.ln_Name=tnode->buf;
            tnode->UserData=area;
            AddTail(&nodeareaslist,(struct Node *)tnode);
            nodeareasnum++;
         }
         else
         {
            strcpy(tnode->buf,area->Tagname);

            tnode->Node.ln_Name=tnode->buf;
            tnode->UserData=area;
            AddTail(&notnodeareaslist,(struct Node *)tnode);
         }
      }
   }

   LT_SetAttributes(parthandle,6711,GTLV_Labels,&nodeareaslist,TAG_END);
}

BOOL CheckFlags(UBYTE group,UBYTE *node);

void RefreshNotNodeAreasAccessList(void)
{
   struct TossNode *tossnode;
   struct Area *area;
   struct TempNode *tnode;

   FreeTempNodes(&notnodeareasaccesslist);

   for(area=AreaList.First;area;area=area->Next)
   {
      if(!(area->Flags & AREA_BAD) &&
         !(area->Flags & AREA_NETMAIL) &&
         !(area->Flags & AREA_DEFAULT))
      {
         for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
            if(tossnode->ConfigNode == nodenode) break;

         if(!tossnode && CheckFlags(area->Group,nodenode->Groups))
         {
            if(!(tnode=(struct TempNode *)AllocMem(sizeof(struct TempNode),MEMF_CLEAR)))
            {
               FreeTempNodes(&notnodeareasaccesslist);
               DisplayBeep(NULL);
               return;
            }

            strcpy(tnode->buf,area->Tagname);
            tnode->Node.ln_Name=tnode->buf;
            tnode->UserData=area;
            AddTail(&notnodeareasaccesslist,(struct Node *)tnode);
         }
      }
   }
}

void SetAreaNodes(void)
{
   struct TossNode *tossnode;
   struct Area *area;
   struct TempNode *tempnode;
   ULONG c;

   if(nodeareasnum)
   {
      LT_SetAttributes(parthandle,611,GA_Disabled,FALSE,TAG_DONE);

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

      area=tempnode->UserData;

      for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
         if(tossnode->ConfigNode == nodenode) break;

      c=0;
      if(tossnode->Flags & TOSSNODE_READONLY) c=1;
      if(tossnode->Flags & TOSSNODE_WRITEONLY) c=2;
      if(tossnode->Flags & TOSSNODE_FEED) c=3;

      LT_SetAttributes(parthandle,601,GA_Disabled,FALSE,TAG_DONE);
      LT_SetAttributes(parthandle,601,GTCY_Active,c,TAG_END);
   }
   else
   {
      LT_SetAttributes(parthandle,601,GA_Disabled,TRUE,TAG_DONE);
      LT_SetAttributes(parthandle,611,GA_Disabled,TRUE,TAG_DONE);
   }
}

void RefreshNodeBannedlist(void)
{
   struct BannedNode *bannednode;
   struct Area *area;
   struct TempNode *tnode;

   LT_SetAttributes(parthandle,7711,GTLV_Labels,~0,TAG_END);

   FreeTempNodes(&nodebannedlist);
   FreeTempNodes(&notnodebannedlist);
   nodebannednum=0;

   for(area=AreaList.First;area;area=area->Next)
   {
      if(!(area->Flags & AREA_BAD) &&
         !(area->Flags & AREA_NETMAIL) &&
         !(area->Flags & AREA_DEFAULT))
      {
         for(bannednode=area->BannedNodes.First;bannednode;bannednode=bannednode->Next)
            if(bannednode->ConfigNode == nodenode) break;

         if(!(tnode=(struct TempNode *)AllocMem(sizeof(struct TempNode),MEMF_CLEAR)))
         {
            FreeTempNodes(&nodebannedlist);
            FreeTempNodes(&notnodebannedlist);
            DisplayBeep(NULL);
            return;
         }

         strcpy(tnode->buf,area->Tagname);
         tnode->Node.ln_Name=tnode->buf;
         tnode->UserData=area;

         if(bannednode)
         {
            AddTail(&nodebannedlist,(struct Node *)tnode);
            nodebannednum++;
         }
         else
         {
            AddTail(&notnodebannedlist,(struct Node *)tnode);
         }
      }
   }

   LT_SetAttributes(parthandle,7711,GTLV_Labels,&nodebannedlist,TAG_END);
}

void SetBannedNodes(void)
{
   if(nodebannednum)
      LT_SetAttributes(parthandle,711,GA_Disabled,FALSE,TAG_DONE);

   else
      LT_SetAttributes(parthandle,711,GA_Disabled,TRUE,TAG_DONE);
}

UBYTE areadefgroupbuf[100];
UBYTE areapackerbuf[100];

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

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

   currentnode=num;
}

ULONG nodeactivepage;

void SetNode(ULONG num)
{
   ULONG c,cyclenum;

   if(currentnode != -1)
   {
      if(nodeactivepage == 0)
      {
         strcmpcpy(nodenode->SysopName,(UBYTE *)LT_GetAttributes(parthandle,100,TAG_END));
         strcmpcpy(nodenode->PacketPW,(UBYTE *)LT_GetAttributes(parthandle,101,TAG_END));
      }

      if(nodeactivepage == 3)
      {
         ULONG oldflags;

         strcmpcpy(nodenode->AreafixPW,(UBYTE *)LT_GetAttributes(parthandle,202,TAG_END));
         strcmpcpy(nodenode->RemoteAFName,(UBYTE *)LT_GetAttributes(parthandle,204,TAG_END));
         strcmpcpy(nodenode->RemoteAFPw,(UBYTE *)LT_GetAttributes(parthandle,205,TAG_END));

         oldflags=nodenode->Flags;
         nodenode->Flags&=~(NODE_SENDAREAFIX|NODE_SENDTEXT);
         cyclenum=LT_GetAttributes(parthandle,206,TAG_END);
         
         if(cyclenum == 1 || cyclenum == 3) nodenode->Flags|=NODE_SENDAREAFIX;
         if(cyclenum == 2 || cyclenum == 3) nodenode->Flags|=NODE_SENDTEXT;

         if(oldflags != nodenode->Flags)
            saveconfig=TRUE;
      }
   }

   if(nodesnum == 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);

      LT_SetAttributes(parthandle,100,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,101,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,102,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,103,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,104,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,105,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,106,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,107,GA_Disabled,TRUE,TAG_END);

      LT_SetAttributes(parthandle,5711,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,5713,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,5714,GA_Disabled,TRUE,TAG_END);

      LT_SetAttributes(parthandle,6711,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,7711,GA_Disabled,TRUE,TAG_END);

      LT_SetAttributes(parthandle,601,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,610,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,612,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,611,GA_Disabled,TRUE,TAG_END);

      LT_SetAttributes(parthandle,200,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,201,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,202,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,203,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,204,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,205,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,206,GA_Disabled,TRUE,TAG_END);

      OffMenu(partwin,FULLMENUNUM(0,0,0));
      OffMenu(partwin,FULLMENUNUM(0,2,0));

      LT_SetAttributes(parthandle,710,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,711,GA_Disabled,TRUE,TAG_END);
   }
   else
   {
      LT_SetAttributes(parthandle,100,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,101,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,102,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,103,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,104,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,105,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,106,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,107,GA_Disabled,FALSE,TAG_END);

      LT_SetAttributes(parthandle,5711,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,5713,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,5714,GA_Disabled,FALSE,TAG_END);

      LT_SetAttributes(parthandle,6711,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,7711,GA_Disabled,FALSE,TAG_END);

      LT_SetAttributes(parthandle,601,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,610,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,612,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,611,GA_Disabled,FALSE,TAG_END);

      LT_SetAttributes(parthandle,200,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,201,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,202,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,203,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,204,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,205,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,206,GA_Disabled,FALSE,TAG_END);

      OnMenu(partwin,FULLMENUNUM(0,0,0));
      OnMenu(partwin,FULLMENUNUM(0,2,0));

      LT_SetAttributes(parthandle,710,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,711,GA_Disabled,FALSE,TAG_END);
   }

   if(num!=-1)
   {
      nodenode=CNodeList.First;
      for(c=0;c<num;c++) nodenode=nodenode->Next;

      if(nodesnum)
      {
         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!=nodesnum-1)       LT_SetAttributes(parthandle,13,GA_Disabled,FALSE,TAG_END);
      else                      LT_SetAttributes(parthandle,13,GA_Disabled,TRUE,TAG_END);

      LT_SetAttributes(parthandle,100,GTST_String,nodenode->SysopName,TAG_END);
      LT_SetAttributes(parthandle,101,GTST_String,nodenode->PacketPW,TAG_END);

      if(nodenode->Packer) strcpy(areapackerbuf,nodenode->Packer->Name);
      else                 strcpy(areapackerbuf,"<None>");

      LT_SetAttributes(parthandle,102,GTTX_Text,areapackerbuf,TAG_END);

      if(nodenode->Flags & NODE_PASSIVE) LT_SetAttributes(parthandle,103,GTCB_Checked,TRUE,TAG_END);
      else                               LT_SetAttributes(parthandle,103,GTCB_Checked,FALSE,TAG_END);

      if(nodenode->Flags & NODE_STONEAGE) LT_SetAttributes(parthandle,104,GTCB_Checked,TRUE,TAG_END);
      else                                LT_SetAttributes(parthandle,104,GTCB_Checked,FALSE,TAG_END);

      if(nodenode->Flags & NODE_PACKNETMAIL) LT_SetAttributes(parthandle,106,GTCB_Checked,TRUE,TAG_END);
      else                                   LT_SetAttributes(parthandle,106,GTCB_Checked,FALSE,TAG_END);

      if(nodenode->Flags & NODE_AUTOADD) LT_SetAttributes(parthandle,107,GTCB_Checked,TRUE,TAG_END);
      else                               LT_SetAttributes(parthandle,107,GTCB_Checked,FALSE,TAG_END);

      if(nodenode->Flags & NODE_TINYSEENBY)       LT_SetAttributes(parthandle,105,GTCY_Active,2,TAG_END);
      else if(nodenode->Flags & NODE_NOSEENBY)    LT_SetAttributes(parthandle,105,GTCY_Active,1,TAG_END);
      else                                        LT_SetAttributes(parthandle,105,GTCY_Active,0,TAG_END);

      if(nodenode->Flags & NODE_NOTIFY) LT_SetAttributes(parthandle,200,GTCB_Checked,TRUE,TAG_END);
      else                              LT_SetAttributes(parthandle,200,GTCB_Checked,FALSE,TAG_END);

      if(nodenode->Flags & NODE_FORWARDREQ) LT_SetAttributes(parthandle,201,GTCB_Checked,TRUE,TAG_END);
      else                                  LT_SetAttributes(parthandle,201,GTCB_Checked,FALSE,TAG_END);

      LT_SetAttributes(parthandle,202,GTST_String,nodenode->AreafixPW,TAG_END);

      if(nodenode->DefaultGroup) sprintf(areadefgroupbuf,"%lc: %s",nodenode->DefaultGroup,cfg_GroupNames[nodenode->DefaultGroup-'A']);
      else                       strcpy(areadefgroupbuf,"<No group>");

      LT_SetAttributes(parthandle,203,GTTX_Text,areadefgroupbuf,TAG_END);

      LT_SetAttributes(parthandle,204,GTST_String,nodenode->RemoteAFName,TAG_END);
      LT_SetAttributes(parthandle,205,GTST_String,nodenode->RemoteAFPw,TAG_END);

      cyclenum=0;

      if((nodenode->Flags & NODE_SENDAREAFIX) && (nodenode->Flags & NODE_SENDTEXT))
         cyclenum=3;

      else if(nodenode->Flags & NODE_SENDAREAFIX)
         cyclenum=1;

      else if(nodenode->Flags & NODE_SENDTEXT)
         cyclenum=2;

      LT_SetAttributes(parthandle,206,GTCY_Active,cyclenum,TAG_END);

      RefreshNodeGrouplist();

      currentnodearea=0;
      RefreshNodeAreaslist();
      SetAreaNodes();

      currentnodebanned=0;
      RefreshNodeBannedlist();
      SetBannedNodes();

      LT_SetAttributes(parthandle,6711,GTLV_Selected,currentnodearea,GTLV_MakeVisible,currentnodearea,TAG_DONE);

      LT_SetAttributes(parthandle,5711,GTLV_Selected,0,GTLV_MakeVisible,0,TAG_DONE);

      if(CheckFlags('A',nodenode->Groups))
      {
         if(CheckFlags('A',nodenode->ReadOnlyGroups))
         {
            LT_SetAttributes(parthandle,5713,GTCY_Active,2,TAG_DONE);
         }
         else
         {
            LT_SetAttributes(parthandle,5713,GTCY_Active,1,TAG_DONE);
         }
      }
      else
      {
         LT_SetAttributes(parthandle,5713,GTCY_Active,0,TAG_DONE);
      }

      if(CheckFlags('A',nodenode->AddGroups))
      {
         LT_SetAttributes(parthandle,5714,GTCB_Checked,TRUE,TAG_DONE);
      }
      else
      {
         LT_SetAttributes(parthandle,5714,GTCB_Checked,FALSE,TAG_DONE);
      }
   }

   currentnode=num;
}

BOOL CheckDupeNode(UBYTE *buf,ULONG num)
{
   struct Node4D n4d;
   struct ConfigNode *cnode;
   ULONG c;

   if(!Parse4D(buf,&n4d))
   {
      rtEZRequestTags("Invalid node number","_Ok",NULL,NULL,RT_Underscore,'_',
                                                            RT_Window,partwin,
                                                            RT_WaitPointer, TRUE,
                                                            RT_LockWindow, TRUE,
                                                            TAG_END);
      return(FALSE);
   }

   for(cnode=CNodeList.First,c=0;cnode;cnode=cnode->Next,c++)
      if(Compare4D(&cnode->Node,&n4d)==0 && c!=num) break;

   if(cnode)
   {
      rtEZRequestTags("You already have that node","_Ok",NULL,NULL,RT_Underscore,'_',
                                                                   RT_Window,partwin,
                                                                   RT_WaitPointer, TRUE,
                                                                   RT_LockWindow, TRUE,
                                                                   TAG_END);
      return(FALSE);
   }

   return(TRUE);
}

void AddNode(void)
{
   struct ConfigNode *cnode;
   struct Node4D n4d;
   UBYTE buf[200];
   BOOL res;
   BOOL kg;

   kg=TRUE;
   buf[0]=0;

   while(kg)
   {
      res=rtGetString(buf,50,"Add node",NULL,RT_Window,partwin,
                                            RT_WaitPointer, TRUE,
                                            RT_LockWindow, TRUE,
                                            TAG_END);

      if(!res)
         return;

      if(CheckDupeNode(buf,-1))
         kg=FALSE;
   }

   Parse4D(buf,&n4d);

   if(cnode=(struct ConfigNode *)AllocMem(sizeof(struct ConfigNode),MEMF_CLEAR))
   {
      jbNewList(&cnode->RemoteAFList);
      jbAddNode(&CNodeList,(struct jbNode *)cnode);
      Copy4D(&cnode->Node,&n4d);
      RefreshNodelist();
      SetNode(nodesnum-1);
      LT_SetAttributes(parthandle,4711,GTLV_Selected,currentnode,GTLV_MakeVisible,currentnode,TAG_END);
      saveconfig=TRUE;
   }
   else
   {
      DisplayBeep(NULL);
   }
}

void RemNode(void)
{
   struct Arealist *arealist,*arealist2;
   struct Area *area;
   struct TossNode *tossnode,*tossnode2;
   struct BannedNode *bannednode,*bannednode2;
   ULONG arealists,areas,tmp;
   UBYTE buf[400],buf2[400];
   BOOL res;
   struct ConfigNode *tmpnode;
   
   arealists=0;
   areas=0;

   for(arealist=ArealistList.First;arealist;arealist=arealist->Next)
      if(arealist->Node == nodenode) arealists++;

   for(area=AreaList.First;area;area=area->Next)
      for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
         if(tossnode->ConfigNode == nodenode) areas++;

   sprintf(buf,"Do you really want to remove the node %lu:%lu/%lu.%lu?\n"
               "You send %lu areas to that node and the nodes\n"
               "will be removed from all areas too.",
                  nodenode->Node.Zone,
                  nodenode->Node.Net,
                  nodenode->Node.Node,
                  nodenode->Node.Point,
                  areas);

   if(arealists)
   {
      sprintf(buf2,"\n\nYou also have %lu arealists for that node\n"
                   "They will be removed from the Arealist settings.",arealists);

      strcat(buf,buf2);
   }

   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;

   arealist=ArealistList.First;

   while(arealist)
   {
      arealist2=arealist->Next;

      if(arealist->Node == nodenode)
         jbFreeNode(&ArealistList,(struct jbNode *)arealist,sizeof(struct Arealist));

      arealist=arealist2;
   }

   for(area=AreaList.First;area;area=area->Next)
      if(!(area->Flags & AREA_NETMAIL))
      {
         tossnode=area->TossNodes.First;

         while(tossnode)
         {
            tossnode2=tossnode->Next;

            if(tossnode->ConfigNode == nodenode)
               jbFreeNode(&area->TossNodes,(struct jbNode *)tossnode,sizeof(struct TossNode));

            tossnode=tossnode2;
         }

         bannednode=area->BannedNodes.First;

         while(bannednode)
         {
            bannednode2=bannednode->Next;

            if(bannednode->ConfigNode == nodenode)
               jbFreeNode(&area->BannedNodes,(struct jbNode *)bannednode,sizeof(struct BannedNode));

            bannednode=bannednode2;
         }
      }

   tmp=currentnode;
   tmpnode=nodenode;

   SetNode(-1);

   jbFreeList(&tmpnode->RemoteAFList,tmpnode->RemoteAFList.First,sizeof(struct RemoteAFCommand));
   jbFreeNode(&CNodeList,(struct jbNode *)tmpnode,sizeof(struct ConfigNode));
   RefreshNodelist();

   if(tmp == nodesnum) tmp--;
   SetNode(tmp);
   saveconfig=TRUE;
}

void DuplicateNode(void)
{
   BOOL res;
   struct Area *area;
   struct TossNode *tnode,*tmptnode;
   struct BannedNode *bnode,*tmpbnode;
   UBYTE buf[80];
   struct ConfigNode *cnode;

   sprintf(buf,"%lu:%lu/%lu.%lu",
      nodenode->Node.Zone,
      nodenode->Node.Net,
      nodenode->Node.Node,
      nodenode->Node.Point);

   res=rtGetString(buf,79,"Enter new node number",NULL,
            RT_Window,  partwin,
            RT_WaitPointer, TRUE,
            RT_LockWindow, TRUE,
            TAG_END);

   if(!res)
      return;

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

   if(!(cnode=AllocMem(sizeof(struct ConfigNode),MEMF_CLEAR)))
   {
      DisplayBeep(NULL);
      return;
   }

   CopyMem(nodenode,cnode,sizeof(struct ConfigNode));
   jbNewList(&nodenode->RemoteAFList);
   
   cnode->Next=NULL;
   Parse4D(buf,&cnode->Node);

   for(area=AreaList.First;area;area=area->Next)
   {
      if(!(area->Flags & AREA_NETMAIL))
      {
         for(tnode=area->TossNodes.First;tnode;tnode=tnode->Next)
            if(tnode->ConfigNode == nodenode) break;

         if(tnode)
         {
            if(tmptnode=AllocMem(sizeof(struct TossNode),MEMF_CLEAR))
            {
               tmptnode->ConfigNode=cnode;
               tmptnode->Flags=tnode->Flags;
               jbAddNode(&area->TossNodes,(struct jbNode *)tmptnode);
            }
         }

         for(bnode=area->BannedNodes.First;bnode;bnode=bnode->Next)
            if(bnode->ConfigNode == nodenode) break;

         if(bnode)
         {
            if(tmpbnode=AllocMem(sizeof(struct BannedNode),MEMF_CLEAR))
            {
               tmpbnode->ConfigNode=cnode;
               jbAddNode(&area->BannedNodes,(struct jbNode *)tmpbnode);
            }
         }
      }
   }

   jbAddNode(&CNodeList,(struct jbNode *)cnode);
   RefreshNodelist();
   SetNode(nodesnum-1);
   LT_SetAttributes(parthandle,4711,GTLV_Selected,currentnode,GTLV_MakeVisible,currentnode,TAG_END);
   saveconfig=TRUE;
}

void AddMandatory(void)
{
   struct Area *area;
   struct TossNode *tnode,*tmptnode;
   ULONG added;
   UBYTE buf[100];

   added=0;

   for(area=AreaList.First;area;area=area->Next)
   {
      if(!(area->Flags & AREA_NETMAIL))
      {
         for(tnode=area->TossNodes.First;tnode;tnode=tnode->Next)
            if(tnode->ConfigNode == nodenode) break;

         if(!tnode)
         {
            if(area->Group && (area->Flags & AREA_MANDATORY) && CheckFlags(area->Group,nodenode->Groups))
            {
               if(tmptnode=AllocMem(sizeof(struct TossNode),MEMF_CLEAR))
               {
                  tmptnode->ConfigNode=nodenode;

                  if((area->Flags & AREA_DEFREADONLY) || CheckFlags(area->Group,nodenode->ReadOnlyGroups))
                     tmptnode->Flags|=TOSSNODE_READONLY;

                  jbAddNode(&area->TossNodes,(struct jbNode *)tmptnode);
                  added++;
               }
            }
            if(area->Group && CheckFlags(area->Group,nodenode->AddGroups))
            {
               if(tmptnode=AllocMem(sizeof(struct TossNode),MEMF_CLEAR))
               {
                  tmptnode->ConfigNode=nodenode;

                  if((area->Flags & AREA_DEFREADONLY) || CheckFlags(area->Group,nodenode->ReadOnlyGroups))
                     tmptnode->Flags|=TOSSNODE_READONLY;

                  jbAddNode(&area->TossNodes,(struct jbNode *)tmptnode);
                  added++;
               }
            }
         }
      }
   }

   if(added)
   {
      sprintf(buf,"%lu areas were added",added);
      saveconfig=TRUE;
   }
   else
      strcpy(buf,"No areas were added");

   rtEZRequestTags(buf,"Ok",NULL,NULL,
      RT_Underscore,'_',
      RT_Window,partwin,
      RT_WaitPointer,TRUE,
      RT_LockWindow, TRUE,
      RTEZ_Flags, EZREQF_CENTERTEXT,
      TAG_END);

   SetNode(currentnode);
}

void PartNode(void)
{
   LONG c,d,e;
   ULONG class,code,tmp,num;
   APTR iaddress;
   struct IntuiMessage *IntuiMessage;
   struct TempNode *tempnode;
   struct Packer *packer;
   struct Area *area;
   struct TossNode *tossnode;
   struct BannedNode *bannednode;
   UBYTE buf[50];
   BOOL res;
   struct Node4D n4d;
   UBYTE nodebuf[50];
   struct MenuItem *menuitem;
   UBYTE grp;
   
   NewList(&tmp_nodelist);
   NewList(&nodegrouplist);
   NewList(&nodeareaslist);
   NewList(&notnodeareaslist);
   NewList(&notnodeareasaccesslist);
   NewList(&nodepackerslist);
   NewList(&nodebannedlist);
   NewList(&notnodebannedlist);

   if(!(tempnode=AllocMem(sizeof(struct TempNode),MEMF_CLEAR)))
   {
      DisplayBeep(NULL);
      return;
   }

   strcpy(tempnode->buf,"<No packer>");
   tempnode->Node.ln_Name=tempnode->buf;
   AddTail(&nodepackerslist,(struct Node *)tempnode);

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

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

   if(!parthandle)
   {
      FreeTempNodes(&tmp_nodelist);
      FreeTempNodes(&nodegrouplist);
      FreeTempNodes(&nodeareaslist);
      FreeTempNodes(&notnodeareaslist);
      FreeTempNodes(&notnodeareasaccesslist);
      FreeTempNodes(&nodepackerslist);
      FreeTempNodes(&nodebannedlist);
      FreeTempNodes(&notnodebannedlist);
      return;
   }

   nodemenus=LT_LayoutMenus(parthandle,nodenewmenus,GTMN_FrontPen,0L,
                                                    GTMN_TextAttr,scr->Font,
                                                    GTMN_NewLookMenus,TRUE,
                                                    LH_MenuGlyphs,TRUE,
                                                    TAG_DONE);
   if(!parthandle)
   {
      LT_DeleteHandle(parthandle);
      FreeTempNodes(&tmp_nodelist);
      FreeTempNodes(&nodegrouplist);
      FreeTempNodes(&nodeareaslist);
      FreeTempNodes(&notnodeareaslist);
      FreeTempNodes(&notnodeareasaccesslist);
      FreeTempNodes(&nodepackerslist);
      FreeTempNodes(&nodebannedlist);
      FreeTempNodes(&notnodebannedlist);
      return;
   }

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

      LT_New(parthandle,
         LA_Type,      VERTICAL_KIND,
         TAG_DONE);

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

         LT_New(parthandle,
            LA_Type,       LISTVIEW_KIND,
            LA_Chars,      20,
            LALV_Lines,    13,
            LALV_LockSize, TRUE,
            LALV_CursorKey,TRUE,
            LALV_Link,     4712,
            GTLV_Labels,   &tmp_nodelist,
            LA_ID,4711,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,      HORIZONTAL_KIND,
            LAGR_SameSize,TRUE,
/*            LAGR_Spread, 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,10,
                  LA_ID,10,
                  TAG_DONE);

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

            LT_EndGroup(parthandle);

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

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

               LT_New(parthandle,
                  LA_Type,      BUTTON_KIND,
                  LA_LabelText, "Down",
                  LA_Chars,10,
                  GA_Disabled,TRUE,
                  LA_ID,13,
                  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,
         TAG_DONE);

         LT_New(parthandle,
            LA_LabelText,     "Page",
            LA_Chars,30,
            LA_Type,          CYCLE_KIND,
            LA_ID,            98,
            GTCY_Labels,      nodegroups,
            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_LabelText, "General",
               TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Sysop",
                  LA_Chars,         31,
                  LA_Type,          STRING_KIND,
                  LA_ID,            100,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Packet PW",
                  GTST_MaxChars,    8,
                  LA_Chars,         31,
                  LA_Type,          STRING_KIND,
                  LA_ID,            101,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Packer",
                  LA_Chars,         15,
                  LA_Type,          TEXT_KIND,
                  LA_ID,            102,
                  LATX_Picker,      TRUE,
                  GTTX_Border,      TRUE,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Passive",
                  LA_Type,          CHECKBOX_KIND,
                  LA_ID,            103,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "StoneAge",
                  LA_Type,          CHECKBOX_KIND,
                  LA_ID,            104,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Pack netmail",
                  LA_Type,          CHECKBOX_KIND,
                  LA_ID,            106,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Auto-add",
                  LA_Type,          CHECKBOX_KIND,
                  LA_ID,            107,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "SEEN-BY",
                  LA_Type,          CYCLE_KIND,
                  GTCY_Labels,      nodeseenby,
                  LA_ID,            105,
                  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_LabelText, "Groups",
               TAG_DONE);

               LT_New(parthandle,
                  LA_Type,       LISTVIEW_KIND,
                  LALV_LockSize, TRUE,
                  LA_Chars,      25,
                  LA_Lines,      12,
                  LA_ID,         5711,
                  LALV_LockSize, TRUE,
                  LALV_Link,     NIL_LINK,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_Type,          CYCLE_KIND,
                  LA_ID,            5713,
                  GTCY_Labels,      nodegroupflags,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_Type,          CHECKBOX_KIND,
                  LA_ID,            5714,
                  LA_LabelText,     "Get new areas",
                  LA_LabelPlace,    PLACE_RIGHT,
                  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_LabelText, "Areas",
               TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      VERTICAL_KIND,
                  TAG_DONE);

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

               LT_EndGroup(parthandle);

               LT_New(parthandle,
                  LA_Type,          CYCLE_KIND,
                  LA_ID,            601,
                  GTCY_Labels,      nodeareaflags,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_Type,          XBAR_KIND,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_Type,          CYCLE_KIND,
                  GTCY_Labels,      nodeaddmodes,
                  LA_ID,            612,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_Type,      HORIZONTAL_KIND,
                  TAG_DONE);

                  LT_New(parthandle,
                     LA_Type,    BUTTON_KIND,
                     LA_LabelText,"Add...",
                     LA_ID,      610,
                     LA_Chars,   15,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_Type,    BUTTON_KIND,
                     LA_LabelText,"Remove",
                     LA_ID,      611,
                     LA_Chars,   15,
                     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_LabelText, "AreaFix",
               TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Send Notify",
                  LA_Type,          CHECKBOX_KIND,
                  LA_ID,            200,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Allow forward requests",
                  LA_Type,          CHECKBOX_KIND,
                  LA_ID,            201,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "When area is removed",
                  GTCY_Labels,      nodewhenremoved,
                  LA_Type,          CYCLE_KIND,
                  LA_ID,            206,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "AreaFix password",
                  LA_Chars,         25,
                  GTST_MaxChars,    39,
                  LA_Type,          STRING_KIND,
                  LA_ID,            202,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Default group",
                  LA_Chars,         15,
                  LA_Type,          TEXT_KIND,
                  LA_ID,            203,
                  LATX_Picker,      TRUE,
                  GTTX_Border,      TRUE,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Remote AF name",
                  LA_Chars,         25,
                  GTST_MaxChars,    35,
                  LA_Type,          STRING_KIND,
                  LA_ID,            204,
                  TAG_DONE);

               LT_New(parthandle,
                  LA_LabelText,     "Remote AF password",
                  GTST_MaxChars,    71,
                  LA_Chars,         25,
                  LA_Type,          STRING_KIND,
                  LA_ID,            205,
                  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_LabelText, "Banned",
               TAG_DONE);

               LT_New(parthandle,
                  LA_Type,       LISTVIEW_KIND,
                  LALV_LockSize, TRUE,
                  LA_Lines,      11,
                  LA_Chars,      32,
                  LA_ID,         7711,
                  LALV_Link,     NIL_LINK,
                  TAG_DONE);

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

                  LT_New(parthandle,
                     LA_Type,    BUTTON_KIND,
                     LA_LabelText,"Add...",
                     LA_ID,      710,
                     LA_Chars,   15,
                     TAG_DONE);

                  LT_New(parthandle,
                     LA_Type,    BUTTON_KIND,
                     LA_LabelText,"Remove...",
                     LA_ID,      711,
                     LA_Chars,   15,
                     TAG_DONE);

                  LT_EndGroup(parthandle);

               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_Title,    "Nodes",
                               LAWN_HelpHook, &NodesHelpHook,
                               LAWN_Menu,     nodemenus,
                               WA_Flags,      WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_NEWLOOKMENUS,
                               TAG_END);

   RefreshNodelist();

   currentnode=-1;
   nodeactivepage=0;

   if(nodesnum)
   {
      SetNode(0);
      LT_SetAttributes(parthandle,4711,GTLV_Selected,0,TAG_END);
   }
   else
   {
      SetNode(-1);
   }
   
   if(!partwin)
   {
      ClearMenuStrip(parthandle->Window);
      LT_DeleteHandle(parthandle);
	   FreeMenus(nodemenus);
      FreeTempNodes(&tmp_nodelist);
      FreeTempNodes(&nodegrouplist);
      FreeTempNodes(&nodeareaslist);
      FreeTempNodes(&notnodeareaslist);
      FreeTempNodes(&notnodeareasaccesslist);
      FreeTempNodes(&nodepackerslist);
      FreeTempNodes(&nodebannedlist);
      FreeTempNodes(&notnodebannedlist);
      DisplayBeep(NULL);
      return;
   }

   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_MENUPICK:       num=code;
                                      while(num!=MENUNULL)
                                      {
                                         if(MENUNUM(num)==0)
                                         {
                                            switch(ITEMNUM(num))
                                            {
                                               case 0: DuplicateNode();
                                                       break;
                                               case 2: AddMandatory();
                                                       break;
                                            }
                                         }
                                         menuitem=ItemAddress(nodemenus,num);
                                         num=menuitem->NextSelect;
                                      }
                                      break;
            case IDCMP_IDCMPUPDATE:   switch(((struct Gadget *)iaddress)->GadgetID)
                                      {
                                         case 102:
                                            c=AskList(&nodepackerslist,"Select packer",partwin);

                                            if(c!=-1)
                                            {
                                               if(c == 0)
                                               {
                                                  nodenode->Packer=NULL;
                                               }
                                               else
                                               {
                                                  c--;
                                                  packer=PackerList.First;
                                                  for(e=0;e<c;e++) packer=packer->Next;
                                                  nodenode->Packer=packer;
                                               }
                                               SetNode(currentnode);
                                               saveconfig=TRUE;
                                            }
                                            break;
                                         case 203:
                                            grp=AskGroup(partwin,"<No group>");

                                            if(grp!=-1)
                                            {
                                               nodenode->DefaultGroup=grp;
                                               SetNode(currentnode);
                                               saveconfig=TRUE;
                                            }
                                            break;
                                         case 5711:
                                            if(CheckFlags('A'+code,nodenode->Groups))
                                            {
                                               if(CheckFlags('A'+code,nodenode->ReadOnlyGroups))
                                               {
                                                  for(d=0,e=0;d<strlen(nodenode->Groups);d++)
                                                     if(nodenode->Groups[d]!='A'+code) buf[e++]=nodenode->Groups[d];

                                                  buf[e]=0;
                                                  strcpy(nodenode->Groups,buf);

                                                  for(d=0,e=0;d<strlen(nodenode->ReadOnlyGroups);d++)
                                                     if(nodenode->ReadOnlyGroups[d]!='A'+code) buf[e++]=nodenode->ReadOnlyGroups[d];

                                                  buf[e]=0;
                                                  strcpy(nodenode->ReadOnlyGroups,buf);
                                                  LT_SetAttributes(parthandle,5713,GTCY_Active,0,TAG_DONE);
                                               }
                                               else
                                               {
                                                  buf[0]='A'+code;
                                                  buf[1]=0;
                                                  strcat(nodenode->ReadOnlyGroups,buf);
                                                  LT_SetAttributes(parthandle,5713,GTCY_Active,2,TAG_DONE);
                                               }
                                            }
                                            else
                                            {
                                               buf[0]='A'+code;
                                               buf[1]=0;
                                               strcat(nodenode->Groups,buf);
                                               LT_SetAttributes(parthandle,5713,GTCY_Active,1,TAG_DONE);
                                            }

                                            saveconfig=TRUE;
                                            RefreshNodeGrouplist();
                                            break;
                                         case 6711:
                                            tempnode=nodeareaslist.lh_Head;
                                            for(c=0;c<currentnodearea;c++) tempnode=tempnode->Node.ln_Succ;

                                            area=tempnode->UserData;

                                            for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
                                               if(tossnode->ConfigNode == nodenode) break;

                                            code=LT_GetAttributes(parthandle,601,TAG_END);
                                            code++;
                                            if(code == 4) code=0;

                                            tossnode->Flags=0;

                                            if(code == 1) tossnode->Flags|=TOSSNODE_READONLY;
                                            if(code == 2) tossnode->Flags|=TOSSNODE_WRITEONLY;
                                            if(code == 3) tossnode->Flags|=TOSSNODE_FEED;

                                            LT_SetAttributes(parthandle,6711,GTLV_Labels,~0,TAG_END);
                                            tempnode->buf[0]=0;
                                            if(tossnode->Flags & TOSSNODE_READONLY) strcpy(tempnode->buf,"!");
                                            if(tossnode->Flags & TOSSNODE_WRITEONLY) strcpy(tempnode->buf,"@");
                                            if(tossnode->Flags & TOSSNODE_FEED) strcpy(tempnode->buf,"%");
                                            strcat(tempnode->buf,area->Tagname);
                                            LT_SetAttributes(parthandle,6711,GTLV_Labels,&nodeareaslist,TAG_END);
                                            LT_SetAttributes(parthandle,601,GTCY_Active,code,TAG_END);
                                            saveconfig=TRUE;
                                            break;
                                      }
                                      break;
            case IDCMP_GADGETUP:      switch(((struct Gadget *)iaddress)->GadgetID)
                                      {
                                          case 10:
                                             AddNode();
                                             break;
                                          case 11:
                                             RemNode();
                                             break;
                                          case 12:
                                             if(currentnode != 0)
                                             {
                                                tmp=currentnode;
                                                MoveUp(&CNodeList,tmp);
                                                RefreshNodelist();
                                                SetNodeQuick(tmp-1);
                                                LT_SetAttributes(parthandle,4711,
                                                   GTLV_Selected,currentnode,
                                                   GTLV_MakeVisible,currentnode,
                                                   TAG_END);
                                                saveconfig=TRUE;
                                             }
                                             break;
                                          case 13:
                                             if(currentnode != nodesnum-1)
                                             {
                                                tmp=currentnode;
                                                MoveDown(&CNodeList,tmp);
                                                RefreshNodelist();
                                                SetNodeQuick(tmp+1);
                                                LT_SetAttributes(parthandle,4711,
                                                   GTLV_Selected,currentnode,
                                                   GTLV_MakeVisible,currentnode,
                                                   TAG_END);
                                                saveconfig=TRUE;
                                             }
                                             break;
                                         case 98:
                                            SetNode(currentnode);
                                            LT_SetAttributes(parthandle,99,LAGR_ActivePage,code,TAG_END);
                                            nodeactivepage=code;
                                            break;
                                         case 103:
                                            if(nodenode->Flags & NODE_PASSIVE) nodenode->Flags&=~(NODE_PASSIVE);
                                            else                               nodenode->Flags|=NODE_PASSIVE;
                                            saveconfig=TRUE;
                                            break;
                                         case 104:
                                            if(nodenode->Flags & NODE_STONEAGE) nodenode->Flags&=~(NODE_STONEAGE);
                                            else                                nodenode->Flags|=NODE_STONEAGE;
                                            saveconfig=TRUE;
                                            break;
                                         case 106:
                                            if(nodenode->Flags & NODE_PACKNETMAIL) nodenode->Flags&=~(NODE_PACKNETMAIL);
                                            else                                   nodenode->Flags|=NODE_PACKNETMAIL;
                                            saveconfig=TRUE;
                                            break;
                                         case 107:
                                            if(nodenode->Flags & NODE_AUTOADD) nodenode->Flags&=~(NODE_AUTOADD);
                                            else                               nodenode->Flags|=NODE_AUTOADD;
                                            saveconfig=TRUE;
                                            break;
                                        case 105:
                                            nodenode->Flags&=~(NODE_NOSEENBY|NODE_TINYSEENBY);
                                            if(code == 1) nodenode->Flags|=NODE_NOSEENBY;
                                            if(code == 2) nodenode->Flags|=NODE_TINYSEENBY;
                                            saveconfig=TRUE;
                                            break;
                                         case 200:
                                            if(nodenode->Flags & NODE_NOTIFY) nodenode->Flags&=~(NODE_NOTIFY);
                                            else                              nodenode->Flags|=NODE_NOTIFY;
                                            saveconfig=TRUE;
                                            break;
                                         case 201:
                                            if(nodenode->Flags & NODE_FORWARDREQ) nodenode->Flags&=~(NODE_FORWARDREQ);
                                            else                                  nodenode->Flags|=NODE_FORWARDREQ;
                                            saveconfig=TRUE;
                                            break;
                                          case 601:
                                            tempnode=nodeareaslist.lh_Head;
                                            for(c=0;c<currentnodearea;c++) tempnode=tempnode->Node.ln_Succ;

                                            area=tempnode->UserData;

                                            for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
                                               if(tossnode->ConfigNode == nodenode) break;

                                            tossnode->Flags=0;

                                            if(code == 1) tossnode->Flags|=TOSSNODE_READONLY;
                                            if(code == 2) tossnode->Flags|=TOSSNODE_WRITEONLY;
                                            if(code == 3) tossnode->Flags|=TOSSNODE_FEED;

                                            LT_SetAttributes(parthandle,6711,GTLV_Labels,~0,TAG_END);
                                            tempnode->buf[0]=0;
                                            if(tossnode->Flags & TOSSNODE_READONLY) strcpy(tempnode->buf,"!");
                                            if(tossnode->Flags & TOSSNODE_WRITEONLY) strcpy(tempnode->buf,"@");
                                            if(tossnode->Flags & TOSSNODE_FEED) strcpy(tempnode->buf,"%");
                                            strcat(tempnode->buf,area->Tagname);
                                            LT_SetAttributes(parthandle,6711,GTLV_Labels,&nodeareaslist,TAG_END);

                                            saveconfig=TRUE;
                                            break;

                                         case 610:
                                            {
                                               struct List *tmplist;

                                               RefreshNotNodeAreasAccessList();

                                               if(LT_GetAttributes(parthandle,612,TAG_END)==0) tmplist=&notnodeareaslist;
                                               else                                            tmplist=&notnodeareasaccesslist;

                                               res=AskList(tmplist,"Select area",partwin);

                                               if(res!=-1)
                                               {
                                                  tempnode=tmplist->lh_Head;
                                                  for(c=0;c<res;c++) tempnode=tempnode->Node.ln_Succ;

                                                  area=tempnode->UserData;

                                                  if(area->TossNodes.First && area->TossNodes.First->Next && Checksum9() != checksums[9])
                                                  {
                                                      rtEZRequestTags("An area can only be exported to two nodes\n"
                                                                      "in the unregistered version of CrashMail","_Ok",NULL,NULL,RT_Underscore,'_',
                                                                           RT_Window,partwin,
                                                                           RT_WaitPointer, TRUE,
                                                                           RT_LockWindow, TRUE,
                                                                           TAG_END);
                                                  }
                                                  else
                                                  {
                                                     if(tossnode=AllocMem(sizeof(struct TossNode),MEMF_CLEAR))
                                                     {
                                                        tossnode->ConfigNode=nodenode;
                                                        if(area->Flags & AREA_DEFREADONLY) tossnode->Flags|=TOSSNODE_READONLY;
                                                        jbAddNode(&area->TossNodes,(struct jbNode *)tossnode);

                                                        for(tempnode=notnodeareaslist.lh_Head;tempnode->Node.ln_Succ;tempnode=tempnode->Node.ln_Succ)
                                                           if(tempnode->UserData == area) break;

                                                        Remove((struct Node *)tempnode);

                                                        tempnode->buf[0]=0;
                                                        if(tossnode->Flags & TOSSNODE_READONLY) strcpy(tempnode->buf,"!");
                                                        if(tossnode->Flags & TOSSNODE_FEED) strcpy(tempnode->buf,"%");
                                                        strcat(tempnode->buf,area->Tagname);
                                                        tempnode->UserData=area;

                                                        LT_SetAttributes(parthandle,6711,GTLV_Labels,~0,TAG_END);
                                                        AddTail(&nodeareaslist,(struct Node *)tempnode);
                                                        LT_SetAttributes(parthandle,6711,GTLV_Labels,&nodeareaslist,TAG_END);
                                                        nodeareasnum++;

                                                        currentnodearea=nodeareasnum-1;
                                                        SetAreaNodes();
                                                        LT_SetAttributes(parthandle,6711,GTLV_Selected,currentnodearea,GTLV_MakeVisible,currentnodearea,TAG_DONE);
                                                        saveconfig=TRUE;
                                                     }
                                                     else
                                                     {
                                                        DisplayBeep(NULL);
                                                     }
                                                  }
                                               }
                                            }
                                            break;
                                         case 611:
                                            tempnode=nodeareaslist.lh_Head;
                                            for(c=0;c<currentnodearea;c++) tempnode=tempnode->Node.ln_Succ;

                                            area=tempnode->UserData;

                                            for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
                                               if(tossnode->ConfigNode == nodenode) break;

                                            jbFreeNode(&area->TossNodes,(struct jbNode *)tossnode,sizeof(struct TossNode));

                                            LT_SetAttributes(parthandle,6711,GTLV_Labels,~0,TAG_END);
                                            Remove((struct Node *)tempnode);
                                            LT_SetAttributes(parthandle,6711,GTLV_Labels,&nodeareaslist,TAG_END);

                                            tempnode->UserData=area;
                                            strcpy(tempnode->buf,area->Tagname);
                                            AddTail(&notnodeareaslist,(struct Node *)tempnode);

                                            if(currentnodearea==nodeareasnum-1) currentnodearea--;
                                            nodeareasnum--;
                                            SetAreaNodes();
                                            LT_SetAttributes(parthandle,6711,GTLV_Selected,currentnodearea,GTLV_MakeVisible,currentnodearea,TAG_DONE);
                                            saveconfig=TRUE;
                                            break;
                                         case 4711:
                                            SetNode(code);
                                            break;
                                         case 5711:
                                            if(CheckFlags('A'+code,nodenode->Groups))
                                            {
                                               if(CheckFlags('A'+code,nodenode->ReadOnlyGroups))
                                               {
                                                  LT_SetAttributes(parthandle,5713,GTCY_Active,2,TAG_DONE);
                                               }
                                               else
                                               {
                                                  LT_SetAttributes(parthandle,5713,GTCY_Active,1,TAG_DONE);
                                               }
                                            }
                                            else
                                            {
                                               LT_SetAttributes(parthandle,5713,GTCY_Active,0,TAG_DONE);
                                            }

                                            if(CheckFlags('A'+code,nodenode->AddGroups))
                                            {
                                               LT_SetAttributes(parthandle,5714,GTCB_Checked,TRUE,TAG_DONE);
                                            }
                                            else
                                            {
                                               LT_SetAttributes(parthandle,5714,GTCB_Checked,FALSE,TAG_DONE);
                                            }

                                            break;
                                         case 5713:
                                            num=LT_GetAttributes(parthandle,5711,TAG_END);

                                            for(d=0,e=0;d<strlen(nodenode->Groups);d++)
                                               if(nodenode->Groups[d]!='A'+num) buf[e++]=nodenode->Groups[d];

                                            buf[e]=0;
                                            strcpy(nodenode->Groups,buf);

                                            for(d=0,e=0;d<strlen(nodenode->ReadOnlyGroups);d++)
                                               if(nodenode->ReadOnlyGroups[d]!='A'+num) buf[e++]=nodenode->ReadOnlyGroups[d];

                                            buf[e]=0;
                                            strcpy(nodenode->ReadOnlyGroups,buf);

                                            if(code == 1)
                                            {
                                               buf[0]='A'+num;
                                               buf[1]=0;
                                               strcat(nodenode->Groups,buf);
                                            }
                                            if(code == 2)
                                            {
                                               buf[0]='A'+num;
                                               buf[1]=0;
                                               strcat(nodenode->Groups,buf);
                                               strcat(nodenode->ReadOnlyGroups,buf);
                                            }
                                            saveconfig=TRUE;
                                            RefreshNodeGrouplist();
                                            break;
                                         case 5714:
                                            num=LT_GetAttributes(parthandle,5711,TAG_END);

                                            if(CheckFlags('A'+num,nodenode->AddGroups))
                                            {
                                               for(d=0,e=0;d<strlen(nodenode->AddGroups);d++)
                                                  if(nodenode->AddGroups[d]!='A'+num) buf[e++]=nodenode->AddGroups[d];

                                               buf[e]=0;
                                               strcpy(nodenode->AddGroups,buf);
                                            }
                                            else
                                            {
                                               buf[0]='A'+num;
                                               buf[1]=0;
                                               strcat(nodenode->AddGroups,buf);
                                            }
                                            saveconfig=TRUE;
                                            RefreshNodeGrouplist();
                                            break;
                                         case 710:
                                            res=AskList(&notnodebannedlist,"Select area",partwin);

                                            if(res!=-1)
                                            {
                                               tempnode=notnodebannedlist.lh_Head;
                                               for(c=0;c<res;c++) tempnode=tempnode->Node.ln_Succ;

                                               area=tempnode->UserData;

                                               if(bannednode=AllocMem(sizeof(struct BannedNode),MEMF_CLEAR))
                                               {
                                                  bannednode->ConfigNode=nodenode;
                                                  jbAddNode(&area->BannedNodes,(struct jbNode *)bannednode);
                                                  Remove((struct Node *)tempnode);

                                                  tempnode->UserData=area;

                                                  LT_SetAttributes(parthandle,7711,GTLV_Labels,~0,TAG_END);
                                                  AddTail(&nodebannedlist,(struct Node *)tempnode);
                                                  LT_SetAttributes(parthandle,7711,GTLV_Labels,&nodebannedlist,TAG_END);
                                                  nodebannednum++;

                                                  currentnodebanned=nodebannednum-1;
                                                  SetBannedNodes();
                                                  LT_SetAttributes(parthandle,7711,GTLV_Selected,currentnodebanned,GTLV_MakeVisible,currentnodebanned,TAG_DONE);
                                                  saveconfig=TRUE;
                                               }
                                               else
                                               {
                                                  DisplayBeep(NULL);
                                               }
                                            }
                                            break;
                                         case 711:
                                            tempnode=nodebannedlist.lh_Head;
                                            for(c=0;c<currentnodebanned;c++) tempnode=tempnode->Node.ln_Succ;

                                            area=tempnode->UserData;

                                            for(bannednode=area->BannedNodes.First;bannednode;bannednode=bannednode->Next)
                                               if(bannednode->ConfigNode == nodenode) break;

                                            jbFreeNode(&area->BannedNodes,(struct jbNode *)bannednode,sizeof(struct BannedNode));

                                            LT_SetAttributes(parthandle,7711,GTLV_Labels,~0,TAG_END);
                                            Remove((struct Node *)tempnode);
                                            LT_SetAttributes(parthandle,7711,GTLV_Labels,&nodebannedlist,TAG_END);

                                            tempnode->UserData=area;
                                            strcpy(tempnode->buf,area->Tagname);
                                            AddTail(&notnodebannedlist,(struct Node *)tempnode);

                                            if(currentnodebanned==nodebannednum-1) currentnodebanned--;
                                            nodebannednum--;
                                            SetBannedNodes();
                                            LT_SetAttributes(parthandle,7711,GTLV_Selected,currentnodebanned,GTLV_MakeVisible,currentnodebanned,TAG_DONE);
                                            saveconfig=TRUE;
                                            break;
                                          case 7711:
                                            currentnodebanned=code;
                                            SetBannedNodes();
                                            break;
                                          case 4712:
                                            if(!Parse4D(getgadgetstring((struct Gadget *)iaddress),&n4d))
                                            {
                                               DisplayBeep(NULL);
                                               LT_Activate(parthandle,4712);
                                            }
                                            else
                                            {
                                               if(!CheckDupeNode(getgadgetstring((struct Gadget *)iaddress),currentnode))
                                               {
                                                  LT_Activate(parthandle,4712);
                                               }
                                               else
                                               {
                                                  Copy4D(&nodenode->Node,&n4d);
                                                  sprintf(nodebuf,"%lu:%lu/%lu.%lu",n4d.Zone,n4d.Net,n4d.Node,n4d.Point);

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

                                                  LT_SetAttributes(parthandle,4711,GTLV_Labels,~0,TAG_END);
                                                  strcpy(tempnode->buf,nodebuf);
                                                  LT_SetAttributes(parthandle,4711,GTLV_Labels,&tmp_nodelist,TAG_END);
                                                  saveconfig=TRUE;
                                               }
                                            }
                                            break;
                                         case 6711:
                                            currentnodearea=code;
                                            SetAreaNodes();
                                            break;
                                      }
                                      break;
            case IDCMP_CLOSEWINDOW:   SetNode(-1);
                                      ClearMenuStrip(parthandle->Window);
                                      LT_DeleteHandle(parthandle);
                                 	  FreeMenus(nodemenus);
                                      FreeTempNodes(&tmp_nodelist);
                                      FreeTempNodes(&nodegrouplist);
                                      FreeTempNodes(&nodeareaslist);
                                      FreeTempNodes(&notnodeareaslist);
                                      FreeTempNodes(&notnodeareasaccesslist);
                                      FreeTempNodes(&nodepackerslist);
                                      FreeTempNodes(&nodebannedlist);
                                      FreeTempNodes(&notnodebannedlist);
                                      parthandle=NULL;
                                      return;
         }
      }
      WaitPort(partwin->UserPort);
   }
}



