/*
** BBS ANSI support
**
 **********************************************************************/

#include "Include.h"

#define  NROW     24    // Screen size.
#define  NCOL     80    // Edit if you want to.
#define  NPAUSE   100   // # times thru update to pause
#define  MARGIN   8     // size of minimim margin and
#define  SCRSIZ   64    // scroll size for extended lines
#define  ESC      0x1B  // ESC character.

// Local functions

int STD ansimove(int, int);
int STD ansieeol(void);
int STD ansieeop(void);
int STD ansiopen(void);
int STD ansirev(int);
int STD ansiclose(void);
int STD ansidummy(void);
int STD ansicres(char *);
int STD ansiparm(int);
int STD ansifcol(int);
int STD ansibcol(int);

// this is extern-referenced in xenosepll.c
int cfcolor = -1; /* current forground color */
int cbcolor = -1; /* current background color */


/// term struct -- terminal interface dispatch table.  See Estruct.h
/*
** Standard terminal interface dispatch table. Most of the fields point into
** "termio" code.
 *****************************************************************************/
NOSHARE TERM term =
{
   NROW-1,
   NROW-1,
   NCOL,
   NCOL,
   0,
   0,
   MARGIN,
   SCRSIZ,
   NPAUSE,
   ansiopen,
   ansiclose,
   ansidummy,
   ansidummy,
   ttgetc,
   ttputc,
   ttflush,
   ansimove,
   ansieeol,
   ansieeop,
   ansieeop,
   NULL,
   ansirev,
   ansicres,
   ansifcol,
   ansibcol
};
//-

/// ttputs()
/***
**  ttputs  -  Send a string to ttputc
**
**  Nothing returned
 ***********************************************************************/
void STD ttputs(char *string)
{
   while (*string != '\0')
      ttputc(*string++);
}
//-

/// ansikey()
int STD ansikey(int f, int n)
{
    switch (ttgetc()) {
    case 'A':
   return backline(f, n);
    case 'B':
   return forwline(f, n);
    case 'C':
   return forwchar(f, n);
    case 'D':
   return backchar(f, n);
    case 'T':
   // shift-up
   return backpage(f, n);
    case 'S':
   // shift-down
   return forwpage(f, n);
    case ' ':
   switch (ttgetc()) {
   case 'A':
       // shift-left
       return gotobol(f, n);
   case '@':
       // shift-right
       return gotoeol(f, n);
   }
    }
    return FALSE;
}

//-

// Local functions

/// ansimove()
STD ansimove(row, col)
{
   ttputs("\033[");

   if (row || col)
   {
      ansiparm(row+1);
      ttputc(';');
      ansiparm(col+1);
   }

   ttputc('H');
   return(1);
}
//-

/// ansieeol()
STD ansieeol()
{
   ttputs("\033[K");
   return(1);
}
//-

/// ansieeop()
STD ansieeop()
{
   ansifcol(gfcolor);
   ansibcol(gbcolor);
   ttputs("\033[J");
   return(1);
}
//-

/// ansiopen()
STD ansiopen()
{
   ttopen();
   return(1);
}
//-

/// ansirev()
/*
** change reverse video state
**
** int state;  TRUE = reverse, FALSE = normal
 ***********************************************************/
STD ansirev(int state)
{
   int ftmp, btmp;      /* temporaries for colors */

   if (color_ok)
   {
      if (state == FALSE)
      {
         ftmp = cfcolor;
         btmp = cbcolor;
         cfcolor = -1;
         cbcolor = -1;
         ansifcol(ftmp);
         ansibcol(btmp);
      }
   }
   else
   {
      ttputc(ESC);
      ttputc('[');
      ttputc(state ? '7': '0');
      ttputc('m');
   }

   return(1);
}
//-

/// ansiclose()
STD ansiclose()
{
   cfcolor = -1;
   cbcolor = -1;
   ansifcol(7);
   ansibcol(0);
   ttputs("\033[H\033[J");
   ttclose();
   return(1);
}
//-

/// ansidummy()
/*
** a dummy function for ANSI code
 **************************************/
STD ansidummy()
{return(1);
}
//-

/// ansicres()
STD ansicres(char *n)
{
   return(TRUE);
}
//-

/// ansiparm()
STD ansiparm(register int n)
{
   ttputs(int_asc(n));
   return(1);
}
//-

/// ansifcol()
/*
** set the current output color
**
** int color;  color to set
 ************************************************/
STD ansifcol(int color)
{
   if (!color_ok) return(0);  // DLG monochrome

   if (color == cfcolor)   return(1);

   ttputs("\033[");
   if (color >= 8 && cfcolor < 8) {
      ttputs("1;");
   }
   else if (cfcolor >= 8 && color < 8)
   {
      ttputs("0;");
   }

   ansiparm((color%8)+30);
   ttputc('m');

   cfcolor = color;

   return(1);
}
//-

/// ansibcol()
/*
** set the current background color
**
** int color;  color to set
 *********************************************/
STD ansibcol(color)
{
   if (!color_ok) return(0);  // DLG monochrome

   if (color >= 8)
      color -= 8;
   if (color == cbcolor)
      return(1);

   ttputs("\033[");
   ansiparm(color+40);
   ttputc('m');
   cbcolor = color;

   return(1);
}
//-



