#include "Includes.h"
#include "Defines.h"
#include "Protos.h"
#include "Version.h"
#include "Vars.h"

#include <link/io.h>

struct Screen    *Screen=NULL;
struct Window    *Window=NULL;
struct MsgPort      *ConReadPort=NULL;
struct MsgPort      *ConRitePort=NULL;
struct IOStdReq  *ConReadMsg=NULL;
struct IOStdReq  *ConRiteMsg=NULL;
struct ColorMap  *NewColorMap=NULL;
struct ColorMap  *OldColorMap=NULL;
struct TextFont  *font=NULL;

int ScreenPixelWidth=640;

static UWORD NewColors [] = { 0x888, 0x000, 0xfff, 0x66b };

/// MyFont
struct TextAttr MyFont =
{
   "topaz.font",     /* Name          */
   8,          /* Height        */
   FS_NORMAL,        /* Style         */
   FPF_DISKFONT      /* Preferences   */
};
//-

UWORD Pens[] = {0,1,(USHORT)~0 }; /* just detail and block */

UBYTE PUBSCNNAME[50];

ULONG sd[]=
{
   SA_PubName, (ULONG)PUBSCNNAME,
   SA_Title,   (ULONG)"DLGMail ©" COPYRIGHT " by Digerati Dreams",
   SA_Pens,(ULONG)Pens, 0, 0
};

/// ns
struct ExtNewScreen ns =
{
   0,            /* left edge     */
   0,            /* Top edge      */
   640,          /* Default Width         */
   200,          /* Default Height        */
   2,            /* Depth         */
   1,            /* Detail Pen    */
   3,            /* Block Pen     */
   HIRES,        /* View Modes    */
   PUBLICSCREEN|
   NS_EXTENDED,  /* Type          */
   &MyFont,      /* Font          */
   NULL,         /* Default Title */
   NULL,         /* Gadgets       */
   NULL,         /* Custom Bit Map*/
   (struct TagItem *)&sd[0] /* new tagitem array */
};
//-

/// nw
struct NewWindow nw = 
{
   0,            /* Left Edge     */
   12,           /* Top Edge      */
   640,          /* Width         */
   78,           /* Height        */
   2,            /* Detail Pen    */
   1,            /* Block Pen     */
   NULL,         /* IDCMPFlags    */
   WINDOWDEPTH|
   WINDOWDRAG|
   WINDOWSIZING|
   SMART_REFRESH,/* Flags         */
   NULL,         /* FirstGadget   */
   NULL,         /* CheckMark     */
   "DLGMail",    /* Title         */
   NULL,         /* Screen        */                              
   NULL,         /* Bit Map       */
   200,          /* MinWidth      */
   78,          /* MinHeight     */
   640,          /* MaxWidth      */
   78,          /* MaxHeight     */
   WBENCHSCREEN  /* Type          */
};
//-

char  lin_buf[7][120];
char  boundsreport[50];
char  report[50];
char  Buffer[4];


char *printlines[]=
{
   "[1;2H[33;1mARexx CMD: [0;33m",
   "[2;2H  [31;1mInstant: [0;31m",
   "[3;2H[31;1mCoProcs 0: [0;31m",
   "[4;2H[31;1mCoProcs 1: [0;31m",
   "[5;2H[31;1mCoProcs 2: [0;31m",
   "[6;2H[31;1mCoProcs 3: [0;31m",
   "[7;2H [32;1mStat/Err: [0;32m"
};

/// QueueRead
int QueueRead(void)
{ 
    ConReadMsg -> io_Command = CMD_READ;
    ConReadMsg -> io_Data    = (APTR) Buffer;
    ConReadMsg -> io_Length  = 1;
    SendIO((struct IORequest *)ConReadMsg);
    return 0;
}
//-

/// ConOpen
int ConOpen(void)
{
   struct Screen *pubscn=NULL;

   int      conflag;
 
   font=(void *)OpenFont(&MyFont);
   
   if(font)
   {
      if(font->tf_YSize != MyFont.ta_YSize)
      {
         CloseFont(font);
         font=NULL;
      }
   }
   
   if(!font)
   {
      font=OpenDiskFont(&MyFont);

      if(font)
      {
         if(font->tf_YSize != MyFont.ta_YSize)
         {
            CloseFont(font);
            font=NULL;
         }
      }
   }

   /* ================== PUBLIC SCREEN SHIT ==================== */

   if(*_SCREENNAME && OS_VERSION>36)
   {
      strcpy(PUBSCNNAME,_SCREENNAME);
      pubscn=(struct Screen *)LockPubScreen((void *)PUBSCNNAME);

      if(!pubscn)
      {
         if(_PUBSCNBEHIND)
            ns.Type |= SCREENBEHIND;

         ns.DefaultTitle=PUBSCNNAME;

         if(_PUBSCNLACE)      ns.ViewModes |= LACE;
         if(_PUBSCNOSCAN)     ns.Width=-1;
         if(_PUBSCNOSCAN && _PUBSCNLACE)  ns.Height=-1;

         if(Screen=OpenScreen((struct NewScreen *)&ns))
         {
            PubScreenStatus(Screen,0);

            nw.Screen=Screen;
            nw.Type=PUBLICSCREEN;
            ScreenPixelWidth=Screen->Width;
            nw.Width=ScreenPixelWidth;
            nw.MaxWidth=ScreenPixelWidth;
         }
      }
      else
      {
         /* we have a public screen already */

         nw.Screen=pubscn;
         Screen=pubscn;
         nw.Type=PUBLICSCREEN;
         ScreenPixelWidth=Screen->Width;
         nw.Width=ScreenPixelWidth;
         nw.MaxWidth=ScreenPixelWidth;
      }
   }

   if(_WIN_X)  nw.LeftEdge=_WIN_X;
   if(_WIN_Y)  nw.TopEdge=_WIN_Y;
   if(_WIN_WIDTH)    nw.Width=_WIN_WIDTH;

   _SCNPTR=Screen;

   if(Window=OpenWindow((struct NewWindow *)&nw))
   {
      if(pubscn)
      {
         if(OS_VERSION>36)
         {
            UnlockPubScreen(NULL,pubscn);
         }
         pubscn=NULL;
      }
      if(font)SetFont(Window->RPort,font);
      if(ConRitePort=CreatePort(0,0)) /*MyCon.Rite*/
      {
         if(ConRiteMsg=CreateStdIO(ConRitePort))
         {
            if(ConReadPort=CreatePort(0,0)) /*MyCon.Read*/
            {
               if(ConReadMsg=CreateStdIO(ConReadPort))
               {
                  ConRiteMsg -> io_Data   = (APTR) Window;
                  ConRiteMsg -> io_Length = sizeof(*Window);
                  conflag=0;
                  if(!OpenDevice("console.device",conflag,(struct IORequest *)ConRiteMsg,0))
                  {
                     ConReadMsg -> io_Device = ConRiteMsg -> io_Device;
                     ConReadMsg -> io_Unit   = ConRiteMsg -> io_Unit;
                     QueueRead();
                     InitWindow();
                     return(TRUE);
                  }
                  DeleteStdIO(ConReadMsg);
               }  
               DeletePort(ConReadPort);
            }
            DeleteStdIO(ConRiteMsg);
         }
         DeletePort(ConRitePort);
      }
      CloseWindow(Window);
   }

   if(pubscn && OS_VERSION>36) UnlockPubScreen(NULL,pubscn);

   if(Screen)
      CloseScreen(Screen);

   if(NewColorMap)
   {
      Screen -> ViewPort.ColorMap = OldColorMap;
      FreeColorMap(NewColorMap);
   }

   if(font)
      CloseFont(font);



   return(FALSE);
}
//-

/// ConClose
void ConClose(void)
{
   if (!CheckIO((struct IORequest *)ConReadMsg))
      AbortIO((struct IORequest *)ConReadMsg);

      WaitPort(ConReadPort);
      GetMsg(ConReadPort);

   if(ConRiteMsg)
      CloseDevice((struct IORequest *)ConRiteMsg);
   if(ConReadMsg)
      DeleteStdIO(ConReadMsg);
   if(ConReadPort)
      DeletePort(ConReadPort);
   if(ConRiteMsg)
      DeleteStdIO(ConRiteMsg);
   if(ConRitePort)
      DeletePort(ConRitePort);
   if(Window)
      CloseWindow(Window);
   if(NewColorMap)
      FreeColorMap(NewColorMap);
   if(Screen)
   {
      /*Screen -> ViewPort.ColorMap = OldColorMap;*/
      CloseScreen(Screen);
   }
   if(GfxBase)
      CloseLibrary((void *) GfxBase);
#ifndef DLGMAIL
   if(IntuitionBase)
      CloseLibrary((void *) IntuitionBase);
#endif
   if(font)
      CloseFont(font);
   if(DiskfontBase)
      CloseLibrary(DiskfontBase);
}
//-

/* Truly Useful Routines Begin Here */

/// ConGetChar
char ConGetChar(void)
{
   char temp;

   while(NULL == GetMsg(ConReadPort))
   {
      WaitPort(ConReadPort);
   }

   temp = *Buffer;
   QueueRead();
   return(temp);
}
//-

/// ConCheck
int ConCheck(void)
{
   if (NULL == CheckIO((struct IORequest *)ConReadMsg))
   {
      return(FALSE);
   }
   else
   {
      return(TRUE);
   }
}
//-

/// ConPutStr
#define CHECKSIZE 0

int ConPutStr(char *Str)
{
   char aaa[10];
   char *aab;
   int c;
   UBYTE *causereport="›0 q";

   aab=aaa;
   aab++;

   if(CHECKSIZE)
   {
      ConRiteMsg -> io_Command = CMD_WRITE;
      ConRiteMsg -> io_Data    = (APTR) causereport;
      ConRiteMsg -> io_Length  = -1;
      DoIO((struct IORequest *)ConRiteMsg);

      if(ConCheck())
      {
         while(ConCheck())
         {
            c=ConGetChar();
            if(c==-101)
            {
               strcpy(report,"");

               while(ConCheck())
               {
                  *aab=0;
                  *aaa=ConGetChar();
   
                  strcat(report,aaa);
               
                  if(isalpha(*aaa)) break;
               }

               if(0==Strnicmp(report,"1;1;",4))
               {
                  /* our window bounds report */
            
                  if(Stricmp(report,boundsreport))
                  {
                     strcpy(boundsreport,report);
                     RedrawWindow();
                  }
               }
            }
         }
      }
   }

   ConRiteMsg -> io_Command = CMD_WRITE;
   ConRiteMsg -> io_Data    = (APTR) Str;
   ConRiteMsg -> io_Length  = -1;
   DoIO((struct IORequest *)ConRiteMsg);
   return 0;
}
//-

/// ConPutChar
void ConPutChar(char Character)
{
   ConRiteMsg -> io_Command = CMD_WRITE;
   ConRiteMsg -> io_Data    = (APTR) &Character;
   ConRiteMsg -> io_Length  = 1;
   DoIO((struct IORequest *)ConRiteMsg);
}
//-

/// ConCommandLine
void ConCommandLine(char *string)
{
   ASPrintf(NULL,lin_buf[0],"%s%-75.75s[33m ",printlines[0],string);
   RedrawWindow();
}
//-

/// InstCommandLine
void InstCommandLine(char *string)
{
   ASPrintf(NULL,lin_buf[1],"%s%-75.75s[33m ",printlines[1],string);
   RedrawWindow();
}
//-

/// CP0CommandLine
void CP0CommandLine(char *string)
{
   ASPrintf(NULL,lin_buf[2],"%s%-75.75s[33m ",printlines[2],string);
   RedrawWindow();
}
//-

/// CP1CommandLine
void CP1CommandLine(char *string)
{
   ASPrintf(NULL,lin_buf[3],"%s%-75.75s[33m ",printlines[3],string);
   RedrawWindow();
}
//-

/// CP2CommandLine
void CP2CommandLine(char *string)
{
   ASPrintf(NULL,lin_buf[4],"%s%-75.75s[33m ",printlines[4],string);
   RedrawWindow();
}
//-

/// CP3CommandLine
void CP3CommandLine(char *string)
{
   ASPrintf(NULL,lin_buf[5],"%s%-75.75s[33m ",printlines[5],string);
   RedrawWindow();
}
//-

/// StatCommandLine
void __stdargs StatCommandLine(char *string, ... )
{
   char  stline[256];

   XASPrintf(NULL, stline, string, (char *)(&string+1));
   ASPrintf(NULL,lin_buf[6],"%s%-75.75s[33m ", printlines[6], stline);
   RedrawWindow();
}
//-

/// InitGrid
int InitGrid(void)
{
   ConPutStr("[0m[H[J[?7l[0 p[>1l");
   return 0;
}
//-

/// InitLines
int InitLines(void)
{
   ConCommandLine("You clearly have too much time on your hands");
   InstCommandLine(" 8-) ");
   CP0CommandLine("Two bits, four bits,");
   CP1CommandLine("Eight bits, a peso!");
   CP2CommandLine("All who like Zorro,");
   CP3CommandLine("Stand up and say so!");
   StatCommandLine("");

   Delay(50);
   CP0CommandLine("");
   Delay(50);
   CP1CommandLine("");
   Delay(50);
   CP2CommandLine("");
   Delay(50);
   CP3CommandLine("");

   return(0);
}
//-

/// InitWindow
int InitWindow(void)
{
   strcpy(boundsreport,"1;1;11;83 r");
   InitGrid();
   InitLines();
   return 0;
}
//-

/// RedrawWindow
int RedrawWindow(void)
{
   int i;
   char *s;

   ConPutStr("[0m[H[?7l[0 p[>1l");

   for(i=0;i<7;i++)
   {
      s=strchr(lin_buf[i],'\n');
      if(s) *s=' ';
      ConPutStr(lin_buf[i]);
   }
   return 0;
}
//-

/// PrintConsoleCoProc
int PrintConsoleCoProc(char *x)
{
   char buf[30];
   char *s;
   int what;

   s=x;
   s=stpblk(s);
   s=stptok(s,buf,sizeof(buf)," ");
   s=stpblk(s);

   what=atoi(buf);
   if(what>-1 && what<5)
   {
      what+=2;
      ASPrintf(NULL,lin_buf[what],"%s%-75.75s[33m ",printlines[what],s);
      ConPutStr(lin_buf[what]);
   }

   if(*s)   Log(". Coproc %d: %.150s",what-2,s);

   return(0);
}
//-
