/* arclynx - simple version of Lynx for Acorn machines
 * (c) 1996 Andrew Wood
 *
 * Routines contained in this file (a_term.c):
 *   awterm_initialise() - last modified 96/07/18
 *   awterm_finalise()   - last modified 96/07/18
 *   awterm_workspace()  - last modified 96/07/16
 *   awterm_status()     - last modified 96/07/18
 *   awterm_info()       - last modified 96/07/18
 *   awterm_input()      - last modified 96/07/18
 *   awterm_clear()      - last modified 96/07/18
 *   awterm_readkey()    - last modified 96/07/16
 *   awterm_getch()      - last modified 96/07/16
 *   awterm_move()       - last modified 96/07/18
 *   awterm_colour()     - last modified 96/07/18
 *   awterm_pause()      - last modified 96/07/16
 *   awterm_char()       - last modified 96/07/18
 */

#include "arclynx.h"
#include <string.h>
#include <roslib.h>


/******************************************************************************
 * awterm_initialise() - initialise terminal input and output
 */
void awterm_initialise(void) {
 static Screen *screen;                                /* screen information */
 int x,y;                                               /* OS_Byte registers */
 screen=awterm_workspace();                       /* get screen data pointer */
 screen->width=80; screen->height=32;                /* set width and height */
 os_mode(12); os_cursor(0);                            /* mode 12, no cursor */
 os_vduq(19,LYNX_COL_PLAIN,16,200,200,200);                  /* set palette: */
 os_vduq(19,LYNX_COL_BOLD,16,200,100,100);
 os_vduq(19,LYNX_COL_ITALIC,16,200,200,0);
 os_vduq(19,LYNX_COL_HEADING,16,0,100,200);
 os_vduq(19,LYNX_COL_SELECTED,16,0,200,0);
 os_vduq(19,LYNX_COL_ANCHOR,16,255,255,255);
 os_vduq(19,LYNX_COL_ANCHOR+LYNX_COL_PLAIN,16,255,255,255);
 os_vduq(19,LYNX_COL_ANCHOR+LYNX_COL_BOLD,16,255,140,140);
 os_vduq(19,LYNX_COL_ANCHOR+LYNX_COL_ITALIC,16,255,255,0);
 os_vduq(19,LYNX_COL_ANCHOR+LYNX_COL_HEADING,16,0,220,255);
 os_vduq(19,LYNX_COL_ANCHOR+LYNX_COL_SELECTED,16,0,255,0);
 x=1; y=0; os_byte(4,&x,&y);                 /* enable arrow key ASCII codes */
 screen->data=(char *)malloc(screen->width*screen->height);
 screen->colour=(char *)malloc(screen->width*screen->height);
 awterm_clear();                                             /* clear screen */
}


/******************************************************************************
 * awterm_finalise() - reset terminal to normal
 */
void awterm_finalise(void) {
 static int x,y;                                        /* OS_Byte registers */
 static Screen *screen;                            /* pointer to screen data */
 screen=awterm_workspace();                               /* get screen data */
 os_mode(0); os_cursor(1);                         /* mode 0, cursor enabled */
 x=0; y=0; os_byte(4,&x,&y);                    /* arrow keys back to normal */
 free(screen->data); free(screen->colour);          /* free screen workspace */
}


/******************************************************************************
 * awterm_workspace() - return pointer to screen information workspace
 */
Screen *awterm_workspace(void) {
 static Screen screen;
 return(&screen);
}


/******************************************************************************
 * awterm_status(string) - change status line of display
 */
void awterm_status(char *string) {
 static Screen *screen;                            /* pointer to screen info */
 static int i;                                  /* general iteration counter */
 screen=awterm_workspace();                               /* get screen data */
 awterm_move(0,screen->height-1);            /* move to start of status line */
 awterm_colour(LYNX_COL_ANCHOR+LYNX_COL_HEADING);   /* bright heading colour */
 for(i=0; i<(screen->width-1); i++) {           /* display almost full line: */
  if (i<strlen(string)) {awterm_char(string[i]);} else {awterm_char(32);}
 }
}


/******************************************************************************
 * awterm_info(string) - change info line of display
 */
void awterm_info(char *string) {
 static Screen *screen;                            /* pointer to screen info */
 static int i;                                  /* general iteration counter */
 screen=awterm_workspace();                               /* get screen data */
 awterm_move(0,screen->height-2);              /* move to start of info line */
 awterm_colour(LYNX_COL_ANCHOR+LYNX_COL_HEADING);   /* bright heading colour */
 for(i=0; i<(screen->width-1); i++) {           /* display almost full line: */
  if (i<strlen(string)) {awterm_char(string[i]);} else {awterm_char(32);}
 }
}


/******************************************************************************
 * awterm_input(display,string) - show "display" on bottom line and input text
 *                                into "string"
 */
void awterm_input(char *display,char *string) {
 static Screen *screen;                            /* pointer to screen info */
 static int i;
 screen=awterm_workspace();                               /* get screen data */
 awterm_info("");                                              /* clear line */
 os_vduq(31,0,screen->height-2);               /* move to start of info line */
 os_colour(LYNX_COL_ANCHOR+LYNX_COL_HEADING);       /* bright heading colour */
 printf("%s",display);                                /* show display string */
 os_colour(LYNX_COL_PLAIN);                             /* plain text colour */
 gets(string);                                          /* read line of text */
 os_vduq(31,0,screen->height-2);
 for(i=0; i<screen->width; i++) {os_vdu(32);}                  /* clear line */
 awterm_info("");                                              /**/
}


/******************************************************************************
 * awterm_clear() - clear screen
 */
void awterm_clear(void) {
 static Screen *screen;
 screen=awterm_workspace();
 os_cls();
 memset(screen->data,32,screen->width*screen->height);
 memset(screen->colour,LYNX_COL_BLACK,screen->width*screen->height);
 screen->c=LYNX_COL_PLAIN; screen->x=0; screen->y=0;
}


/******************************************************************************
 * awterm_readkey() - return key pressed, or -1 if none
 */
int awterm_readkey(void) {return(os_inkey(0));}


/******************************************************************************
 * awterm_getch() - wait for key press, return it
 */
int awterm_getch(void) {return(os_get());}


/******************************************************************************
 * awterm_move(x,y) - move to (x,y), 0,0 is top left
 */
void awterm_move(int x,int y) {
 static Screen *screen;
 screen=awterm_workspace();
 screen->x=x; screen->y=y;
}


/******************************************************************************
 * awterm_colour(c) - change to colour c
 */
void awterm_colour(int c) {
 static Screen *screen;
 screen=awterm_workspace();
 screen->c=c;
}


/******************************************************************************
 * awterm_pause() - pause for a moment
 */
void awterm_pause(void) {os_inkey(100);}


/******************************************************************************
 * awterm_char(c) - print character
 */
void awterm_char(int c) {
 static Screen *screen;
 static int a;
 screen=awterm_workspace();
 a=screen->x+screen->width*screen->y;
 if ((screen->data[a]!=c) | (screen->colour[a]!=screen->c)) {
  screen->data[a]=c; screen->colour[a]=screen->c;
  os_vduq(31,screen->x,screen->y); os_colour(screen->c); os_vdu(c);
 }
 screen->x++;
}
