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

#define CALC_Y(y) Off_Y+Mul_Y*(y)-(Mul_Y+2)/4

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

#include <local/bool.h>

#include <intuition/intuition.h>
#include <graphics/text.h>
#ifdef LATTICE
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#else
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#endif

#define SCREEN_C
#define I_DISPLAY_C
#define I_KEYBOARD_C

#include "origami.h"
/*}}}  */

/*{{{  variables*/
extern struct Window *wind;
extern struct RastPort *rp;
extern bool os20q;
bool screenon=TRUE;

struct IntuiText it = {1, 0, JAM1, 0, 0, NULL /* ROM_FONT */,
                               NULL, NULL };

int screen_lines,screen_columns,csr_x=1,csr_y=1,sg=0;
int sx_ptr,sy_ptr,cy_ptr;
bool cursor_on = FALSE,ok_pos = FALSE;
bool aktinvers=0, num_key_pad = TRUE,xs;

char *so=".",*se=".";
char textscreen[Max_Y][Max_X+1],invers[Max_Y][Max_X+1];
/*}}}  */

/*{{{  get_terminal_capability*/
int get_terminal_capability(void)

 {
#  ifdef OSall
  if (os20q)
#  endif
#  ifdef OS20
   {
    W_dx = screen_columns = min(((wind->Width-Off_X-Off_X_Right)/Mul_X)-1,
      Max_X)-1;
   }
#  endif
#  ifdef OSall
  else
#  endif
#  ifdef OS13
   {
    W_dx = screen_columns = min((wind->Width-Off_X-Off_X_Right)/Mul_X,
      Max_X)-1;
   }
#  endif
  screen_lines = min((wind->Height-Off_Y-Off_Y_Bottom)/Mul_Y,Max_Y);
  return (0);
 }
/*}}}  */
/*{{{  pos_x*/
SHORT pos_x (void)

 {
  if (csr_x<1) csr_x=1;
  return Off_X+Mul_X*csr_x;
 }
/*}}}  */
/*{{{  pos_y*/
SHORT pos_y (void)

 {
  SHORT y;

  get_terminal_capability();
  if (csr_y>screen_lines) csr_y = screen_lines;
  if (csr_y<1) csr_y=1;
  y = CALC_Y(csr_y);
  if (csr_y==MESSAGE_LINE) y++;
  return min (y,wind->Height-1);
 }
/*}}}  */
/*{{{  check_pos*/
bool check_pos (void)

 {
#  ifdef OSall
  if (os20q)
   {
#  endif
#  ifdef OS20
    if ((pos_x()<wind->Width-Mul_X)&&(pos_y()<wind->Height)) return TRUE;
#  endif
#  ifdef OSall
   }
  else
   {
#  endif
#  ifdef OS13
    if ((pos_x()<wind->Width)&&(pos_y()<wind->Height)) return TRUE;
#  endif
#  ifdef OSall
   }
#  endif
  return FALSE;
 }
/*}}}  */
/*{{{  Move to pos*/
void move_to_pos(void)

 {
  if (ok_pos = check_pos ()) Move (rp,pos_x(),pos_y());
  SetAPen (rp,1L);
 }
/*}}}  */
/*{{{  Display_one_line*/
void Dis1Line(int x,int y, int len)
{
  int ai,l=0,ol=0;

  if (x<1) x=1;
  while (l<len)
  {
    ai=invers[y][x+ol-1];
    while ((l<len) && (invers[y][x+l-1]==ai)) l++;
    Move (rp,Off_X+Mul_X*(x+ol),CALC_Y(y));
    if (ai) SetDrMd (rp, JAM2 | INVERSVID);
    else SetDrMd (rp, JAM2 );
    Text (rp,&textscreen[y][x+ol-1],l-ol);
    ol = l;
  }
}
/*}}}  */

/*{{{  Set_Cursor*/
void Set_Cursor(void)

 {
  char buffer;

  if (!(buffer=textscreen[csr_y][csr_x-1])) buffer=' ';
  SetDrMd (rp,JAM2 | INVERSVID | COMPLEMENT);
  if (check_pos()) Text (rp,&buffer,1);
  move_to_pos();
  cursor_on = TRUE;
 }
/*}}}  */
/*{{{  Clear_Cursor*/
void Clear_Cursor(void)

 {
  char buffer;

  if (!(buffer=textscreen[csr_y][csr_x-1])) buffer=' ';
  if (invers[csr_y][csr_x-1]) SetDrMd (rp,JAM2 | INVERSVID);
  else SetDrMd (rp,JAM2);
  if (check_pos()) Text (rp, &buffer,1);
  cursor_on = FALSE;
 }
/*}}}  */
/*{{{  Print*/
void Print (char *ptr)

 {
  char line[100];
  int  i=0,j;
#  if 0
  bool backspace=FALSE;
#  endif

  if (screenon)
   {
    if (cursor_on) Clear_Cursor();
    while (ptr[i])
     {
      j=0;
      while ((ptr[i])&&(ptr[i]!='\n')&&(j<screen_columns-csr_x+1))
        line[j++]=ptr[i++];
      line[j]=0x00;
      while (j>0)
      {
        textscreen[csr_y][--j+csr_x-1]=line[j];
        invers[csr_y][j+csr_x-1]=aktinvers;
      }
      j=csr_x;
      while (j>=0)
      {
        if (textscreen[csr_y][--j]==0)
        {
          textscreen[csr_y][j]=0x20;
          invers[csr_y][j]=0;
        }
      }
      while ((ptr[i])&&(ptr[i]!='\n')) i++;
      SetAPen (rp,1L);
      if (check_pos()) Dis1Line (csr_x,csr_y,strlen(line));
      if (ptr[i]=='\n')
       {
        i++;
        csr_y++;
        csr_x=1;
       }

      else
#      if 0
      if (!backspace)
#      endif
        csr_x+=strlen(line);
      move_to_pos();
     }
   }
 }
/*}}}  */
/*{{{  oputc*/
int oputc (char ch)

 {
  char putchar_buffer[2] = {0,0};

  putchar_buffer[0]=ch;
  Print (putchar_buffer);
  return (int)ch;
 }
/*}}}  */

/*{{{  gotoxy*/
int gotoxy(int x,int y)

 {
  if (cursor_on) Clear_Cursor();
  csr_x = x;
  csr_y = y;
  move_to_pos ();
  return 0;
 }
/*}}}  */
/*{{{  clreol*/
int clreol(void)
 {
  int i;

  if (cursor_on) Clear_Cursor ();
  SetAPen (rp,0L);
  SetBPen (rp,0L);
  SetDrMd (rp,JAM1);
  if ((Off_X+Mul_X*csr_x<wind->Width-Off_X-Off_X_Right)
      &&(Off_Y+(csr_y-1)*Mul_Y<pos_y()+1))
  {
    RectFill (rp,
      Off_X+Mul_X*csr_x,Off_Y+(csr_y-1)*Mul_Y,
      wind->Width-Off_X-Off_X_Right,Off_Y+csr_y*Mul_Y);
    for (i=csr_x-1; i<=screen_columns;
      invers[csr_y][i]=textscreen[csr_y][i++]=0);
  }
  return 0;
}
/*}}}  */
/*{{{  goclreol: go to xy and do clreol*/
public void goclreol(int x,int y)
{ gotoxy(x,y);
  clreol ();
}
/*}}}  */
/*{{{  ClrFullScr*/
int ClrFullScr(void)
{
  int i,j;

  clreol();
  if (Off_Y+csr_y*Mul_Y<wind->Height-Off_Y_Bottom)
   {
    RectFill (rp,Off_X+Mul_X,Off_Y+Mul_Y*csr_y,
       wind->Width-Off_X-Off_X_Right,wind->Height-Off_Y_Bottom);
    for (i=csr_y+1; i<screen_lines;i++)
    {
      for (j=0;j<=screen_columns; invers[i][j]=textscreen[i][j++]=0);
    }
  }
  return 0;
}
/*}}}  */
/*{{{  ClrScr*/
void ClrScr (void)

 {
  int i,j;

  SetAPen (rp,0L);
  SetBPen (rp,0L);
  SetDrMd (rp,JAM1);
  if ((rp,2*Off_X+Mul_X<wind->Width-Off_X_Right)
      &&(Off_Y<wind->Height-Off_Y_Bottom))
  {
    RectFill (rp,Off_X+Mul_X,Off_Y,
      wind->Width-Off_X-Off_X_Right,wind->Height-Off_Y_Bottom);
  }
  get_terminal_capability();
  for (i=1; i<screen_lines;i++)
   {
    for (j=0;j<=screen_columns; invers[i][j]=textscreen[i][j++]=0);
   }
  csr_y = csr_x = 1;
  move_to_pos();
 }
/*}}}  */
/*{{{  re_displ*/
void re_displ (int y)

 {
  int i;

  if (y<screen_lines)
   {
    SetAPen (rp,0L);
    SetDrMd (rp,JAM1);
    RectFill (rp,Off_X+Mul_X,Off_Y+Mul_Y*(y-1),
      wind->Width-Off_X-Off_X_Right,wind->Height-Off_Y_Bottom);
    SetAPen (rp,1L);
    SetDrMd (rp,JAM2);
    for (i=y;i<screen_lines;i++)
      Dis1Line (1,i,min (strlen (textscreen[i]),screen_columns));
   }
  move_to_pos();
 }
/*}}}  */
/*{{{  insLine*/
int insLine(void)
 {
  movmem (&textscreen[csr_y][0],&textscreen[csr_y+1][0],
          (screen_lines-csr_y+2)*(Max_X+1));
  movmem (&invers[csr_y][0],&invers[csr_y+1][0],
          (screen_lines-csr_y+2)*(Max_X+1));
  setmem (&textscreen[csr_y][0],Max_X+1,0);
  setmem (&invers[csr_y][0],Max_X+1,0);
  re_displ(csr_y);
  return 0;
 }
/*}}}  */
/*{{{  DelLine*/
int DelLine(void)
 {
  movmem (&textscreen[csr_y+1][0],&textscreen[csr_y+0][0],
          (screen_lines-csr_y+1)*(Max_X+1));
  movmem (&invers[csr_y+1][0],&invers[csr_y+0][0],
          (screen_lines-csr_y+1)*(Max_X+1));
  re_displ(csr_y);
  return 0;
}
/*}}}  */
/*{{{  standout*/
int standout(void)
{
  aktinvers = 1;
  return 0;
}
/*}}}  */
/*{{{  standend*/
int standend(void)
{
  aktinvers = 0;
  return 0;
}
/*}}}  */
/*{{{  init_terminal*/
void init_terminal(void)
{
}
/*}}}  */
/*{{{  reset_terminal*/
void reset_terminal(void)
{
}
/*}}}  */
/*{{{  bell*/
void bell (void)

 {
  DisplayBeep (NULL);
 }
/*}}}  */
/*{{{  bell_visible*/
void bell_visible(void)

 {
  DisplayBeep (NULL);
 }
/*}}}  */
/*{{{  num_on*/
void num_on (void)

 {
  num_key_pad = !num_key_pad;
 }
/*}}}  */
/*{{{  apl_on*/
void apl_on (void)

 {}
/*}}}  */
/*{{{  screen_off*/
public void screen_off(void)
 {
  screenon=FALSE;
 }
/*}}}  */
/*{{{  screen_on*/
public void screen_on(void)
 {
  screenon=TRUE;
 }
/*}}}  */

/*{{{  err_ausg*/
int err_ausg (long i)

 {
  bool stop = FALSE;
  struct IntuiMessage *msg;

  Print ("Press any key to exit !\n");
  while (!stop)
   {
    Wait (1 << wind->UserPort->mp_SigBit );
    while (msg = (struct IntuiMessage *)GetMsg (wind->UserPort))
     {
      if ((msg->Class==RAWKEY)||(msg->Class==MOUSEBUTTONS)||
          (msg->Class==CLOSEWINDOW)) stop = TRUE;
     }
   }
  exit (i);
 }
/*}}}  */
