/*---------------------------------------------------------------
 *  vtxxx.c - ecurses driver module for DEC VT100, VT102, VT220,
 *                                      VT320
 *  Author: Frank Meyer
 *  (c) Copyright 1992 textware GmbH Koeln
 *-------------------------------------------------------------*/

#include <ecurses.h>
#include "private.h"

#define STANDOUT_ATTRS      (A_BOLD) /*   use BOLD on vtxxx    */

static int oldy         = -1;
static int oldx         = -1;
static int phys_attrs   = -1;

VT_move ()
{
    int y = stdscr->cury;
    int x = stdscr->curx;
    chtype ** scr_ptr = stdscr->image;

    if (y >= LINES)                 /* y out of range ?         */
    {                               /* yes, correct y...        */
        y = LINES - 1;
        oldy = -1;                  /* mark: old y undefined    */
    }
    if (x >= COLS)                  /* x out of range ?         */
    {                               /* yes, correct x...        */
        x = COLS - 1;
        oldx = -1;                  /* mark: old x undefined    */
    }

    if (oldy == y)                  /* same line ?              */
    {                               /* yes ...                  */
        if (oldx == x)              /* same column ?            */
        {                           /* it's the old position !  */
            return (OK);            /* so return !              */
        }
        if (x == 0)                 /* to beginning of line?    */
        {
            fputc ('\r', stdout);   /* simply send CR           */

            oldx = 0;               /* update position          */
            return (OK);
        }
        if (oldx > x)               /* move left some chars ?   */
        {
            if (oldx == x + 1)      /* simply move left ?       */
            {                       /* yes, do it               */
                fputc ('\b', stdout);
                oldx--;             /* update position          */
                return (OK);
            }
            printf ("\033[%dD", oldx - x);
            oldx = x;
            return (OK);
        }
        if (oldx == x - 1)          /* simply move right ?      */
        {                           /* yes, do it               */
            oldx++;                 /* update position          */
                                    /* before call of addch() ! */
            if (*(scr_ptr[y] + oldx) == 0)
            {
                addch (' ');
            }
            else
            {
                addch (*(scr_ptr[y] + oldx));
            }
            return (OK);
        }
        printf ("\033[%dC", x - oldx); /* move right some chars */
        oldx = x;
        return (OK);
    }

    if (oldx == x)                     /* same column ?         */
    {
        if (oldy < y)                  /* some lines down ?     */
        {
            if (oldy + 1 == y)         /* simply down ?         */
            {                          /* yes, do it            */
                fputs ("\033[B", stdout);
                oldy++;                /* update position       */
                return (OK);
            }
            printf ("\033[%dB", y - oldy);
            oldy = y;
            return (OK);
        }
        if (oldy - 1 == y)             /* simply up ?           */
        {                              /* yes, do it            */
            fputs ("\033[A", stdout);
            oldy--;                    /* update position       */
            return (OK);
        }
        printf ("\033[%dA", oldy - y); /* move some lines up    */
        oldy = y;
        return (OK);
    }
    if (y == 0 && x == 0)              /* HOME position ?       */
    {                                  /* yes !                 */
        fputs ("\033[H", stdout);
        oldx = 0;
        oldy = 0;                      /* update positions      */
        return (OK);
    }

    printf ("\033[%d;%dH", y + 1, x + 1);

    oldx = x;
    oldy = y;                          /* and update positions  */
    return (OK);
} /* VT_move () */


static int
VT_attrset (additional_attrs)
int additional_attrs;
{
    static char attr_buf[20];
    int real_attrs;

    real_attrs = stdscr->attrs | additional_attrs;

    if (phys_attrs != real_attrs)
    {
        if (real_attrs & A_STANDOUT)
        {
            real_attrs |= STANDOUT_ATTRS;
        }
        (void) strcpy (attr_buf, "\033[0");
        if (real_attrs & A_UNDERLINE)
        {
            (void) strcat (attr_buf, ";4");
        }
        if (real_attrs & A_REVERSE)
        {
            (void) strcat (attr_buf, ";7");
        }
        if (real_attrs & A_BLINK)
        {
            (void) strcat (attr_buf, ";5");
        }
        if (real_attrs & A_BOLD)
        {
            (void) strcat (attr_buf, ";1");
        }
        if (real_attrs & A_DIM)
        {
            (void) strcat (attr_buf, ";2");
        }

        (void) strcat (attr_buf, "m");
        fputs (attr_buf, stdout);
        phys_attrs = real_attrs;
    }
    return (OK);
} /* VT_attrset (additional_attrs) */


static int
VT_clear ()
{
  fputs ("\033[2J", stdout);
  oldy = -1;                /* mark: positions destroyed */
  oldx = -1;
  return (OK);
} /* VT_clear () */


static int
VT_endwin ()
{
  move (LINES - 1, 0);
  VT_move ();
  return (TT_endwin ());
} /* VT_endwin () */


int
VT_initscr (emul)
char * emul;
{
  endwin_func  = VT_endwin;
  move_func    = VT_move;
  attrset_func = VT_attrset;
  clear_func   = VT_clear;

  getch_func   = TT_getch;
  addch_func   = TT_addch;
  raw_func     = TT_raw;
  noraw_func   = TT_noraw;
  echo_func    = TT_echo;
  noecho_func  = TT_noecho;

  LINES = 24;
  COLS = 80;

  return (TT_initscr ());               /* initialize TTY */
} /* VT_initscr (emul) */

/* end of vtxxx.c */
