/*
 *	Universal Terminal Interface -- Printing of Text
 *
 *	(c) 1997 Martin Mares, <mj@ericsson.cz>
 */

#include "termint.h"

/* Current position of writing point */

int write_r, write_c, write_pos;
int ww_c0, ww_c1, ww_r0, ww_r1;
static byte *row_first, *row_last;

/* Specify `writing window' */

void
Trestrict(int r, int c, int h, int w)
{
  ww_r0 = r;
  ww_r1 = r + h - 1;
  ww_c0 = c;
  ww_c1 = c + w - 1;
  Tgoto(0,0);
}

void
Tunrestrict(void)
{
  Trestrict(0, 0, rows, columns);
}

/* Put a character */

inline void
Tputc(int c)
{
  cnew[write_pos] = c;
  anew[write_pos] = write_attrs;
  knew[write_pos] = write_color;
  if (*row_last < write_c)
    *row_last = write_c;
  write_pos++;
  write_c++;
}

/* Put a graphic character */

void
Tputg(int c)
{
  int a = write_attrs;

  write_attrs |= ATTR_ALTERNATE & supported_attrs;
  Tputc(gfx_chars[c]);
  write_attrs = a;
}

/* Put a string */

void
Tputs(const char *c)
{
  while (*c)
    Tputc(*c++);
}

/* Change writing position */

static void
internal_goto(int r, int c)
{
  write_r = r;
  write_c = c;
  if (write_r > ww_r1 || write_c > ww_c1 || write_r < ww_r0 || write_c < ww_c0)
    fatal_error("Tgoto(%d,%d) in window [%d,%d]--[%d,%d] is out of range",
		r, c, ww_r0, ww_c0, ww_r1, ww_c1);
  write_pos = write_r * columns + write_c;
  row_first = lfirst + write_r;
  row_last = llast + write_r;
  if (*row_first > write_c)
    *row_first = write_c;
  if (ltop > write_r)
    ltop = write_r;
  if (lbot < write_r)
    lbot = write_r;
}

void
Tgoto(int r, int c)
{
  internal_goto(ww_r0 + r, ww_c0 + c);
}

/* Put a character emulating a teletype */

void
Tputt(int i)
{
  if (i >= 32)
    {
      if (write_c > ww_c1)
	Tputt('\n');
      Tputc(i);
    }
  else switch (i)
    {
    case '\r':
      internal_goto(write_r, ww_c0);
      break;
    case '\n':
      if (write_r < ww_r1)
	internal_goto(write_r + 1, ww_c0);
      else
	{
	  Tscroll(0, 0, ww_r1-ww_r0+1, ww_c1-ww_c0+1, -1, 0);
	  internal_goto(ww_r1, ww_c0);
	}
      break;
    case '\t':
      do Tputt(' '); while ((write_c - ww_c0) & 7);
      break;
    case '\010':
      internal_goto(write_r, --write_c);
      Tputc(' ');
      internal_goto(write_r, --write_c);
      break;
    }
}
