#include <stdlib.h>
#include <string.h>

#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>

#include <rexx/rxslib.h>
#include <rexx/storage.h>

#include <libraries/dos.h>
#include <libraries/dosextens.h>

#include <dlg/dlg.h>
#include <dlg/msg.h>
#include <dlg/log.h>
#include <dlg/file.h>
#include <dlg/resman.h>
#include <dlg/bulletin.h>
#include <dlg/misc.h>

#include <link/io.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/dlg.h>

#include <pragmas/dlg.h>

void __regargs XferTranslate(char *source, char *dest, char *filename, char *batchfile);


BOOL  __saveds __asm LIBCD(register __a0 char *dirname);
BOOL  __saveds __asm LIBExists(register __a0 char *);
LONG  __saveds __asm LIBFileSize(register __a0 char  *, register __a1 ULONG *);
LONG  __saveds __asm LIBGetFirstStruct(register __a0 char *, register __a1 char *, register __d0 ULONG);

LONG  __saveds __asm LIBCheckUser(register __a0 char *);
void  __saveds __asm LIBUnderScore(register __a0 char *);

BOOL  __saveds __asm LIBReadArea(register __d0 long, register __a0 struct Msg_Area *, register __d1 UBYTE);
LONG  __saveds __asm LIBBorrowArea(register __d0 long, register __a0 char  *, register __a1 char  *, register __d1 char, register __d2 UBYTE);
LONG  __saveds __asm LIBFreeArea(register __d0 long, register __a0 char  *, register __d1 UBYTE);

LONG  __saveds __asm LIBTranslateBuffer(register __a0 char *, register __a1 char *, register __d0 ULONG, register __a2 struct USER_DATA *, register __a3 struct Ram_File *, register __d1 char *);
LONG  __saveds __asm LIBOverlayProgram(register __a0 char *);
void  __saveds __asm LIBClearLine(void);


extern struct DosLibrary *DOSBase;

/// GetHiLowFPointers
void __saveds __asm LIBGetHiLowFPointers(register __d0 USHORT area,
                                         register __a0 char  *username,
                                         register __a1 LONG  *low,
                                         register __a2 LONG  *high,
                                         register __a3 char  *pswd)
{BPTR fh;
 char filename[80];

 if (area != PVTAREA)
    {ASPrintf(NULL,filename,"FILE:%d/Pointers.file",area);
     LIBBorrowArea(area,pswd,"Reading File Pointers",64,FILELOCK|WRITELOCK);
    }
   else
    {ASPrintf(NULL,filename,"USER:%s/Pointers.file",username);
     LIBUnderScore(filename);
    }

 if (!(fh = Open(filename, MODE_OLDFILE)))
    {*high = 0;
     *low  = 1;
    }
  else
    {if (!FGets(fh, filename, 20))
        *low = 1;
       else
         StrToLong(filename, low);

     if (!FGets(fh, filename, 20))
        *high = 1;
       else
         StrToLong(filename, high);

     Close(fh);
    }

 if (area != PVTAREA)
     LIBFreeArea(area,pswd,FILELOCK|WRITELOCK);
}
//-

/// PutHiLowFPointers
BOOL __saveds __asm LIBPutHiLowFPointers(register __d0 USHORT area,
                                         register __a0 char  *username,
                                         register __d1 LONG   low,
                                         register __d2 LONG   high,
                                         register __a1 char  *pswd)
{BPTR fh;
 char filename[80];

 if (area != PVTAREA)
    {ASPrintf(NULL,filename,"FILE:%d/Pointers.file", area);
     LIBBorrowArea(area,pswd,"Writing File Pointers",64,FILELOCK|WRITELOCK);
    }
   else    
    {ASPrintf(NULL,filename,"USER:%s/Pointers.file",username);
     LIBUnderScore(filename);
    }

 if (!(fh = Open(filename, MODE_OLDFILE)))
       fh = Open(filename, MODE_NEWFILE);

 if (fh)
    {AFPrintf(NULL, fh, "%ld\n%ld\n", low, high);
     Close(fh);
    }

 if (area != PVTAREA)
     LIBFreeArea(area,pswd,FILELOCK|WRITELOCK);

 if (!fh)  return(FALSE);
 return(TRUE);
}
//-

/// GetPath
LONG __saveds __asm LIBGetPath(register __a0 char            *path,
                               register __d0 USHORT           area,
                               register __a1 struct Msg_Area *carea,
                               register __a2 char            *file)

{  
   long                   altfound = 0;
   char                   otherpath[256];


   // Private or Invalid area, don't bother
 
   if (area == PVTAREA)  return(altfound);
   if (area <  0)        return(-1);

/// Insure Valid AreaInfo
 
   Forbid();
   
   if(carea == NULL) carea = calloc(1,sizeof(struct Msg_Area));

   // load the correct area data

   if (area != carea->Number)
   {
      carea = calloc(1,sizeof(struct Msg_Area));

      if (!LIBReadArea(area, carea, 1))
      {
         Permit();
         return(-1);
      }
   }
//-

/// Get Default Path
   if (strlen(carea->path) == 0)
   {
      ASPrintf(NULL, path, "FILE:%ld/", area);
      altfound = 0;
   }
   else
   {
      strcpy(path, carea->path);
      altfound = 1;
   }
 
   Permit();
//-

/// if a filename was passed -- find it
   if (file)
   {
      unsigned long  size  =  0;
      
      if(altfound == 1)
      {
         ASPrintf(NULL,otherpath,"%s%s",carea->path,file);
         
         if(LIBExists(otherpath))
         {
            path = strdup(carea->path);
            return(1);
         }
      }
      
      if(altfound == 0);
      {
         ASPrintf(NULL,otherpath,"FILE:%ld/%s",area,file);
         
         if(LIBExists(otherpath))
         {
            ASPrintf(NULL,path,"FILE:%ld/",area);
            return(0);
         }
      }

      altfound = 0;
      
      // find file in filepaths.bbs
      
      LIBFileSize("DLGConfig:Misc/FilePaths.BBS",&size);
      
      if(size >= sizeof(struct path))
      {
         struct path *Path = NULL;
         
         Path = AllocMem(size,MEMF_PUBLIC);
         
         if(Path)
         {
            BPTR fh  =  NULL;

            fh = Open("DLGConfig:Misc/FilePaths.BBS",MODE_OLDFILE);
            
            if(fh)
            {
               unsigned long  i  =  0;
               
               Read(fh,Path,size);
               Close(fh);
               
               for(i = 0; i < (size/sizeof(struct path)); i++)
               {
                  ASPrintf(NULL,otherpath,"%s%s",Path[i].path,file);
                  
                  if(LIBExists(otherpath))
                  {
                     strcpy(path,Path[i].path);
                     FreeMem(Path,size);
                     return(1);
                  }
               }
               
               FreeMem(Path,size);
               altfound = -1;
               
            }
            else
            {
               return(-1);
            }
         }
         else
         {
            return(-1);
         }
      }
      else
      {
         return(-1);
      }
   }
//-

   return(altfound);
}
//-

/// ReceiveFile
BOOL __saveds __asm LIBReceiveFile(register __a0 char               *path,
                                   register __a1 struct Protocol    *protocol,
                                   register __a2 struct File_Header *header,
                                   register __a3 struct USER_DATA   *user,
                                   register __d0 struct Ram_File    *ram,
                                   register __d1 char               *ext)

{char callstring[512];
 char tempstring[256];

 if (!LIBCD(path))  return(FALSE);

 LIBTranslateBuffer(protocol->recstring, tempstring, 128, user, ram, ext);
 XferTranslate     (tempstring,          callstring, header->Filename, "NOT_AVAILABLE");

 if (LIBOverlayProgram(callstring) != protocol->recsuccess)
    {LIBClearLine();
     return(FALSE);
    }

 LIBClearLine();
 return(TRUE);
}
//-

/// SendFile
BOOL __saveds __asm LIBSendFile(register __a0 struct Protocol  *protocol,
                                register __a1 char             *FilePath,
                                register __a2 char             *batchname,
                                register __a3 struct USER_DATA *user,
                                register __d0 struct Ram_File  *ram,
                                register __d1 char             *ext)

{char callstring[512];
 char tempstring[256];

 LIBTranslateBuffer((batchname)?protocol->sendbatch:protocol->sendstring, tempstring, 128, user, ram, ext);
 XferTranslate     (tempstring,  callstring,  FilePath, (batchname)?batchname:"Not_Available");

 if (LIBOverlayProgram(callstring) != protocol->sendsuccess)
    {LIBClearLine();
     return(FALSE);
    }

 LIBClearLine();
 return(TRUE);
}
//-

/// XferTranslate
void __regargs XferTranslate(char *source, char *dest, char *filename, char *batchfile)

{char *s;

 while(*source)
    {if (*source != '~')
        {*dest++ = *source++;
         continue;
        }

     source++;
     s = 0;
     switch(*source)
           {case 'f': s = filename;
                      break;

            case 'b': s = batchfile;
                      break;
           }

     if (s)
         dest = stpcpy(dest, s);
      else
        {*dest++ = '~';
         *dest++ = *source;
        }

     source++;
    }

 *dest = 0;
 return;
}
//-

/// ScreenPath
void __saveds __asm LIBScreenPath(register __a0 char *filename)

{while(*filename)
      {if (*filename == 58 ||   /* ':' */
           *filename == 47 ||   /* '/' */
           *filename == 35 ||   /* '#' */
           *filename == 63 ||   /* '?' */
           *filename == 42 ||   /* '*' */
           *filename == 60 ||   /* '<' */
           *filename == 62 ||   /* '>' */
           *filename == 32)     /* ' ' */
           *filename =  95;     /* '_' */

       filename++;
      }
}
//-
