#include <CrashPrefs.h>

UBYTE bbsbuf[4000];

extern ULONG jbcpos;
jbstrcpy(UBYTE *dest,UBYTE *src,ULONG maxlen);

ULONG matchnum(UBYTE *s1,UBYTE *s2)
{
   ULONG c,res;

   res=0;
   c=0;

   while(s1[c] && s2[c] && s1[c]==s2[c])
   {
      res++;
      c++;
   }

   return(res);
}

struct Aka *BestAka(struct Node4D *n4d)
{
   UBYTE nodebuf[50];
   UBYTE akabuf[50];
   LONG bestnum;
   struct Aka *aka,*bestmatch;

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

   bestnum=0;
   bestmatch=AkaList.First;

   for(aka=AkaList.First;aka;aka=aka->Next)
   {
      sprintf(akabuf,"%lu:%lu/%lu.%lu",
         aka->Node.Zone,
         aka->Node.Net,
         aka->Node.Node,
         aka->Node.Point);

      if(matchnum(nodebuf,akabuf) > bestnum)
      {
         bestnum=matchnum(nodebuf,akabuf);
         bestmatch=aka;
      }
   }

   if(!bestmatch)
      bestmatch=AkaList.First;

   return(bestmatch);
}

void ImportAreasBBS(void)
{
   UBYTE filebuf[300];
   UBYTE buf[200];
   UBYTE tagname[200];
   UBYTE path[200];
   struct Area *area,*defarea;
   struct ConfigNode *cnode,*tmpcnode;
   struct TossNode *tossnode;
   struct Node4D n4d,old4d;
   BPTR fh;

   for(defarea=AreaList.First;defarea;defarea=defarea->Next)
      if(stricmp(defarea->Tagname,"DEFAULT")==0) break;

   filebuf[0]=0;

   if(!OpenReq(filebuf,300,"Import Areas.bbs...",mainwin,FALSE))
      return;

   if(!(fh=Open(filebuf,MODE_OLDFILE)))
   {
      sprintf(buf,"Unable to open \"%s\"",filebuf);

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

      return;
   }

   while(FGets(fh,bbsbuf,4000))
   {
      jbcpos=0;

      if(!strstr(bbsbuf," ! ") && bbsbuf[0]!='-' && bbsbuf[0]!=10 && bbsbuf[0]!=';' && bbsbuf[0]!=0)
      {
         if(jbstrcpy(path,bbsbuf,200))
         {
            if(jbstrcpy(tagname,bbsbuf,200))
            {
               for(area=AreaList.First;area;area=area->Next)
                  if(stricmp(area->Tagname,tagname)==0) break;

               if(!area)
               {
                  if(!(area=AllocMem(sizeof(struct Area),MEMF_CLEAR)))
                  {
                     DisplayBeep(NULL);
                     Close(fh);
                     return;
                  }

                  jbAddNode(&AreaList,(struct jbNode *)area);
                  strcpy(area->Tagname,tagname);

                  if(stricmp(path,"T:")==0)
                  {
                     area->Path[0]=0;
                     area->AreaType=0;
                  }
                  else if(strncmp(path,"UMS:",4)==0)
                  {
                     strcpy(area->Path,&path[4]);
                     area->AreaType=AREATYPE_UMS;
                  }
                  else
                  {
                     strcpy(area->Path,path);
                     area->AreaType=AREATYPE_MSG;
                  }

                  jbNewList(&area->TossNodes);

                  if(defarea)
                  {
                     strcpy(area->Description,defarea->Description);

                     area->DefaultCHRS=defarea->DefaultCHRS;
                     area->ExportCHRS=defarea->ExportCHRS;

                     if(defarea->Flags & AREA_MANDATORY)
                        area->Flags |= AREA_MANDATORY;

                     if(defarea->Flags & AREA_DEFREADONLY)
                        area->Flags |= AREA_DEFREADONLY;
                  }
               }

               old4d.Zone=0;
               old4d.Net=0;
               old4d.Node=0;

               while(jbstrcpy(buf,bbsbuf,200))
               {
                  if(Parse4D(buf,&n4d))
                  {
                     if(n4d.Zone == 0)
                        n4d.Zone=old4d.Zone;

                     if(n4d.Net == 0)
                     {
                        if(n4d.Node == 0)
                           n4d.Node=old4d.Node;

                        n4d.Net=old4d.Net;
                     }

                     Copy4D(&old4d,&n4d);

                     if(n4d.Net == 0) n4d.Net=old4d.Net;

                     if(n4d.Zone == 0)
                        for(tmpcnode=CNodeList.First;tmpcnode;tmpcnode=tmpcnode->Next)
                        {
                           if(Compare4D(&n4d,&tmpcnode->Node)==0)
                           {
                              n4d.Zone=tmpcnode->Node.Zone;
                              break;
                           }
                        }

                     if(n4d.Zone == 0) n4d.Zone=cfg_DefaultZone;

                     Copy4D(&old4d,&n4d);

                     if(!area->Aka)
                        area->Aka=BestAka(&n4d);

                     for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
                        if(Compare4D(&tossnode->ConfigNode->Node,&n4d)==0) break;

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

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

                           jbNewList(&cnode->RemoteAFList);
                           jbAddNode(&CNodeList,(struct jbNode *)cnode);

                           Copy4D(&cnode->Node,&n4d);

                           sprintf(buf,"The node %lu:%lu/%lu.%lu was added to your configuration",
                                 n4d.Zone,
                                 n4d.Net,
                                 n4d.Node,
                                 n4d.Point);

                           rtEZRequestTags(buf,"_Ok",NULL,NULL,
                              RT_Underscore,'_',
                              RT_Window,mainwin,
                              RT_WaitPointer,TRUE,
                              RT_LockWindow, TRUE,
                              RTEZ_Flags, EZREQF_CENTERTEXT,
                              TAG_END);
                        }

                        if(!(tossnode=AllocMem(sizeof(struct TossNode),MEMF_CLEAR)))
                        {
                              DisplayBeep(NULL);
                              Close(fh);
                              return;
                        }

                        if(area->Flags & AREA_DEFREADONLY) tossnode->Flags|=TOSSNODE_READONLY;
                        tossnode->ConfigNode=cnode;
                        jbAddNode(&area->TossNodes,(struct jbNode *)tossnode);
                     }
                  }
                  else
                  {
                     sprintf(bbsbuf,"Invalid node \"%s\"",buf);

                     rtEZRequestTags(bbsbuf,"_Ok",NULL,NULL,
                        RT_Underscore,'_',
                        RT_Window,mainwin,
                        RT_WaitPointer,TRUE,
                        RT_LockWindow, TRUE,
                        RTEZ_Flags, EZREQF_CENTERTEXT,
                        TAG_END);
                  }
               }

               if(!area->Aka)
                  area->Aka=AkaList.First;
            }
         }
      }
   }

   Close(fh);
   saveconfig=TRUE;
}

void ImportTrapToss(void)
{
   UBYTE filebuf[300];
   UBYTE bbsword[200];
   UBYTE buf[200];
   UBYTE tagname[200];
   UBYTE path[200];
   UBYTE akabuf[200];
   struct Aka *aka;
   struct Area *area,*defarea;
   struct ConfigNode *cnode,*tmpcnode;
   struct TossNode *tossnode;
   struct Node4D n4d,old4d;
   BPTR fh;

   for(defarea=AreaList.First;defarea;defarea=defarea->Next)
      if(stricmp(defarea->Tagname,"DEFAULT")==0) break;

   filebuf[0]=0;

   if(!OpenReq(filebuf,300,"Import TrapToss configuration...",mainwin,FALSE))
      return;

   if(!(fh=Open(filebuf,MODE_OLDFILE)))
   {
      sprintf(buf,"Unable to open \"%s\"",filebuf);

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

      return;
   }

   while(FGets(fh,bbsbuf,4000))
   {
      jbcpos=0;

      jbstrcpy(bbsword,bbsbuf,20);

      if(stricmp(bbsword,"NODE")==0 || stricmp(bbsword,"AKA")==0)
      {
         if(jbstrcpy(akabuf,bbsbuf,200))
         {
            if(Parse4D(akabuf,&n4d))
            {
               for(aka=AkaList.First;aka;aka=aka->Next)
                  if(Compare4D(&aka->Node,&n4d)==0) break;

               if(!aka)
               {
                  if(!(aka=AllocMem(sizeof(struct Aka),MEMF_CLEAR)))
                  {
                     DisplayBeep(NULL);
                     Close(fh);
                     return;
                  }

                  if(n4d.Zone >=1 || n4d.Zone <=6)
                     strcpy(aka->Domain,"FidoNet");

                  else
                     strcpy(aka->Domain,"UnknownNet");

                  Copy4D(&aka->Node,&n4d);
                  jbAddNode(&AkaList,(struct jbNode *)aka);

                  sprintf(bbsbuf,"The aka %lu:%lu/%lu.%lu was added to your configuration",
                        n4d.Zone,
                        n4d.Net,
                        n4d.Node,
                        n4d.Point);

                  rtEZRequestTags(bbsbuf,"_Ok",NULL,NULL,
                     RT_Underscore,'_',
                     RT_Window,mainwin,
                     RT_WaitPointer,TRUE,
                     RT_LockWindow, TRUE,
                     RTEZ_Flags, EZREQF_CENTERTEXT,
                     TAG_END);
                }
            }
            else
            {
               sprintf(bbsbuf,"Invalid aka \"%s\"",akabuf);

               rtEZRequestTags(bbsbuf,"_Ok",NULL,NULL,
                  RT_Underscore,'_',
                  RT_Window,mainwin,
                  RT_WaitPointer,TRUE,
                  RT_LockWindow, TRUE,
                  RTEZ_Flags, EZREQF_CENTERTEXT,
                  TAG_END);
            }
         }
      }
      if(stricmp(bbsword,"AREA")==0)
      {
         if(jbstrcpy(tagname,bbsbuf,200))
         {
            if(jbstrcpy(path,bbsbuf,200))
            {
               for(area=AreaList.First;area;area=area->Next)
                  if(stricmp(area->Tagname,tagname)==0) break;

               if(!area)
               {
                  if(!(area=AllocMem(sizeof(struct Area),MEMF_CLEAR)))
                  {
                     DisplayBeep(NULL);
                     Close(fh);
                     return;
                  }

                  jbAddNode(&AreaList,(struct jbNode *)area);
                  strcpy(area->Tagname,tagname);
                  area->AreaType=0;
                  jbNewList(&area->TossNodes);

                  if(defarea)
                  {
                     strcpy(area->Description,defarea->Description);

                     area->DefaultCHRS=defarea->DefaultCHRS;
                     area->ExportCHRS=defarea->ExportCHRS;

                     if(defarea->Flags & AREA_MANDATORY)
                        area->Flags |= AREA_MANDATORY;

                     if(defarea->Flags & AREA_DEFREADONLY)
                        area->Flags |= AREA_DEFREADONLY;
                  }
               }

               old4d.Zone=0;
               old4d.Net=0;
               old4d.Node=0;

               while(jbstrcpy(buf,bbsbuf,200))
               {
                  if(Parse4D(buf,&n4d))
                  {
                     if(n4d.Zone == 0)
                        n4d.Zone=old4d.Zone;

                     if(n4d.Net == 0)
                     {
                        if(n4d.Node == 0)
                           n4d.Node=old4d.Node;

                        n4d.Net=old4d.Net;
                     }

                     Copy4D(&old4d,&n4d);

                     if(n4d.Net == 0) n4d.Net=old4d.Net;

                     if(n4d.Zone == 0)
                        for(tmpcnode=CNodeList.First;tmpcnode;tmpcnode=tmpcnode->Next)
                        {
                           if(Compare4D(&n4d,&tmpcnode->Node)==0)
                           {
                              n4d.Zone=tmpcnode->Node.Zone;
                              break;
                           }
                        }

                     if(n4d.Zone == 0) n4d.Zone=cfg_DefaultZone;


                     Copy4D(&old4d,&n4d);

                     for(aka=AkaList.First;aka;aka=aka->Next)
                        if(Compare4D(&aka->Node,&n4d)==0) break;

                     if(aka)
                     {
                        area->Aka=aka;
                        area->AreaType=AREATYPE_MSG;
                        strcpy(area->Path,path);
                     }
                     else
                     {
                        if(!area->Aka)
                           area->Aka=BestAka(&n4d);

                        for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
                           if(Compare4D(&tossnode->ConfigNode->Node,&n4d)==0) break;

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

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

                              jbNewList(&cnode->RemoteAFList);
                              jbAddNode(&CNodeList,(struct jbNode *)cnode);

                              Copy4D(&cnode->Node,&n4d);

                              sprintf(buf,"The node %lu:%lu/%lu.%lu was added to your configuration",
                                    n4d.Zone,
                                    n4d.Net,
                                    n4d.Node,
                                    n4d.Point);

                              rtEZRequestTags(buf,"_Ok",NULL,NULL,
                                 RT_Underscore,'_',
                                 RT_Window,mainwin,
                                 RT_WaitPointer,TRUE,
                                 RT_LockWindow, TRUE,
                                 RTEZ_Flags, EZREQF_CENTERTEXT,
                                 TAG_END);
                           }

                           if(!(tossnode=AllocMem(sizeof(struct TossNode),MEMF_CLEAR)))
                           {
                                 DisplayBeep(NULL);
                                 Close(fh);
                                 return;
                           }

                           if(area->Flags & AREA_DEFREADONLY) tossnode->Flags|=TOSSNODE_READONLY;
                           tossnode->ConfigNode=cnode;
                           jbAddNode(&area->TossNodes,(struct jbNode *)tossnode);
                        }
                     }
                  }
                  else
                  {
                     sprintf(bbsbuf,"Invalid node \"%s\"",buf);

                     rtEZRequestTags(bbsbuf,"_Ok",NULL,NULL,
                        RT_Underscore,'_',
                        RT_Window,mainwin,
                        RT_WaitPointer,TRUE,
                        RT_LockWindow, TRUE,
                        RTEZ_Flags, EZREQF_CENTERTEXT,
                        TAG_END);
                  }
               }

               if(!area->Aka)
                  area->Aka=AkaList.First;
            }
         }
      }
   }

   Close(fh);
   saveconfig=TRUE;
}

extern UBYTE *config_version;

void WriteAreasBBS(void)
{
   UBYTE filebuf[300];
   UBYTE buf[200];
   struct Area *area;
   struct TossNode *tossnode;
   BPTR fh;
   struct DateTime dt;
   UBYTE time[40],date[40];

   filebuf[0]=0;

   if(!OpenReq(filebuf,300,"Export Areas.bbs...",mainwin,TRUE))
      return;

   if(!(fh=Open(filebuf,MODE_NEWFILE)))
   {
      sprintf(buf,"Unable to open \"%s\" for writing",filebuf);

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

      return;
   }

   DateStamp(&dt.dat_Stamp);
   dt.dat_Format=FORMAT_DOS;
   dt.dat_Flags=0;
   dt.dat_StrDay=NULL;
   dt.dat_StrDate=date;
   dt.dat_StrTime=time;
   DateToStr(&dt);

   FPrintf(fh,"; Generated by %s\n; %s %s\n\n",config_version,date,time);

   FPrintf(fh,"%s ! %s\n\n",cfg_DefaultOrigin,cfg_Sysop);

   for(area=AreaList.First;area;area=area->Next)
   {
      if(stricmp(area->Tagname,"DEFAULT")!=0)
      {
         if(area->AreaType == AREATYPE_UMS)      FPrintf(fh,"UMS:%-36s",area->Path);
         else if(area->AreaType == AREATYPE_MSG) FPrintf(fh,"%-40s",area->Path);
         else FPrintf(fh,"%-40s","T:");

         FPrintf(fh," %-40s",area->Tagname);

         if(!(area->Flags & AREA_NETMAIL))
            for(tossnode=area->TossNodes.First;tossnode;tossnode=tossnode->Next)
               FPrintf(fh," %lu:%lu/%lu.%lu",
                  tossnode->ConfigNode->Node.Zone,
                  tossnode->ConfigNode->Node.Net,
                  tossnode->ConfigNode->Node.Node,
                  tossnode->ConfigNode->Node.Point);

         FPrintf(fh,"\n");
      }
   }

   Close(fh);
}

