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

#include <devices/tpt.h>

#include <dlg/dlg.h>
#include <dlg/portconfig.h>
#include <dlg/resman.h>
#include <dlg/user.h>
#include <dlg/log.h>

#include <link/io.h>
#include <link/lang.h>

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

#include <pragmas/dlg.h>

#include <private/Version.h>
#define  ObjRev "3"
const UBYTE version[]="\0$VER: Immed " BUILDVER "." ObjRev " ©" COPYRIGHT " by Digerati Dreams "__AMIGADATE__;

void             main(int , char **);
void             CleanUp(void);
void             Usage(char *);
void __regargs __chkabort();


BPTR            sout;
char          **SA;
struct Library *DLGBase      = NULL;
struct Library *DiskfontBase = NULL;
struct GfxBase *GfxBase      = NULL;

struct PortInfo        PInfo   = {NULL, NULL, NULL, 0, NULL};
struct Ram_File        RStruct = {"Connected", 0, "", 0, "Logging into System", 0, 0, 0, "", "", 0, 0, 0, 0, 0, ""};
struct Global_Settings Globals;
struct Port            MyPort;
struct Modem           MyModem;
struct Displays        MyDisplay;

char  port[4]   = "";
char  locked    = FALSE;
char  iwait     = FALSE;
UBYTE spawned   = TRUE;
BPTR  ofh       = NULL;


void main(int argc, char **argv)

{long lbaud;
 long rbaud;

 char *s;
 char  handle[5];
 char  log[24];
 char  filename[80];
 char  executestring[128];

   struct TextAttr   tAttr;
   struct TextFont  *tFont;
   struct RMMessage  rm;

 sout = Output(); 
 if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  exit(5);
 if (!(SA = getlang(NULL)))                          CleanUp();
 if (argc < 4)                                       Usage(NULL);

 strncpy(port, argv[1], 3);
 port[3] = 0;

 lbaud = atol(argv[2]);
 rbaud = atol(argv[3]);

 while(--argc > 0)
      {s = *++argv;

       if (*s++ == '-')
          {while(*s)
                {switch(*s++)
                       {case 'w':
                        case 'W': iwait  = TRUE;
                                  break;

                        default:  Usage(NULL);

                       }
                }
          }
      }

 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33L)))
    {AFPrintf(NULL, sout, SA[930]);
     CleanUp();
    }

 if (!(DiskfontBase = OpenLibrary("diskfont.library", 33)))
    {AFPrintf(NULL, sout, SA[931]);
     CleanUp();
    }

 PInfo.port = port;
 if (GetPortInfo(&PInfo) != RMNOERR)
    {if (ImmedLockPort(port, "BBS", "User OnLine", 0, "") != RMNOERR)
        {AFPrintf(NULL, sout, SA[932]);
         CleanUp();
        }

     locked = TRUE;
    }
  else
    {if (PInfo.priority > -1)
        {AFPrintf(NULL, sout, SA[933]);
         CleanUp();
        }

     if (TransferPortLock(port,PInfo.passwd,"BBS","User OnLine",0,"")!=RMNOERR)
        {AFPrintf(NULL, sout, SA[934]);
         CleanUp();
        }
    }

 spawned = FALSE;

 ASPrintf(NULL, handle, "%s:", port);
 ASPrintf(NULL, filename, "DlgConfig:Port/%s.port", port);
 if (GetFirstStruct(filename,(char *)&MyPort,sizeof(MyPort))==-1)
    {AFPrintf(NULL, sout, SA[935], filename);
     CleanUp();
    }

 ASPrintf(NULL, filename, "DlgConfig:Port/%s", MyPort.GlobalFile);
 if (GetFirstStruct(filename,(char *)&Globals,sizeof(Globals))==-1)
    {AFPrintf(NULL, sout, SA[935], filename);
     CleanUp();
    }

 ASPrintf(NULL, filename, "DlgConfig:Port/%s", MyPort.ModemFile);
 if (GetFirstStruct(filename,(char *)&MyModem,sizeof(MyModem))==-1)
    {AFPrintf(NULL, sout, SA[935], filename);
     CleanUp();
    }

 ASPrintf(NULL, filename, "DlgConfig:Port/%s", MyPort.DisplayFile);
 if (GetFirstStruct(filename,(char *)&MyDisplay,sizeof(MyDisplay))==-1)
    {AFPrintf(NULL, sout, SA[935], filename);
     CleanUp();
    }

 ASPrintf(NULL, filename, "%s%s/%d", handle, MyPort.Device, MyPort.Unit);
 if (MyModem.Lock)
     strcat(filename, "/7");
   else
     strcat(filename, "/0");

 if (Globals.DefaultScreen)
    {tAttr.ta_Name  = (UBYTE *)MyDisplay.Screen.fontname;
     tAttr.ta_YSize =  MyDisplay.Screen.fontsize;
    }
  else
    {tAttr.ta_Name  = (UBYTE *)MyDisplay.Window.fontname;
     tAttr.ta_YSize =  MyDisplay.Window.fontsize;
    }

 tAttr.ta_Style = FS_NORMAL;
 tAttr.ta_Flags = FPF_ROMFONT | FPF_DISKFONT | FPF_DESIGNED;
 if ((tFont=(struct TextFont *)OpenDiskFont(&tAttr)))  CloseFont(tFont);

 if (!(ofh=Open(filename, MODE_NEWFILE)))
    {AFPrintf(NULL, sout, SA[936]);
     CleanUp();
    }

 TBaud(lbaud,                   port);
 TUnSetFlags(T_BREAK | T_PAUSE, port);
 TSetFlags(T_RAW,               port);

 RStruct.Baud_Rate = rbaud;
 WriteRam(&RStruct, port);

 if (Globals.GlobalScreen)
    {if (!Globals.DefaultScreen)
          TWindow(WOPEN,      &MyDisplay.Window,port);
        else
          TScreen(TPOPSCREEN, &MyDisplay.Screen,port);
    }

 ASPrintf(NULL, log, "[%ld] Baud", RStruct.Baud_Rate);
 WriteLog(CONNECT,"System",port,log);

 TSetFlags(T_DO_PEND | T_KILL_ENABLE | T_PAUSE, port);
 TTimeDelay((Globals.TimeOut * 20),             port);

 if (Globals.VerbPause)
     TSetFlags(T_VERB_PAUSE,   port);
   else
     TUnSetFlags(T_VERB_PAUSE, port);

   // New for object 3 (2.1)

   rm.type = 98;
   ResourceMsg(&rm);

   SendCtlMsg(99,(long)rm.passwd,port);

   // end Object 3 changes

   SendCtlMsg(TVERSION, -2, port);

 ASPrintf(NULL, executestring, "newcli %s%s/%d%s from DLGCONFIG:Batch/%s.startup",handle,MyPort.Device,MyPort.Unit,(MyModem.Lock)?"/7":"",port);
 Execute(executestring, 0, 0);
 spawned = TRUE;

 if (ofh)
    {Close(ofh);
     ofh = NULL;
    }

 /* Wait for bbs to exit */ 
 if (iwait)
    {if (locked)
        {LockPort(port, "IMMED", "Exiting", 0, "");
         FreePort(port, "IMMED");
        }
      else
        {LockPort(port, "IMMED", "Exiting", 0, "");
         TransferPortLock(port,"IMMED",PInfo.passwd,PInfo.reason,PInfo.priority,PInfo.breakcommand);
        }
    }

 Delay(50);
 CleanUp();
}


void CleanUp()

{if (ofh)           Close(ofh);

 if (DiskfontBase)  CloseLibrary(DiskfontBase);
 if (GfxBase)       CloseLibrary((struct Library *)GfxBase);

 if (!spawned)
     if (locked)
         FreePort(port, "BBS");
       else
         TransferPortLock(port,"BBS",PInfo.passwd,PInfo.reason,PInfo.priority,PInfo.breakcommand);

 if (PInfo.passwd || PInfo.reason || PInfo.breakcommand)
     FreePortInfo(&PInfo);

 CloseLibrary(DLGBase); 
 exit(0);
}


void Usage(char *string)

{if (string)  AFPrintf(NULL, sout, SA[937], string);
 AFPrintf(NULL, sout, SA[938]);

 CleanUp();
}

void __regargs __chkabort()

{
}
