/* term.c */
     
/**********************************************************************
 * Terminal I/O for the CBBS program.
 *
 * Pete VE5VA
 **********************************************************************/
#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <stdio.h>
#include <ctype.h>
#include "amiga.h"
#define INTUITION_REV 1L
     
     
struct IntuitionBase *IntuitionBase = 0L;
struct IntuiMessage *NewMessage = 0L;
extern char tmpstr[];     
extern char optflags[];     
extern int debug;
long readbit,windbit,keybit;
struct TextAttr TextFont = {
   (UBYTE *)"topaz.font",
   8,0,0
};
     
struct IOStdReq *Con_Read = 0L,*Con_Write = 0L;
     
     
/* my window structure */
struct NewWindow NewWindow = {
   0,
   0,
   640,
   256,
   0,
   1,

   /* IDCMPFlags */
   0L
   | IDCMP_MOUSEBUTTONS
   | IDCMP_CLOSEWINDOW
   ,

   /* Flags */  
   0L
   | WFLG_ACTIVATE
   | WFLG_BORDERLESS
   | WFLG_DEPTHGADGET
/*   | WFLG_SIZEGADGET  */
/*   | WFLG_DRAGBAR    */
   | WFLG_CLOSEGADGET
   | WFLG_SMART_REFRESH
   | WFLG_RMBTRAP
   ,

   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   350,50,
   640,256,
   WBENCHSCREEN
};
     
     
struct Window *mywindow = 0L;             /* ptr to applications window */
struct RastPort *rp;
struct ViewPort *vp;
short mouse = 0;               /* If mouse set then open mouse too */
struct MsgPort *crp,*cwp;
     
unsigned char ichar;
#define NEW      1006L
#define AMG_MAXBUF   1024
static unsigned char scrn_tmp[AMG_MAXBUF+1];
static long      scrn_tmp_p = 0L;
short od = 0;     /* device is open so it can be closed */
openterm()
{
   long i;
     
   short id;
   register unsigned short *p,*q;
   register int j,k;
   IntuitionBase = (struct IntuitionBase *)
                    OpenLibrary((UBYTE *)"intuition.library", INTUITION_REV);
   if( IntuitionBase == NULL ) {
      puts("can't open intuition\n");
      return(1);
   }
   if(optflags[3] == 0) {
      /* Option to add window border and allow resizing of the window
      */
      NewWindow.Flags &= ~WFLG_BORDERLESS;
      NewWindow.Flags |= (WFLG_SIZEGADGET | WFLG_DRAGBAR);
   }
   if(optflags[5] == 0) {
      /* Option to remove the title bar etc. */
      NewWindow.IDCMPFlags &= ~IDCMP_CLOSEWINDOW;
      NewWindow.Flags &= ~ (WFLG_DEPTHGADGET | WFLG_CLOSEGADGET);
   }
   /* Start by trying to open a full-size European window.
      If that fails, try the North American one.
   */
   if(( mywindow = OpenWindow(&NewWindow) ) == NULL) {
      NewWindow.Height = 200;
      if(( mywindow = OpenWindow(&NewWindow) ) == NULL) {
         printf("cant open window\n");
         return(1);
      }
   }
   rp = mywindow->RPort;
   vp = &mywindow->WScreen->ViewPort;
   crp = CreatePort(0L,0L);
   if(crp == 0L) {
      printf("can't create console read port\n");
      closeterm();
      return(1);
   }
   cwp = CreatePort(0L,0L);
   if(cwp == 0L) {
      printf("can't create console write port\n");
      closeterm();
      return(1);
   }
   Con_Read = CreateStdIO(crp);
   if(Con_Read == 0L) {
      printf("can't create stdio read port\n");
      closeterm();
      return(1);
   }
   Con_Write = CreateStdIO(cwp);
   if(Con_Write == 0L) {
      printf("can't create stdio write port\n");
      closeterm();
      return(1);
   }
     
   Con_Read->io_Data = (APTR)mywindow;
   Con_Read->io_Length = (long)sizeof(*mywindow);
   if(OpenDevice((UBYTE *)"console.device",0L,
                              (struct IORequest *)Con_Read,0L)) {
      i = IoErr();
      printf("OpenDevice failed %ld\n",i);
      closeterm();
      return(1);
   }
   Con_Write->io_Device = Con_Read->io_Device;
   Con_Write->io_Unit = Con_Read->io_Unit;
   od = 1;

   windbit = (1L << mywindow->UserPort->mp_SigBit);

   keybit  = (1L << crp->mp_SigBit);
   Con_Read->io_Data = (APTR)&ichar;
   Con_Read->io_Command = CMD_READ;
   Con_Read->io_Length = 1;
   SendIO((struct IORequest *)Con_Read);
   cursor_off();
   window_title(0,0);
   return(0);
}
     
closeterm()
{
   if(od)CloseDevice((struct IORequest *)Con_Read);
   if(Con_Read)DeleteStdIO(Con_Read);
   if(crp)DeletePort(crp);
   if(Con_Write)DeleteStdIO(Con_Write);
   if(cwp)DeletePort(cwp);
   if(mywindow)CloseWindow(mywindow);
   if(IntuitionBase)CloseLibrary((struct Library *)IntuitionBase);
   od = 0;
   Con_Read = Con_Write = (struct IOStdReq *) 0L;
   crp = cwp = (struct MsgPort *) 0L;
   mywindow = 0;
   IntuitionBase = 0;
   windbit = keybit = 0L;
}
     
     
ttputc(c)
unsigned char c;
{
   if(c > 0177)return;
   if(c == 7) {   /* beep char ... sound the beep and let it flash screen */
      initbeep();
      beep();
      donebeep();
   }
   /* Remove a return char. The original IBM code outchar()
      will not send us a return char anyway but some of my stuff might.
   */
   if(c == '\r')return;
   /* Don't permit Control-N */
   if(c != ('N' - 0100))
      scrn_tmp[scrn_tmp_p++] = c;
   ttflush();
     
}
ttputs(s)
unsigned char   *s;
{
   if(od == 0)return;
   while (*s) {
      if(*s > 0177) {
         s++;
         continue;
      }
      if(*s == 7) {   /* beep char */
         initbeep();
         beep();
         donebeep();
      }
      /* Remove a return char. The original IBM code
         outstr() will not send us a return char anyway but some of
         my stuff might.
      */
      if(*s == '\r') continue;
      /* Don't permit Control-N */
      if(*s != ('N' - 0100))
         scrn_tmp[scrn_tmp_p++] = *s++;
   }
   ttflush();
}
/*
FILE *deb_out = 0L;     
*/
ttflush()
{
   if(od == 0)return;
   if(scrn_tmp_p) {
      Con_Write->io_Data = (APTR) scrn_tmp;
      Con_Write->io_Length = scrn_tmp_p;
      Con_Write->io_Command = CMD_WRITE;
      DoIO((struct IORequest *)Con_Write);
/*
      if(deb_out == 0) {
         deb_out = fopen("ram:cbbs.debug","w");
      }
      fwrite(scrn_tmp,scrn_tmp_p,1L,deb_out);
*/
   }
   scrn_tmp_p = 0;
}
cleanup()
{
   cleanser();
   closeterm();
/*
   fclose(deb_out);
*/
}
/* Remember the previous state of the cursor */
char cur_state;
cursor_off()
{
   if(cur_state > 0) {
      if(--cur_state)return;
   }
   ttputs("\033[\060\040p");
   cur_state = 0;
}
cursor_on()
{
   cur_state++;
   ttputs("\033[\040p");
}
/* Change the window dimensions BEFORE opening it */
setwindow(l,t,w,h)
short l,t,w,h;
{
   NewWindow.LeftEdge = l;
   NewWindow.TopEdge  = t;
   NewWindow.Width    = w;
   NewWindow.Height   = h;
}
/* This is only in here to save version.c having to #include lots of
   files that make it slow to compile
*/
setwtitles(s)
char *s;
{
   SetWindowTitles(mywindow,(UBYTE *)s,(UBYTE *)-1L);
}
