#include <exec/types.h>
#include <exec/io.h>
#include <intuition/intuition.h>
#include <proto/intuition.h>
#include <graphics/display.h>
#include <graphics/text.h>
#include <proto/graphics.h>
#include <proto/diskfont.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <ctype.h>

#include <devices/tpt.h>

#include <dlg/dlg.h>
#include <dlg/portconfig.h>

#include <link/io.h>

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

#include <pragmas/dlg.h>

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

BOOL  OpenConsole(struct IOStdReq *, struct IOStdReq *, struct Window *);
void  SetConRead(void);
void  HandleChar(void);
void  FakeLine(void);
void  WriteString(char *, int );
void  ConPutChar(char );
void  CloseConStuff(void);
void  CleanUp(char *);
void _CXBRK(void);


struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase             = NULL;
struct Library *DiskfontBase        = NULL;
struct Library *DLGBase             = NULL;

struct Screen   *Scr = NULL;
struct NewScreen ns;

struct Window   *w   = NULL;
struct Window   *rw  = NULL;
struct NewWindow nw;

struct IOStdReq *consoleWriteMsg   = NULL;
struct MsgPort  *consoleWritePort  = NULL;
struct IOStdReq *consoleReadMsg    = NULL;
struct MsgPort  *consoleReadPort   = NULL;

struct TextFont       *tf          = NULL;
struct Global_Settings Globals;

#define CONSOLE_SIG (1 << consoleReadPort->mp_SigBit)

UBYTE  cin_c;
BOOL   CONOPEN = FALSE;
BOOL   runflag = TRUE;
int    numchars;
long   signals;
char   name[23];
char   buf[255];
char   mydevice[4];
int    numlines;
UBYTE  linestr[5];


void main(int argc,char **argv)

{struct TextAttr ta;
 struct Port     MyPort;
 struct Displays MyDisplay;
 long   retval;
 char   filename[80];
 int    confheight, newlines;

 if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  exit(5);

 if (argc>1)
    {strncpy(mydevice,argv[1],3);
     mydevice[3]='\0';
     Upper(mydevice);
    }
  else
     strcpy(mydevice, "TPT");

 retval = TSetFlags(0,mydevice);
 if (retval==ACTIVERR)    CleanUp("Port not active");
 if (retval==FROZENERR)   CleanUp("Port is frozen");
 if (retval==GENERALERR)  CleanUp("Problem with port");

 IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",NULL);
 if (!IntuitionBase)  CleanUp("Unable to open intuition.library");

 GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",NULL);
 if (!GfxBase)  CleanUp("Unable to open graphics.library");

 DiskfontBase=(struct Library *) OpenLibrary("diskfont.library",NULL);
 if (!DiskfontBase)  CleanUp("Unable to open diskfont.library");

 consoleWritePort=CreatePort("conf.con.write",NULL);
 if (!consoleWritePort) CleanUp("Unable to open console write port");

 consoleWriteMsg=CreateStdIO(consoleWritePort);
 if (!consoleWriteMsg) CleanUp("Unable to open console write message");

 consoleReadPort=CreatePort("conf.con.read",NULL);
 if (!consoleReadPort) CleanUp("Unable to open console read port");

 consoleReadMsg=CreateStdIO(consoleReadPort);
 if (!consoleReadMsg) CleanUp("Unable to open console read message");

 Globals.DefaultScreen=1;

 strncpy(name,mydevice,3);

 MyDisplay.Screen.width     = 640;
 MyDisplay.Screen.height    = 200;
 MyDisplay.Screen.hires     =  1;
 MyDisplay.Screen.interlace =  0;
 strcpy(MyDisplay.Screen.fontname, "topaz.font");
 MyDisplay.Screen.fontsize  =  8;

 MyDisplay.Window.x         =  0;
 MyDisplay.Window.y         = 11;
 MyDisplay.Window.width     = 640;
 MyDisplay.Window.height    = 109;
 strcpy(MyDisplay.Window.fontname, "topaz.font");
 MyDisplay.Window.fontsize  =  8;

 ASPrintf(NULL, filename, "DlgConfig:Port/%s.port",mydevice);
 if (GetFirstStruct(filename,(char *)&MyPort,sizeof(MyPort))!=-1)
    {ASPrintf(NULL,filename,"DlgConfig:Port/%s",MyPort.GlobalFile);

     if (GetFirstStruct(filename,(char *)&Globals,sizeof(Globals))!=-1)
        {ASPrintf(NULL, filename,"DlgConfig:Port/%s",MyPort.DisplayFile);
         GetFirstStruct(filename,(char *)&MyDisplay,sizeof(MyDisplay));
        }
    }

 if (Globals.DefaultScreen)
    {strcat(name,": Conference Screen");
     name[22]='\0';

     numlines   = (MyDisplay.Screen.height-12)/MyDisplay.Screen.fontsize;
     confheight = (MyDisplay.Screen.fontsize * 6) + 13;
     newlines   = (MyDisplay.Screen.height-confheight-12)/MyDisplay.Screen.fontsize;

     ASPrintf(NULL,linestr,"%u",newlines);
     TWinHeight(linestr,mydevice);

     ns.LeftEdge     =  0;
     ns.TopEdge      = (MyDisplay.Screen.height-confheight);
     ns.Width        =  MyDisplay.Screen.width;
     ns.Height       =  confheight;
     ns.Depth        =  1;
     ns.DetailPen    =  0;
     ns.BlockPen     =  1;
     ns.ViewModes    =  NULL;
     if (MyDisplay.Screen.hires)      ns.ViewModes |= HIRES;
     if (MyDisplay.Screen.interlace)  ns.ViewModes |= INTERLACE;
     ns.Type         =  CUSTOMSCREEN;
     ns.Font         =  NULL;
     ns.DefaultTitle = (UBYTE *)name;
     ns.Gadgets      =  NULL;
     ns.CustomBitMap =  NULL;
     Scr = OpenScreen(&ns);
     if (!Scr)   CleanUp("Unable to open screen");

     nw.LeftEdge=0; nw.TopEdge=12;
     nw.Width=MyDisplay.Screen.width; nw.Height=(confheight-13);
     nw.DetailPen=(UBYTE)-1; nw.BlockPen=(UBYTE)-1;
     nw.IDCMPFlags=NULL;
     nw.Flags=SMART_REFRESH|BACKDROP|BORDERLESS|ACTIVATE;
     nw.FirstGadget=NULL;
     nw.CheckMark=NULL;
     nw.Title=NULL;
     nw.Screen=Scr;
     nw.BitMap=NULL;
     nw.MinWidth=0; nw.MinHeight=0; nw.MaxWidth=0; nw.MaxHeight=0;
     nw.Type=(USHORT)CUSTOMSCREEN;

     ta.ta_Name=(UBYTE *)MyDisplay.Screen.fontname;
     ta.ta_YSize=MyDisplay.Screen.fontsize;
    }
  else
    {struct Screen wbscreen;

     strcat(name,": Conference Window");
     name[22]='\0';

     GetScreenData(&wbscreen,sizeof(struct Screen),WBENCHSCREEN,NULL);

     /* If globals, Read Window display info here */
     nw.LeftEdge=MyDisplay.Window.x;

     if ((MyDisplay.Window.y + MyDisplay.Window.height + (MyDisplay.Window.fontsize*3) + 13) < wbscreen.Height)
          nw.TopEdge=MyDisplay.Window.y + MyDisplay.Window.height;
        else
          nw.TopEdge=wbscreen.Height-((MyDisplay.Window.fontsize*3)+13);

     nw.Width=MyDisplay.Window.width; nw.Height=(MyDisplay.Window.fontsize*3)+13;
     nw.DetailPen=(UBYTE)-1; nw.BlockPen=(UBYTE)-1;
     nw.IDCMPFlags=NULL;
     nw.Flags=WINDOWDEPTH|WINDOWSIZING|WINDOWDRAG|SMART_REFRESH|ACTIVATE;
     nw.FirstGadget=NULL;
     nw.CheckMark=NULL;
     nw.Title=(UBYTE *)name;
     nw.Screen=NULL;
     nw.BitMap=NULL;
     nw.MinWidth=85; nw.MinHeight=MyDisplay.Window.fontsize+13;
     nw.MaxWidth=(USHORT)-1; nw.MaxHeight=(USHORT)-1;
     nw.Type=(USHORT)WBENCHSCREEN;

     ta.ta_Name=(UBYTE *)MyDisplay.Window.fontname;
     ta.ta_YSize=MyDisplay.Window.fontsize;
    }

 w = OpenWindow(&nw);
 if (!w)  CleanUp("Unable to open window");

 ta.ta_Style = 0;
 ta.ta_Flags = FPF_ROMFONT | FPF_DISKFONT;
 tf = (struct TextFont *)OpenDiskFont(&ta);
 if (tf)  SetFont(w->RPort,tf);

 if (!OpenConsole(consoleWriteMsg,consoleReadMsg,w))
      CleanUp("Unable to open console device");

 CONOPEN = TRUE;
 consoleWriteMsg->io_Command=CMD_WRITE;

 SetConRead();

 WriteString("Type 'exit' to close the Conference ",36);
 if (Globals.DefaultScreen)
     WriteString("Screen\n",7);
   else
     WriteString("Window\n",7);

 numchars = 0;
 while(runflag)
      {signals = Wait(CONSOLE_SIG);
       if ((signals & CONSOLE_SIG) && CheckIO((struct IORequest *)consoleReadMsg))
          {HandleChar();
           SetConRead();
          }
      }

 CleanUp(NULL);
}


BOOL OpenConsole(struct IOStdReq *writerequest,struct IOStdReq *readrequest,struct Window *window)

{int error;

 writerequest->io_Data   = (APTR)window;
 writerequest->io_Length =  sizeof(*window);
 error                   =  OpenDevice("console.device",NULL,(struct IORequest *)writerequest,NULL);
 readrequest->io_Device  =  writerequest->io_Device;
 readrequest->io_Unit    =  writerequest->io_Unit;

 if (error)
     return(FALSE);
   else
     return(TRUE);
}


void SetConRead(void)

{consoleReadMsg->io_Length  =  1;
 consoleReadMsg->io_Command =  CMD_READ;
 consoleReadMsg->io_Data    = (APTR)&cin_c;

 SendIO((struct IORequest *)consoleReadMsg);
}


void HandleChar(void)

{Chk_Abort();
 switch(cin_c)
       {case 13:  cin_c = 10;
                  ConPutChar(cin_c);
                  buf[numchars]=13;
                  buf[numchars+1]='\0';
                  FakeLine();

                  if (!Stricmp(buf,"exit\x0D"))
                     {runflag=FALSE;
                      cin_c=0;
                      break;
                     }

                  numchars=-1;
                  break;

        case 10:  cin_c=0;
                  break;

        case 8:
        case 127: if (numchars)
                     {ConPutChar(8);
                      ConPutChar(' ');
                      ConPutChar(8);
                      cin_c=0;
                      numchars--;
                     }
                  break;
       }

 if ((cin_c<10) || (cin_c==11) || (cin_c==12) || ((cin_c>13) && (cin_c<32)) || (cin_c>126))
      cin_c=0;

 if (cin_c && (numchars<239))
    {if (numchars>=0) buf[numchars]=cin_c;
     numchars++;
     ConPutChar(cin_c);
    }
}


void FakeLine(void)

{if (TString(buf, mydevice) != NOERR)
     CleanUp("Couldn't output to port");
}


void WriteString(char *buf,int len)

{int i=0;

 for(i=0;i<len;i++) ConPutChar(buf[i]);
}


void ConPutChar(char c)

{consoleWriteMsg->io_Data   = (APTR)&c;
 consoleWriteMsg->io_Length =  1;
 DoIO((struct IORequest *)consoleWriteMsg);
}


void CloseConStuff(void)

{if (CONOPEN)
    {AbortIO((struct IORequest *)consoleReadMsg);
     WaitIO((struct IORequest *)consoleReadMsg);
     CloseDevice((struct IORequest *)consoleWriteMsg);
    }

 if (tf)   CloseFont(tf);
 if (w)    CloseWindow(w);
 if (Scr)  CloseScreen(Scr);

 if (consoleReadMsg)    DeleteStdIO(consoleReadMsg);
 if (consoleReadPort)   DeletePort(consoleReadPort);
 if (consoleWriteMsg)   DeleteStdIO(consoleWriteMsg);
 if (consoleWritePort)  DeletePort(consoleWritePort);
 if (DiskfontBase)      CloseLibrary(DiskfontBase);
 if (GfxBase)           CloseLibrary((struct Library *)GfxBase);
 if (IntuitionBase)     CloseLibrary((struct Library *)IntuitionBase);
}


void CleanUp(char *s)

{CloseConStuff();

 ASPrintf(NULL, linestr,"%u", numlines);
 if (Globals.DefaultScreen)  TWinHeight(linestr,mydevice);
 CloseLibrary(DLGBase);

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

 exit(s?5:0);
}


void _CXBRK(void)

{CleanUp(NULL);
}
