#include "zmiglobals.h"

#include <link/io.h>

/* calls calloc */

/// EXPtoLink
int EXPtoLink(void)
{
   int i;
   char buffer[100];
   char *p;

   ASPrintf(NULL,logstring,". Linking replies for %d areas",totREMEMBEREXP);
   Log(logstring);

   for(i=0;i<totREMEMBEREXP;i++)
   {
      AFPrintf(NULL,sout,"[1KLinking %s...\n",REMEMBERAREA[i]);

      if(FetchPassthru(REMEMBERAREA[i]))
      {
         AFPrintf(NULL,sout,"Not linking... PASSTHRU Area\n");
         continue;
      }
      if(!FetchLink(REMEMBERAREA[i]))
      {
         AFPrintf(NULL,sout,"Not linking... LINK not set for area\n");
         continue;
      }

      p=(char *) FetchArea(REMEMBERAREA[i]);
      strcpy(buffer,p);

      if(buffer[strlen(buffer)-1]!='/' && buffer[strlen(buffer)-1]!=':') strcat(buffer,"/");

      if(_VERBOSITY)
      {
         ASPrintf(NULL,logstring,". Linking %s",REMEMBERAREA[i]);
         Log(logstring);
      }

      /* close the area here */

      LinkReplies(buffer,REMEMBERAREALOW[i]);

      /* open the area here */

   }

   Log("<- Done linking replies");
   return(0);
}
//-

/// LinkReplies
int LinkReplies(char *path, int lownum)
{
   int areanum;
   char numbuf[10];

   int disp;
   char display[]="|/-\\";

   struct Msg_Header *mh;
   struct Msg_Header *smh;

   int i,j,fromnum;

   int lo,hi,offset,total;

   char *headers;
   char *thead;

   BPTR HeaderFile;

   FILE *pointerfile;

   int headersize;

   char buf[256];
   char hunt[256];
   char tmp[256];

   strsfn(path,NULL,numbuf,NULL,NULL);

   areanum=atoi(numbuf);

   ASPrintf(NULL,buf,"%sPOINTERS.MSG",path);

   pointerfile=fopen(buf,"r");

   if(!pointerfile) return(20);

   fgets(buf,10,pointerfile);
   lo=atoi(buf);
   fgets(buf,10,pointerfile);
   hi=atoi(buf);
   fclose(pointerfile);

   if(lo<2) lo=2;

   total=hi-lo+1;
   offset=lo;

   fromnum=lownum-offset;

   if(fromnum<0) fromnum=1;
   if(fromnum>total) fromnum=1;

   headersize=sizeof(struct Msg_Header);

   AFPrintf(NULL,sout,"Total: %d (%d-%d)  ",total,lo,hi);

   headers=(char *)calloc((total+1)*headersize,1);

   if(!headers)
   {
      AFPrintf(NULL,sout,"LinkReplies can't allocate memory (1)\n");
      return(20);
   }

   thead=(char *)calloc(2*headersize,1);

   if(!thead)
   {
      AFPrintf(NULL,sout,"LinkReplies can't allocate memory (2)\n");
      free(headers);
      return(20);
   }

   AFPrintf(NULL,sout,"Pass 1: ");
   Flush(sout);

   disp=0;

   MyBorrowArea(areanum);

   for(i=0;i<total;i++)
   {
      if((i%8)==0)
      {
         UnBorrowArea(areanum);
         if(_BORROW) Delay(3);
         MyBorrowArea(areanum);
      }

      if(_LOG)
      {
         AFPrintf(NULL,sout," [%c][4D",display[disp]);
         disp++;
         if(disp>3) disp=0;
         Flush(sout);
      }

      mh=(void *)(headers+(i*headersize));

      ASPrintf(NULL,buf,"%s%d.MSG",path,i+offset);

      HeaderFile=Open(buf,MODE_OLDFILE);

      if(!HeaderFile)
      {
         if(MyDEBUG) AFPrintf(NULL,sout,"Couldn't open %s, skipping...\n",buf);
         continue;
      }

      j=Read(HeaderFile,(void *)mh,headersize);
      Close(HeaderFile);
   }
   UnBorrowArea(areanum);

   AFPrintf(NULL,sout,"Pass 2: ");
   Flush(sout);

   /* link them in memory here */

   disp=0;
   for(i=total-1;i>(fromnum-1);i--)
   {
      if(_LOG)
      {
         AFPrintf(NULL,sout," [%c][4D",display[i%3]);
         disp++;
         if(disp>3)disp=0;
         Flush(sout);
      }

      mh=(void *)(headers+(i*headersize));

      if(strlen(mh->To)==0) continue; /* funky message */

      if(mh->ReplyTo!=0) continue;  /* already backward linked */

      /* forward link must be empty... start here */

      /* clean up the old subject line so we can search for it */

      strcpy(tmp,mh->Title);

      j=0;

      while(1) /* get rid of re: 's */
      {
         if(!Strnicmp(tmp+j,"re:",3))
         {
            j+=3;

            while(1) /* get rid of spaces after re: */
            {
               if(!Strnicmp(tmp+j," ",1))
                  j++;
               else
                  break;
            }
         }
         else
            break;
      }
      strcpy(hunt,tmp+j);
      Upper(hunt);

      /* hunt[25]=NULL;*/  /* search only on 25 significant characters or less */

      for(j=(i-1);j>-1;j--)
      {
         if(j<0) break;
         smh=(void *)(headers+(j*headersize));

         if(strlen(smh->To)==0) continue;
         if(strlen(smh->Title)<strlen(hunt)) continue;   /* can't be ours */
         
         strcpy(tmp,smh->Title);
         Upper(tmp);

         if(!strcmp(hunt,tmp+strlen(tmp)-strlen(hunt)))
         {
            /* found a match! */
            smh->NextReply=i+offset;
            smh->TimesRead=987;  /*flag to rewrite*/
            mh->ReplyTo=j+offset;
            mh->TimesRead=987;   /*flag to rewrite*/
            break;
         }
      }
   }

   AFPrintf(NULL,sout,"Pass 3: ");
   Flush(sout);

   disp=0;

   for(i=0;i<total;i++)
   {
      if(_LOG)
      {
         AFPrintf(NULL,sout," [%c][4D",display[disp]);
         disp++;
         if(disp>3)disp=0;
         Flush(sout);
      }

      mh=(void *)(headers+(i*headersize));
      smh=(void *)thead;

      if(MyDEBUG)
      {
         strcpy(buf,"");
         if(mh->ReplyTo==0 && mh->NextReply==0) strcpy(buf,"[1mO R P H A N[0m");
         if(mh->TimesRead==987) strcpy(buf,"[1m* LINKED ZLINK *[0m");

         AFPrintf(NULL,sout,"%4d.msg   FM: %s\n",mh->ReplyTo,    mh->From);
         AFPrintf(NULL,sout,"[1m%4d.msg[0m   TO: %-40s%s\n",i+offset,       mh->To,buf);
         AFPrintf(NULL,sout,"%4d.msg   SB: %s\n",mh->NextReply,mh->Title);
         AFPrintf(NULL,sout,"           DT: %s\n\n",mh->Date);
      }

      if(mh->TimesRead==987)
      {
         MyBorrowArea(areanum);
         ASPrintf(NULL,buf,"%s%d.MSG",path,i+offset);

         HeaderFile=Open(buf,MODE_READWRITE);

         if(!HeaderFile)
         {
            if(MyDEBUG) AFPrintf(NULL,sout,"Couldn't open %s, skipping...\n",buf);
            continue;
         }

         j=Read(HeaderFile,(void *)smh,headersize);

         if(!Stricmp(mh->Title,smh->Title) && !Stricmp(mh->Date,smh->Date))
         {
            smh->ReplyTo=mh->ReplyTo;
            smh->NextReply=mh->NextReply;
            Seek(HeaderFile,0,OFFSET_BEGINNING);
            j=Write(HeaderFile,(void *)smh,headersize);

            if(MyDEBUG) AFPrintf(NULL,sout,"Wrote links for msg %d\n",i+offset);
         }        

         Close(HeaderFile);
         UnBorrowArea(areanum);
      }  
   }
   free(headers);
   free(thead);
   AFPrintf(NULL,sout,"\n[A");

   return(0);

}
//-

