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

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

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

#include <dlg/dlg.h>
#include <dlg/msg.h>
#include <dlg/user.h>

#include <link/io.h>

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

#include <pragmas/dlg.h>

char **libgetlang(void);
struct Integer {USHORT value;
               };

void  __saveds __asm LIBDraw_Line(register __d0 UBYTE);
LONG  __saveds __asm LIBDispBuffer(register __d0 BPTR, register __a0 char *, register __a1 USHORT *, register __d1 USHORT, register __a2 char *, register __d2 USHORT, register __a3 char *, register __d3 struct USER_DATA *);

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 LIBGetStruct(register __a0 char  *, register __a1 char *, register __d0 ULONG, register __d1 USHORT);
LONG  __saveds __asm LIBAddStruct(register __a0 char   *, register __a1 char *, register __d0 ULONG, register __d1 USHORT);
LONG  __saveds __asm LIBDeleteStruct(register __a0 char *, register __a1 char *, register __d0 ULONG, register __d1 USHORT);

LONG  __saveds __asm LIBStricmp(register __a0 char *,  register __a1 char *);
LONG  __saveds __asm LIBStrnicmp(register __a0 char *, register __a1 char *, register __d0 USHORT);
void  __saveds __asm LIBUpper(register __a0 char *);


BOOL __saveds __asm LIBReadArea(register __d0 USHORT           area,
                                register __a0 struct Msg_Area *msgarea,
                                register __d1 UBYTE            flag)
{BPTR            fh;
 struct Msg_Area temparea;

 if (!flag)
     fh = Open("MSG:Area.BBS", MODE_OLDFILE);
   else
     fh = Open("FILE:Area.BBS",MODE_OLDFILE);

 if (!fh)  return(FALSE);

 while(Read(fh, &temparea, sizeof(temparea)) == sizeof(temparea))
       if (temparea.Number==area)
          {movmem(&temparea, msgarea, sizeof(temparea));
           Close(fh);
           return(TRUE);
          }

 Close(fh);
 return(FALSE);
}


BOOL __saveds __asm LIBAddArea(register __a0 char   *filename,
                               register __d0 USHORT  area)

{BPTR   fh;
 USHORT darea;

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

 Seek(fh, 0, OFFSET_END);
 darea = area;
 Write(fh, &darea, sizeof(USHORT));
 Close(fh);

 return(TRUE);
}


BOOL __saveds __asm LIBDelArea(register __a0 char   *filename,
                               register __d0 USHORT  area)
{
   BOOL     found = FALSE;
   BPTR     fh;
   long     num;
   ULONG    size;
   USHORT  *a;
   USHORT  *i;

   if (LIBFileSize(filename, &size) == -1)      return(FALSE);
   if (!size)                                   return(FALSE);
   if (!(a = AllocMem(size, MEMF_PUBLIC)))      return(FALSE);

   if(!(fh = Open(filename,MODE_OLDFILE)))      return(FALSE);

   Read(fh, a, size);
   Close(fh);
   DeleteFile(filename);

   fh = Open(filename,MODE_NEWFILE);

   num = size/sizeof(USHORT);

   for(i = a; i < (a + num); i++)
   {
      if(*i != area)
      {
         Write(fh,i,sizeof(USHORT));
         found = TRUE;
      }
   }

   Close(fh);
   FreeMem(a, size);

   if(!found)  return(FALSE);
   return(TRUE);
}


BOOL __saveds __asm LIBExistsGlobalArea(register __a0 char   *filename,
                                        register __d0 USHORT  area)
{
   BPTR     fh;

   ULONG    size = 0;
   USHORT   limit;

   USHORT  *a;
   USHORT  *i;

   if (LIBFileSize(filename, &size) == -1)      return(FALSE);
   if (size == 0)                               return(FALSE);
   if (!(a = AllocMem(size, MEMF_PUBLIC)))      return(FALSE);

   fh = Open(filename,MODE_OLDFILE);

   if(fh)
   {
      Read(fh,a,size);
      Close(fh);

      limit = size/sizeof(USHORT);

      for(i = a; i < (a + limit); i++)
      {
         if (*i == area)
         {
            FreeMem(a, size);
            return(TRUE);
         }
      }
   }

   FreeMem(a, size);
   return(FALSE);
}



LONG __saveds __asm LIBListAreas(register __a0 char             *name,
                                 register __a1 struct USER_DATA *user,
                                 register __d0 char              flag,
                                 register __d1 UBYTE             sig)

{BPTR   fh;
 BPTR   sout;

 ULONG  size;
 long   retval;

 char **SA;
 char  *extension;
 char  *path;
 char  *tline;

 struct SIG_Def   Sig;
 struct Msg_Area  msgarea;
 struct Msg_Log   msguser;
 struct USER_DATA tuser;

 UBYTE  u_width;
 char   line   [120];
 char   filename[64];
 char   flippybindle = 0;
 USHORT pos          = 3;


 /* if no user structure was passed, create a tempuser */
 if (!user)
    {tuser.Screen_Width = 80;
     tuser.Screen_Len   = 23;
     tuser.Ansi_Flag    =  0;
    }
  else
     movmem(user, &tuser, sizeof(struct USER_DATA));


 /* calculate MSG or FILE based on the passed flag */
 if (flag)
    {extension = "file";
     path      = "FILE:";
    }
  else
    {extension = "msg";
     path      = "MSG:";
    }


 /* Calculate the name of the area.bbs file or a corresponding SIG file */
 sout = Output();
 SA   = libgetlang();

 if (!sig)
    {tline = stpcpy(filename, path);
             strcpy(tline,   "Area.bbs");
     AFPrintf(&tuser, sout, SA[3668]);
    }
   else
    {Sig.number = sig;

     tline = stpcpy(filename, "DLGConfig:Sigs/SIGS.");
             strcpy(tline,     extension);
     if (LIBGetStruct(filename, (char *)&Sig, sizeof(Sig), 1))  return(-1);

     ASPrintf(NULL, filename, "DLGConfig:Sigs/%s.%s", Sig.name, extension);
     AFPrintf(&tuser, sout, SA[3669], Sig.name);
    }


 /* Get size of the area file */
 if (LIBFileSize(filename, &size) == -1)  return(-1);
 if (!size)
    {AFPrintf(&tuser, sout, SA[3665]);
     return(-1);
    }


 /* open the areafile for read */
 if (!(fh = Open(filename, MODE_OLDFILE)))  return(-1);


 /* Read each area and selectivly add it to the list */
 tline   = line;
 u_width = tuser.Screen_Width-2;
 LIBDraw_Line(u_width);

 while(Read(fh, &msgarea, sizeof(msgarea)) == sizeof(msgarea))
      {if (!((msgarea.Flag & AUTO_ACCESS_AREA)  &&  tuser.User_Level >= msgarea.llevel  &&  tuser.User_Level <= msgarea.ulevel))
          {if (name)
              {if (flag)
                   ASPrintf(NULL, filename, "%s%d/User.File", path, msgarea.Number);
                 else
                   ASPrintf(NULL, filename, "%s%d/User.Msg",  path, msgarea.Number);

               strcpy(msguser.Name, name);
               LIBUpper(msguser.Name);

               if (LIBGetStruct(filename, (char *)&msguser, sizeof(msguser),36))  continue;
              }
          }

       if (u_width < 73)  flippybindle++;
       flippybindle = ((flippybindle+1) & 1);

       if (flippybindle)
          {tline += ASPrintf(&tuser, line, SA[3666], msgarea.Number, msgarea.Name);
           continue;
          }

       ASPrintf(&tuser, tline,  SA[3667], msgarea.Number, msgarea.Name);
       tline  = line;
       retval = LIBDispBuffer(sout, line, &pos, NULL, NULL, 0, "\x03", &tuser);
       if (retval == -2)
           tuser.More_Flag = 0;
         else
           if (retval)  break;
      }

 if (flippybindle)
    {LIBDispBuffer(sout, line, &pos, NULL, NULL, 0, "\x03", &tuser);
     AFPrintf(NULL,sout,"\n");
    }

 AFPrintf(&tuser, sout, SA[3670]);
 LIBDraw_Line(u_width);

 Close(fh);
 return(0);
}


LONG __saveds __asm LIBListSIGS(register __a0 struct USER_DATA *user,
                                register __d0 char              type,
                                register __d1 char              filter)

{BPTR    sout;
 BPTR    fh;
 char  **SA;
 char   *tline;

 long    retval;
 USHORT  pos;
 char    flippybindle;
 UBYTE   u_width;

 static char  filename [32] = "DLGConfig:Sigs/SIGS.";
        char  line     [120];

 struct SIG_Def   Sig;
 struct USER_DATA tuser;


 Forbid();
 if (type)
     strcpy(&filename[20], "File");
   else
     strcpy(&filename[20], "Msg");
 fh = Open(filename, MODE_OLDFILE);
 Permit();
 if (!fh)  return(-1);

 movmem(user, &tuser, sizeof(struct USER_DATA));
 SA      = libgetlang();
 sout    = Output();
 u_width = (user->Screen_Width) - 2;
 AFPrintf(user,sout,SA[3673]);
 LIBDraw_Line(u_width);


 pos          = 1;
 flippybindle = 0;
 tline        = line;

 while(Read(fh, &Sig, sizeof(Sig)) == sizeof(Sig))
      {if (filter)
           if (user->User_Level<Sig.level)  continue;

       if (u_width < 73)  flippybindle++;
       flippybindle = ((flippybindle+1) & 1);

       if (flippybindle)
          {tline += ASPrintf(user, line, SA[3674], Sig.number, Sig.name);
           continue;
          }

       ASPrintf(user, tline, SA[3675], Sig.number, Sig.name);
       tline  = line;
       retval = LIBDispBuffer(sout, line, &pos, NULL, NULL, 0, "\x03", &tuser);
       if (retval == -2)
           tuser.More_Flag = 0;
         else
           if (retval)  break;
      }

 if (flippybindle)
    {LIBDispBuffer(sout, line, &pos, NULL, NULL, 0, "\x03", &tuser);
     AFPrintf(NULL,sout,"\n");
    }


 AFPrintf(user, sout, SA[3676]);
 LIBDraw_Line(u_width);
 AFPrintf(NULL, sout, "\n");

 Close(fh);
 return(0);
}
