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

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

#include <libraries/dosextens.h>

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

#include <link/io.h>

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

#include <pragmas/dlg.h>

char **libgetlang(void);
extern char               nline;
extern struct MsgPort    *bcport;
extern struct DosLibrary *DOSBase;

LONG __saveds __asm LIBAddStruct(register __a0 char   *, register __a1 char *, register __d0 ULONG, register __d1 USHORT);
BOOL __saveds __asm LIBReadRam(register __a0 struct Ram_File *, register __a1 char *);
BOOL __saveds __asm LIBWriteEvent(register __a0 char *, register __a1 char *);
LONG __saveds __asm LIBCheckUser(register __a0 char *);
LONG __saveds __asm LIBListPorts(register __a0 char *, register __a1 char *);
void __saveds __asm LIBUnderScore(register __a0 char *);
LONG __saveds __asm LIBStricmp(register __a0 char *,  register __a1 char *);
LONG __saveds __asm LIBStrnicmp(register __a0 char *, register __a1 char *, register __d0 USHORT);


LONG __saveds __asm LIBBCMsg(register __a0 char *ports,
                             register __a1 char *buffer,
                             register __d0 UBYTE type,
                             register __d1 UBYTE flags)

{struct MsgPort   *myport;
 struct MsgPort   *bcctl;
 struct BCMessage  bcmess;

 Forbid();
 bcctl = FindPort(BCCONTROL);
 Permit();
 if (!bcctl)  return(NOBC);

 myport = CreateMsgPort();
 if (!myport)  return(BCNOMEM);

 bcmess.mess.mn_Node.ln_Type = NT_MESSAGE;
 bcmess.mess.mn_ReplyPort    = myport;
 bcmess.mess.mn_Length       = sizeof(struct BCMessage);
 bcmess.type                 = type;
 bcmess.ports                = ports;
 bcmess.buffer               = buffer;
 bcmess.flags                = flags;

 PutMsg(bcctl,(struct Message *)&bcmess);
 while(!GetMsg(myport))
        WaitPort(myport);
 DeleteMsgPort(myport);

 return((LONG)bcmess.type);
}


LONG __saveds __asm LIBBroadCast(register __a0 char *ports,
                                 register __a1 char *buffer,
                                 register __d0 UBYTE flags)

{return(LIBBCMsg(ports,buffer,BCMSG,flags));
}


LONG __saveds __asm LIBBCPend(register __a0 char *port)

{return(LIBBCMsg(port,NULL,BCPEND,0));
}


LONG __saveds __asm LIBBCResume(register __a0 char *port)

{return(LIBBCMsg(port,NULL,BCRESUME,0));
}


LONG __saveds __asm LIBBCGet(register __a0 char *port,
         register __a1 char *buffer)

{return(LIBBCMsg(port,buffer,BCGET,0));
}


LONG __saveds __asm LIBHandleBCMsgs(register __a0 char *port)

{BPTR   sout;
 char **SA;
 long   gotany = FALSE;
 char   buf[80];

 sout = Output();
 SA   = libgetlang();

 while(LIBBCGet(port,buf)==BCNOERR)
      {gotany = TRUE;
       AFPrintf(NULL, sout, SA[3632]);
       Write(sout, buf, strlen(buf));
       Write(sout, &nline, 1);
      }

 if (gotany)  Write(sout, &nline, 1);
 return(gotany);
}


BOOL __saveds __asm LIBInform(register __a0 char *username,
                              register __a1 char *buffer,
                              register __a2 char *devname,
                              register __d0 UBYTE flags)

{char   ports[80];
 char  *s;
 char   eventlog = TRUE;
 struct Ram_File RStruct;

 if (flags>127)
    {eventlog = FALSE;
     flags   -= 128;
    }

 LIBListPorts(ports,"BBS");

 if (LIBStricmp(username,"all"))
    {for(s = ports; *s; s+=3)
         if (LIBReadRam(&RStruct, s))
             if (!LIBStricmp(username, RStruct.Name))
                  break;

     if (*s)
        {*(s+3) = 0;
         strcpy(ports, s);
        }
      else
       {if (eventlog)  LIBWriteEvent(username,buffer);
        return(FALSE);
       }
    }

 if (devname && *devname)
    {for(s=ports; *s && strncmp(s,devname,3) ;s+=3);
     if (*s)  movmem(s+3, s, strlen(ports)-((int)((long)s-(long)ports)+1));
    }

 LIBBroadCast(ports, buffer, flags);
 return(TRUE);
}


BOOL __saveds __asm LIBWaitingMail(register __a0 char *toname,
                                   register __a1 char *from,
                                   register __a2 char *subject,
                                   register __d0 USHORT areanum,
                                   register __a3 char *areaname,
                                   register __d1 SHORT messagenum,
                                   register __d2 void *aext)
{char  *ext = (char *)aext;
 char **SA;
 char   informstr[80];
 struct WaitingMail WMail;

 SA = libgetlang();

 /* Check for existance of user */
 if (LIBCheckUser(toname)!=1)  return(FALSE);

 /* At this point, the user exists in the form of a user */
 /* Inform the user of the message if he is online */
 ASPrintf(NULL,informstr,SA[3633],messagenum,from,areanum);
 LIBInform(toname,informstr,ext,128);

 /* Construct structure data */
 ASPrintf(NULL,WMail.msgid,"%04d:%05d",areanum,messagenum);
 strcpy(WMail.from,from);
 strcpy(WMail.subject,subject);
 strcpy(WMail.areaname,areaname);
 WMail.areanum    = areanum;
 WMail.messagenum = messagenum;

 /* Write the structure to the proper user accounts */
 ASPrintf(NULL,informstr,"User:%s/WaitingMail.dat",toname);
 LIBUnderScore(informstr);
 LIBAddStruct(informstr,(char *)&WMail,sizeof(WMail),10);

 return(TRUE);
}
