/* This file is part of the origami distrubution. (Amiga Port)
 *
 * Source code written by Thomas Hadig in September 1991
 * Version : 1.6.92.1, February 1994
 * (C) 1991-94 by Thomas Hadig
 * may be distributed unchanged ! (see copyright notes)
 */

#define CALC_Y(y) off_y+off_y_base+3+mul_y*y

/*{{{}}}*/
/*{{{  #includes*/
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

#include <intuition/intuition.h>
#include <graphics/text.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>

#define SCREEN_C
#define I_DISPLAY_C
#define I_KEYBOARD_C
#define I_LOOP_C

#include <origami/origami.h>

#include <sprof.h>
/*}}}  */

/*{{{  variables*/
extern BPTR _Backstdout;

private boolean screenon=True;
public boolean aktinvers=False;
private struct IntuiText it =
  {1, 0, JAM1, 0, 0, 0L /* ROM_FONT */, 0L, 0L };
private int csr_x=0,csr_y=0;

public int sg=0;
public win_data screen;
public char *al=(char *)0,*dl=(char *)0, *ce=(char *)0;
public boolean xs=False,am=False,mi=False, hz=False, xt=False;
public char *so=".",*se=".", *terminal=(char *)0;

public struct line_store myline = { 0,0, 0, (char *)0, 0, 0 };
/*}}}  */

public void scr_cursor(boolean);

/*{{{  ClearRect*/
private void ClearRect (int x,int y, int s, int t)
 {
  if ((s>x)&&(t>y))
   {
    SetDrMd (rp,JAM1);
    SetAPen (rp,0L);
    PROFILE_OFF();
    RectFill (rp,x,y,s,t);
    PROFILE_ON();
   }
 }
/*}}}  */
/*{{{  one line flush routines*/
/*{{{  PrintOnePart*/
private void PrintOnePart (int x, int y, char *ptr, int len, boolean inv)
 {
  scr_cursor(False);
  ClearRect (Off_X+x*mul_x,off_y+y*mul_y+3,
    Off_X+(x+len)*mul_x-1,off_y+y*mul_y+2+mul_y);
  if (inv!=False) SetDrMd (rp, JAM2 | INVERSVID);
  SetAPen (rp,1L);
  Move (rp,Off_X+mul_x*x,CALC_Y(y));
  Text (rp,ptr,len);
 }
/*}}}  */
/*{{{  FlushOneLine*/
public void FlushOneLine (void)
 {
  if (!myline.len) return;
  PrintOnePart (myline.x, myline.y, myline.str, myline.len, aktinvers);
  myline.len = 0;
 }
/*}}}  */
/*{{{  TestCoor*/
public int TestCoor (int x, int y, boolean always)
 {
  if (!myline.str) exit (42);
  if (myline.len)
   {
    if ((csr_y!=myline.y)||(csr_x!=myline.x+myline.len)||always)
      FlushOneLine();
    else
      return myline.len;
   }
  myline.x = x;
  myline.y = y;
  return myline.len = 0;
 }
/*}}}  */
/*{{{  AddChar*/
private void AddChar (char ch)
 {
  myline.str[TestCoor(csr_x,csr_y,False)]=ch;
  myline.len++;
 }
/*}}}  */
/*{{{  AddString*/
private void AddString (char *ptr, int len)
 {
  int i;

  strncpy (myline.str+TestCoor(csr_x,csr_y,False), ptr,
    i = (len < myline.maxlen-myline.len ? len : myline.maxlen-myline.len ));
  myline.len += i;
 }
/*}}}  */
/*}}}  */

/*{{{  get_terminal_capability*/
public int get_terminal_capability(void)
 {
  int w=screen.w;

  /*{{{  get terminal*/
  if (!terminal)
    if (!(terminal=getenv("TERM"))) terminal="AMIGA";
  /*}}}  */
  screen.w = (wind->Width-Off_X_Right-4)/mul_x;
  screen.h = (wind->Height-off_y-Off_Y_Bottom-2)/mul_y;
  /*{{{  clear right border*/
  if ((screen.w != w)&&rp)
    ClearRect (Off_X+mul_x*screen.w,off_y+3,
      wind->Width-Off_X_Right,wind->Height-Off_Y_Bottom);
  /*}}}  */
  /*{{{  get buffer for one line flush*/
  if ((myline.str)&&(screen.w>myline.maxlen))
   /*{{{  flush and delete buffer*/
   {
    FlushOneLine();
    free (myline.str);
    myline.str=(char *)0;
   }
   /*}}}  */
  if (!myline.str)
   /*{{{  malloc buffer*/
   {
    if (!(myline.str = (char *)malloc (
        myline.maxlen = (screen.w>256 ? screen.w : 256))))
      exit (43);
   }
   /*}}}  */
  /*}}}  */
  return (0);
 }
/*}}}  */

/*{{{  pos_x*/
private long pos_x (void)
 {
  return (min (Off_X+mul_x*csr_x,wind->Width-mul_x));
 }
/*}}}  */
/*{{{  pos_y*/
private long pos_y (void)
 {
  return (min (CALC_Y(csr_y),wind->Height-1));
 }
/*}}}  */

/*{{{  scr_cursor*/
public void scr_cursor(boolean show)
 {
  static int cx,cy;
  static boolean cursor_on;

  if (cursor_on == show)
   {
    if (cursor_on==False) return;
    if ((pos_x()==cx)&&(pos_y()==cy)) return;
    scr_cursor (False);
   }
  if (cursor_on==False)
   {
    cx = pos_x();
    cy = pos_y();
    cursor_on = True;
   }
  else cursor_on = False;
  Move (rp,cx,cy);
  SetAPen (rp,1L);
  SetDrMd (rp,JAM1 | INVERSVID | COMPLEMENT);
  Text (rp," ",1);
 }
/*}}}  */

/*{{{  Print*/
private void Print (char *ptr)
 {
  char *optr=ptr;

  if (screenon!=True) return;
  while (*ptr)
   {
    /*{{{  search \n or \000*/
    while ((*ptr)&&(*ptr!='\n')) ptr++;
    /*}}}  */
    AddString (optr, ptr-optr);
    /*{{{  Calc new Cursor Position*/
    if (*ptr=='\n')
     /*{{{  new cursor pos in next line*/
     {
      ptr++;
      csr_y++;
      csr_x=0;
     }
     /*}}}  */
    else csr_x+= (ptr-optr);
    /*}}}  */
   }
 }
/*}}}  */
/*{{{  oputc : Needed by send_terminal and a define*/
public int oputc (char ch)
 {
  if (ch!='\n')
   /*{{{  print one character*/
   {
    AddChar (ch);
    csr_x++;
   }
   /*}}}  */
  else
   /*{{{  set cursor in next line*/
   {
    csr_y++;
    csr_x=0;
   }
   /*}}}  */
  return (int)ch;
 }
/*}}}  */

/*{{{  move_cursor_to*/
public int move_cursor_to(int y,int x)
 {
  if (x>0) csr_x = x-1; else csr_x = 0;
  if (y<=0) csr_y=0;
  else if (y>screen.h) csr_y = screen.h;
  else csr_y = y-1;
  return 0;
 }
/*}}}  */
/*{{{  ins & del line (not defined)*/
/*{{{  insLine*/
public boolean insLine(int n) { return True; }
/*}}}  */
/*{{{  DelLine*/
public boolean DelLine (int n) { return True; }
/*}}}  */
/*}}}  */
/*{{{  init & rest terminals*/
/*{{{  init_terminal*/
public void init_terminal(void) { SetBPen (rp,0L); }
/*}}}  */
/*{{{  reset_terminal*/
public void reset_terminal(void) {}
/*}}}  */
/*}}}  */
/*{{{  stand out & end*/
/*{{{  standout*/
public void do_standout(void)
 {
  FlushOneLine();
  aktinvers = True;
 }
/*}}}  */
/*{{{  standend*/
public void do_standend(void)
 {
  FlushOneLine();
  aktinvers = False;
 }
/*}}}  */
/*}}}  */
/*{{{  moveclreol: go to xy and do clreol*/
public void moveclreol(int y,int x)
 {
  move_cursor_to (y,x);
  ClearRect (Off_X+csr_x*mul_x,off_y+mul_y*csr_y+3,
    wind->Width-Off_X_Right,off_y+mul_y*csr_y+2+mul_y);
 }
/*}}}  */
/*{{{  ClrScr*/
public void ClrScr (void)
 {
  ClearRect (Off_X,off_y+3,
     wind->Width-Off_X_Right,wind->Height-Off_Y_Bottom);
  myline.len=0;
 }
/*}}}  */
/*{{{  bell*/
public void bell_visible (void) { DisplayBeep (beep_screen); }
public void bell_audible (void) {}
/*}}}  */
/*{{{  terminal functions*/
/*{{{  send_terminal*/
public void send_terminal (int ch) { oputc ((char)ch); }
/*}}}  */
/*{{{  flush_terminal*/
public void flush_terminal(void) {}
/*}}}  */
/*{{{  check_terminal*/
public boolean check_terminal(char *t) { return(!strcmp(t,terminal)); }
/*}}}  */
/*}}}  */
/*{{{  screen on & off*/
/*{{{  screen_off*/
public void screen_off(void) { screenon=False; }
/*}}}  */
/*{{{  screen_on*/
public void screen_on(void) { screenon=True; }
/*}}}  */
/*}}}  */

/*{{{  eputs*/
public int eputs (const unsigned char *ptr)
 {
  if (_Backstdout&&(!(init_wind&0x02))) Write (_Backstdout,ptr,strlen(ptr));
  else if (init_wind&0x01) Print (ptr);
  return 0;
 }
/*}}}  */
/*{{{  eputc*/
public int eputc (const unsigned char ch)
 {
  if ((_Backstdout)&&(!(init_wind&0x02))) Write (_Backstdout,&ch,1);
  else if (init_wind&0x01) oputc(ch);
  return 0;
 }
/*}}}  */
