/************************************************************************

screen.h	-	Include file for use with text cursor control
			functions  etc in screen.c.

Programmer      -       Edward James Pugh, FIAP.

Copyright	-	(C) Edward James Pugh, 12-Jan-1990.

*************************************************************************/

#if !defined(BOOLEAN)
#define BOOLEAN int
#define TRUE 1
#define FALSE 0
#endif

#if !defined(_SCREEN_DECL)

#include "llist.h"

/* declare structure types */
typedef struct
	{
	unsigned char Row, Col;
	} Curs_t;

typedef struct
	{
	unsigned char TRow, TCol, BRow, BCol;
	} Screen_t;

typedef struct
	{
	unsigned char TL, TR, BL, BR, HZ, VT, LB, RB, Attrib;
	} Border_t;

typedef enum    {EMPTY = 1, MENU_TITLE, POP_UP_LIST, CODE_BUTTON,
SWITCH, CHECK_BOX, STRING_D, INT_D, NUMBER_D, DATE_D}WObj_s;

typedef enum{SCREEN_W, OBJECT_W, MENU_BAR_W, POP_UP_W}Wind_s;

typedef struct wndw
	{
	char            *Title; /* window title */
	unsigned char   TOffset, TLength; /* title col and length */
	Screen_t        Bounds; /* window boundaries for writing */
	Screen_t        MinBounds; /* minimum window boundaries in order
			to contain attached objects - except POP_UP */
	unsigned char   Attrib; /* window attribute */
	Border_t        *Border; /* Border details */
	unsigned        *Area; /* saved old screen area */
	unsigned        *Pane; /* saved window screen contents */
	void            *Contents; /* window contents */
	char            HKey; /* Hot key for this window */
	llist_t         *ObjList; /* linked object list */
	Wind_s          Type; /* the type of window */
	llnode_t        *SNode; /* its stack pointer if a main window */
	struct wndw     *Parent; /* its parent window */
	llnode_t        *Posn; /* its node in the parent list */
	WObj_s          CType;  /* its contents type */
	llnode_t        *Process; /* set by user routine to the current
			process once the window is established */
	BOOLEAN         Changed; /* set to true if contents has changed
			since the last time pane was saved */
	Curs_t          CursPosn; /* the current cursor position within
				the window */
	void            *PData; /* private data field for programmer's use */
	} Window_t;

/* specify event types */

typedef enum {CHANGE_WINDOW = 1, DO_MENU_BAR, DO_SWITCH, DO_CHECK_BOX,
DO_BUTTON, EXT_KEY_EVENT, CLOSE_WINDOW, ALTER_WINDOW,
DO_LINE, ASCII_KEY, NEW_PROCESS, EXIT_PROGRAM, BUTTON_VALUE, DO_DIALOGUE
}Event_s;

struct ext_key
	{
	int Class;
	unsigned char Key;
	};

struct cde
	{
	int (*TgtProcess)(void);
	unsigned StackSize;
	};

typedef struct
	{
	Event_s Event;
	Window_t *Window;
	llnode_t *Node;
	union
		{
		int RetValue;
		int LineNo;
		struct cde;
		struct ext_key;
		unsigned char Input;
		};
	}Event_t;

typedef struct
	{
	char *Title; /* the option title */
	int State; /* hot key state - ON or OFF */
	int (*Code)(void); /* function pointer */
	unsigned StackSize; /* the amount of stack to be allocated */
	char HKey; /* the title hot key */
	}Option_t;

typedef Option_t Button_t;

typedef struct
	{
	char *Title; /* the menu title */
	Option_t *Options; /* pointer to option array */
	char HKey; /* the menu hot key */
	}Menu_t;

typedef struct
	{
	char *Title; /* the switch title */
	int State; /* hot key state */
	int *TempVar; /* the address to hold temporary settings */
	int *Var; /* the address of the variable to be changed
			on a continue event */
	int Mask; /* the mask to be applied */
	char HKey; /* the title hot key */
	}Switch_t; /* switch is on when Var == mask */

typedef Switch_t CheckBox_t; /* check is on when (Var & mask)==TRUE */


/* function prototypes */

/* restore the cursor posn */
void ResCurs(const Curs_t *cursposn);

/* save the cursor posn */
void SaveCurs(Curs_t *cursposn);

/* create a new window */
Window_t *NewWindow(Wind_s type, char *Title, unsigned char TLine,
			unsigned char TCol, unsigned char BLine,
			unsigned char BCol, unsigned char Attrib,
			Border_t *Border);

/* name a window */
size_t NameWindow(Window_t *window, char *title);

/* get the width and hot key contained in a title string */
unsigned char TStringWidth(char *string, char *hkey);

/* move the cursor up */
BOOLEAN CursUp(void);

/* move the cursor down */
BOOLEAN CursDn(void);

/* move the cursor left */
BOOLEAN CursL(void);

/* move the cursor right */
BOOLEAN CursR(void);

/* move cursor to beginning of next line */
BOOLEAN CursRet(void);

/* move cursor to window home position */
BOOLEAN CursHome(void);

/* clear the current line */
void ClearLine(void);

/* move cursor to beginning of line */
void BegLine(void);

/* move cursor to end of line */
void EndLine(void);

/* clear the window */
void ClearWindow(void);

/* open a window */
Window_t *OpenWindow(Window_t *window);

/* close a window */
Window_t *CloseWindow(Window_t *window);

/* kill a window */
Window_t *KillWindow(Window_t *window);

/* scroll the window up one line */
void ScrollUp(void);

/* scroll the window down one line */
void ScrollDn(void);

/* Kill all windows - including those on the stack */
void KillAllWindows(void);

/* create a menu bar */
Window_t *NewMenuBar(Menu_t *menu, unsigned char attrib);

/* create a pop up menu */
Window_t *NewPopUp(char *Title, Option_t *Options, unsigned char TRow,
	unsigned char TCol, unsigned char Attrib, Border_t *Border);


/* add button */
unsigned char AddButton(Window_t *window, Option_t *data,
		unsigned char TRow, unsigned char TCol);

/* add switches or checkboxes */
BOOLEAN AddSBox(WObj_s type, Window_t *window, Switch_t *switches,
		unsigned char TRow, unsigned char TCol);

#define AddSwitches(window, switches, TRow, TCol) \
AddSBox(SWITCH, window, switches, TRow, TCol)
#define AddCBoxes(window, boxes, TRow, TCol) \
AddSBox(CHECK_BOX, window, boxes, TRow, TCol)

/* get the window corresponding to the given Title Hot Key */
Window_t *GetWindow(char key);

/* pop the given window to the top of the relevant stack */
size_t PopWindow(Window_t *target);

/* Decrement boundaries by one */
void DecBounds(Screen_t *Bounds);

/* Increment boundaries by one */
void IncBounds(Screen_t *Bounds);

/* get an object's details from its given hot key */
Event_t *GetObject(char hkey);

/* get an object clicked on by the mouse */
Event_t  *GetMObj(unsigned int x, unsigned int y);

/* check diagonal lines in bounds1 are all contained in bounds2 */
BOOLEAN B1inB2(Screen_t *bounds1, Screen_t *bounds2);

/* obtain a clipcode for a given position in relation to screen area */

/* clip codes for line endpoints

	1001 | 1000 | 1010
	------------------
	0001 | 0000 | 0010
	------------------
	0101 | 0100 | 0110       */

int ClipCode(unsigned char row, unsigned char col, Screen_t *bounds);

/* discover if window is above location window */
BOOLEAN IsAbove(llnode_t *location, llnode_t *target);

/* discover if window is below location window */
BOOLEAN IsBelow(llnode_t *location, llnode_t *target);


/* label a dialogue box */
size_t LabelWindow(Window_t *window, char *title);

/* increment dialogue box bounds */
void IncDBounds(Window_t *window);

/* decrement dialogue box bounds */
void DecDBounds(Window_t *window);

/* add a dialogue box */
unsigned char AddDBox(Window_t *window, char *label, WObj_s type, void *data,
	unsigned char trow, unsigned char tcol, unsigned char width);

int wprintf(Window_t *window, BOOLEAN restore, char *fmt, ...);

int PutString(Window_t *window, char *buffer, BOOLEAN restore, BOOLEAN date);

/* locate the window on the bottom of the SCREENSTACK */
Window_t *BottomWindow(void);

#define _SCREEN_DECL
#endif
