#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <dos.h>
#include <exec/types.h>
#include <libraries/dosextens.h>

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

#include <dlg_private/dlg.h>

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

#include <pragmas/dlg.h>

static char version[]="$VER: Bulletin 2.1 © 1995-1997 by DLG Development "__AMIGADATE__"";

#define STK RStruct.Command_Stack
#define HOT UserDat.Hot_Keys


BOOL   Read_Message(long, long);
void  _CXBRK(void);
void   CleanUp(char *);


BPTR                 sout;
struct Library      *DLGBase = NULL;
struct LangStruct   *ls;
char               **SA;


struct USER_DATA   UserDat;
struct Ram_File    RStruct;
char   passwd[] = "Bull   ";


void main(int argc, char **argv)

{long   Low_Message;
 long   High_Message;
 long   Message;
 BOOL   read = FALSE;
 char   Ext[4];
 struct Msg_Log    Log;

 sout = Output();

 if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  CleanUp("Unable to open DLG.library");
 if (GetDevName(Ext) == -1)                          CleanUp("Unable to get port");
 if (!(ls = GetLang(Ext)))                           CleanUp("Unable to get language");
 if (!ReadUser(&RStruct, &UserDat, Ext))              CleanUp("Unable to read user data");
 SA = ls->strings;

 /*                */
 /* SetUp Password */
 strcpy(&passwd[4], Ext);


 /*                             */
 /* Get Bulletin Hi-Lo Pointers */
 GetHiLowPointers(0, NULL, &Low_Message, &High_Message, passwd);

 /*                    */
 /* Get User High Read */
 strcpy(Log.Name, RStruct.Name);

 if (GetStruct("MSG:0/User.Msg", (char *)&Log, sizeof(Log), 36) == -1)
    {Log.High_Mess =  0;
     Log.Priv_Flag = 255;
     Log.uflag     =  0;
     Log.dflag     =  0;
     Log.special   =  0;
    }

 if (Log.High_Mess > High_Message)  Log.High_Mess = 0;
 Message = (Log.High_Mess < Low_Message) ? Low_Message-1 : Log.High_Mess;


 /*                   */
 /* Process Bulletins */
 while(Message < High_Message)
      {Message++;
       if (Message == High_Message)
          {Log.High_Mess = Message;
           AddStruct("MSG:0/User.Msg",(char *)&Log,sizeof(Log),36);
          }

       if (Read_Message(Message, High_Message))
          {read = TRUE;
           Pause();
           Clr(UserDat.Ansi_Flag);
          }
      }

 if (!read)  AFPrintf(&UserDat, sout, SA[17]);


 /*                  */
 /* Update User Data */
 WriteUser(RStruct.Name, &UserDat);
 WriteRam(&RStruct, Ext);


 /*      */
 /* Exit */
 CleanUp(NULL);
}


BOOL Read_Message(long msg, long hi)

{FILE  *fp;
 char   dbuffer  [512];
 char   tempstack[256];
 char   filename [100];
 USHORT pos;
 struct Bulletin Header;

 ASPrintf(NULL, filename, "MSG:0/%ld.MSG", msg);

 if (!(fp = fopen(filename, "r")))  return(FALSE);
 fread(&Header, sizeof(Header), 1, fp);
 fclose(fp);

 if (Header.Expire < AmigaTime())
    {DeleteFile(filename);
     return(FALSE);
    }

 if (Header.Attribute & STACK)
    {if (strlen(RStruct.Command_Stack) + strlen(Header.Title) > 255)  return(FALSE);

     strcpy(tempstack,             RStruct.Command_Stack);
     strcpy(RStruct.Command_Stack, Header.Title);
     strcat(RStruct.Command_Stack, tempstack);
     return(FALSE);
    }

 AFPrintf(NULL,sout,"\n");
 Capitalize(Header.From);
 ASPrintf(&UserDat, dbuffer, SA[18], Header.From);
 Capitalize(Header.To);
 ASPrintf(&UserDat, dbuffer+strlen(dbuffer), SA[19], msg, hi, Header.To);
 ASPrintf(&UserDat, dbuffer+strlen(dbuffer), SA[20], Header.Date, Header.Title);

 pos = 1;
 DisplayBuffer(sout,dbuffer,UserDat.Screen_Width-1,UserDat.Screen_Len,UserDat.More_Flag,UserDat.Ansi_Flag,&pos,0,NULL,1,"\003\016\032");

 AFPrintf(&UserDat, sout, "\n%a6");
 pos++;

 Display_Msg(0,NULL,SA[21],MSG_MSGAREA,filename,UserDat.Screen_Width,UserDat.Screen_Len,UserDat.More_Flag,&pos,(long)sizeof(Header),UserDat.Ansi_Flag,SA[22]);
 AFPrintf(NULL,sout,"\n");
 UserDat.Messages_Read++;

 return(TRUE);
}


void _CXBRK()

{CleanUp(NULL);
}


void CleanUp(char *s)

{if (DLGBase)  CloseLibrary(DLGBase);

 if (s)
    {Write(sout, "\n Error: ", 9);
     Write(sout, s, strlen(s));
     Write(sout, "\n\n", 2);
    }

 exit(s?5:0);
}
