
#include "vt.h"
#include <ctype.h>
#include <memory.h>

// All locations are in cursor coordinates, that is 1..n.  0 indexs ignored.

//
// --------  Hardcopy_from_VT100barton ---------
// Hardcopy_from_VT100 customized for BARTON.
// Recognizes the use of spaces to clear lower lines of screen, 
// and ignores them, as they are superfluous with a hardcopy terminal.
//


void Hardcopy_from_VT100barton::insert (char c)
{
  if(c==' ') { if(maybe_doing_clearing_wsp) return; }
  else maybe_doing_clearing_wsp =0;

  return Hardcopy_from_VT100::insert(c);
}

void Hardcopy_from_VT100barton::CUP (int x, int y)
{
  if(x >=23) maybe_doing_clearing_wsp =1;
  else      maybe_doing_clearing_wsp =0;
  return Hardcopy_from_VT100::CUP(x,y);
}

//
// --------- Hardcopy_from_VT100 ----------
//

char iw_buf[1000];
int Hardcopy_from_VT100::IncrementalWrite (char* buf, int nchars)
{
  int ccount =0;
  strncpy(iw_buf,buf,nchars);
  for(int i=0;i<nchars;i++) {
    int res = write(&iw_buf[i],1);
    if(res==-1) return -1;
    ccount ++;
  }
  return ccount;
}
int Hardcopy_from_VT100::write (char* buf, int nchars)
{
  if(nchars>1) return IncrementalWrite(buf,nchars);
  if(nchars<0) return 0;
  
  int c = buf[0];

  switch ( filter_escapeCodes(c) )
    {
    case c_InCode:                            return 1;
    case c_NotCode: insert(c); flush();       return 1;
    case c_ED:      ED(VTArg[0]);              return 1;
    case c_EL:      EL(VTArg[0]);              return 1;
    case c_CUP: if(VTArgn==2) CUP(VTArg[0],VTArg[1]);
                else          CUP(VTArg[0],CurH);
                                               return 1;
    default:                                   return 1;
    }
}


void Hardcopy_from_VT100::initialize ()
{
  ED(2);
  CUP(1,1);
}

void Hardcopy_from_VT100::CUP (int x, int y)
{
  if(x<1||x>25||y<1||y>80) return;
  CurV=x;
  CurH=y;
}

void Hardcopy_from_VT100::ED (int n)
{
  int r;
  char *p;

  switch(n) {
  case 0:
    { p = &scr[CurV][CurH];
      r = (25-CurV)*81+(80-CurH)+1;
      memset(p,' ',r); }
    break;
  case 1:
    { p = (char*) scr;
      r = (CurV)*81+(CurH+1);
      memset(p,' ',r); }
    break;
  case 2:
    { p = (char*) scr;
      r = 26*81;
      memset(p,' ',r); }
    { if(!(CurH==1&&CurV==1))
	printf("\n\n"); }
    break;
  default: ;
  }
  flush();
}
void Hardcopy_from_VT100::EL (int n)
{
    switch(VTArg[0]) {
    case 0: memset(&scr[CurV][CurH],' ',(80-CurH)+1);
      break;
    case 1: memset(&scr[CurV][1],' ',CurH);
      printf("\n"); for(int i=0;i<CurH;i++) printf(" ");
      break;
    case 2: memset(&scr[CurV][1],' ',80);
      printf("\n");
      break;
    default: ;
    }
    flush();
}
void Hardcopy_from_VT100::scroll_up ()
{
  for(int v=1;v<=24;v++)
    for(int h=1;h<=80;h++) scr[v][h] = scr[v+1][h];
  CurV --;
  if(CurV <1) CurV =1;
}

void Hardcopy_from_VT100::insert (char c)
{
  int prevc = nlcr_check_char;
  nlcr_check_char = c;

  move_to(CurV,CurH);

  if(!isspace(c) || c==' ')
    {
      char oldc = scr[CurV][CurH];
      scr[CurV][CurH] = c;
      printf("%c",c);
      CurH++;
    }
  else if(c=='\n'|| c=='\r')
    {
      if((c=='\r' && prevc=='\n') ||
	 (c=='\n' && prevc=='\r'))
	{
	  nlcr_check_char = 'x';
	  return;
	}
      EL(0);
      CurV++;
      CurH = 1;
      printf("%c",c);
    }

  if(CurH>80) {
    CurH = 80;
    // CurH = 1; CurV++;
  }
  if(CurV>25) { scroll_up(); }
  nextV = CurV;
  nextH = CurH;
}

void Hardcopy_from_VT100::move_to(int CurV,int CurH)
{
  if(CurV == nextV && CurH > nextH ) {
    for(int h=nextH;h<CurH;h++) putchar(' ');
  }
  if(CurV < nextV  || ( CurV==nextV && CurH < nextH ) ) {
    printf("\n");
    for(int i=1;i<CurH;i++) putchar(' ');
  }
  if(CurV > nextV) {
    for(int v=nextV;v<CurV;v++) printf("\n");
    for(int h=1;h<CurH;h++) putchar(' ');
  }
}

void Hardcopy_from_VT100::flush()
{
  fflush(stdout);
}

void Hardcopy_from_VT100::refresh()
{
  printf("\n");
  for(int v=1; v<=25; v++) printf("%80s\n",&scr[v][1]);
  printf("\n");
}
