/*===========================================================================*\
| PULLC20.H - Header file for multi-level pull-down menus.  ver 2.0, 04-15-89 |
|                                                                             |
| This file contains all the macros, enums, typedefs, and extern declarations |
| needed for PULLC.  If you change this file, it will not affect the already  |
| compiled PULLC modules.  You must have complete source code and re-compile. |
|   Copyright (c) 1989 James H. LeMay, All rights reserved.                   |
|   Conversion to Turbo C by Jordan Gallagher / Wisdom Research               |
\*===========================================================================*/

#ifdef __TINY__
#error Tiny model not supported by PULLC20
#endif

#define USE_SUBMENU_CODE
#define USE_HELPWNDW_CODE
#define USE_DATAENTRY_CODE
#define USE_MSGLINE_CODE
#define USE_FLOATEMU_CODE

#if !defined(_MATH_H) && defined(USE_FLOATEMU_CODE)
#include <math.h>
#endif

#if !defined(RELMODE) && !defined(MAXWINDOW)
#include "wndwc20.h"
#endif

#define inrange(low,value,high) (high>low ? (value>=low && value<=high) \
                                          : (value>=high && value<=low))
#define strjl(i,o,f) strjust(i,o,f,1)
#define strjr(i,o,f) strjust(i,o,f,0)

#define strapp(str,ch) { str[strlen(str)+1]=0; \
                         str[strlen(str)]=ch; }

/*=================== Data structure configuration macros ===================*/
#define NUM_OF_MAIN_MENUS    8    /* 1 - 255 */
#define NUM_OF_SUB_MENUS     5    /* 1 - 255 */
#define MAX_MENU_LINES       15   /* for main & sub menus */
#define MAX_CHARS_PER_LINE   20   /* for main & sub menus, and
                                     data window titles */

#define NUM_OF_DATA_WNDWS    16   /* 1 - 255 */
#define NUM_OF_DATA_ENTRIES  10   /* 1 - 255 */
#define DATA_STR_SIZE        101  /* max chars in data entry string */

#define NUM_OF_HELP_WNDWS    15   /* 1 - 255 */
#define TOTAL_HELP_LINES     96   /* 1 - 65535 */
#define HELP_CHARS_PER_LINE  52   /* 1 - screen limit */

#define NUM_OF_MSG_LINES     11   /* 1 - 255 */
#define CRT_STR_SIZE         81   /* screen limit for sizing strings */
#define NUM_OF_ERR_MSG_LINES 6    /* 1 - 65535 */
#define ERR_STR_SIZE         61   /* error messages are usually short */

/*========================= Declarations for menus ==========================*/
enum menumodes {
    EXEC_CHOICE,
    SINGLE_CHOICE,
    MULTIPLE_CHOICE
};

enum linemodes {
    CHOICE,
    EXEC_ONLY,
    NO_CHOICE,
    COMMENT,
    PARTITION,
    TO_DATA_WNDW,
    TO_SUB_MENU,
    TO_USER_WNDW
};

enum toggle {
    OFF, ON,
    NO, YES
};

typedef void (*fptr)(void);
typedef char crtstr_t[CRT_STR_SIZE];
typedef char seqstr_t[MAXWINDOW+1];

typedef struct {
    char title[MAX_CHARS_PER_LINE+1];
    char cmdltrs[MAX_MENU_LINES+1];
    char line[ MAX_MENU_LINES ][ MAX_CHARS_PER_LINE+1 ];
    unsigned char linemode[MAX_MENU_LINES];
    unsigned char flagged[MAX_MENU_LINES];
    unsigned char linknum[MAX_MENU_LINES];
    fptr funcptr[MAX_MENU_LINES];

    unsigned char parentdir,linkdir;
    unsigned char menumode;
    unsigned char menulines;
    unsigned char namecol;
    unsigned char row, col, rows, cols;
    unsigned char defaultline, hiliteline, singleflagline;
    unsigned char battr, wattr, hattr, lattr, cattr;
    unsigned char border;
    unsigned char backtodefault, changed;
    unsigned char msglinenum, helpwndwnum;
} menu_t;

extern menu_t *mainmenu;
extern menu_t topmenu;
extern int mri;                        /* TOP menu record index */
extern unsigned char lastmainmenu;     /* <= numofmainmenus */
extern crtstr_t toplinestr;
extern unsigned char toplinerow;
extern unsigned char mainmenurow;
extern unsigned char initattr;
extern unsigned char toplineattr;
extern unsigned char toplinehattr;
extern unsigned char toplinelattr;
extern unsigned char mainmenuwattr;
extern unsigned char mainmenubattr;
extern unsigned char mainmenuhattr;
extern unsigned char mainmenulattr;
extern unsigned char mainmenucattr;
extern unsigned char mainmenubrdr;
extern unsigned char key;
extern char extkey;

/* -- control flags to pull/pop the menus. -- */
extern char pulldown;
extern char pop;
extern char poptoworkwndw;
extern char poptotop;
extern char popandprocess;
extern unsigned char poplevels;

/* -- variables to indicate location of menus and windows. -- */
extern char topcmdltrs[ NUM_OF_MAIN_MENUS+1 ];
extern seqstr_t cmdseq;
extern seqstr_t morecmdseq;         /* sequence of keys pressed. */
extern unsigned char mpulled;
extern unsigned char spulled;
extern char hilited;
extern char accessedworkwndw;
extern char accessedmenus;
extern int workwndwstep;
extern int topworkwndwname;

extern char inworkwndw;
extern char quit;
extern char waitforkbd;

/* -- function keys -- */
#define HELPKEY 59     /* f1 */
#define POPKEY 60      /* f2 */
#define TOPKEY1 68     /* f10 */  /* extended function key */

/* -- data entry keys -- */
#define NULLKEY     0
#define RETKEY      13      /* ^m */
#define BSKEY       8       /* ^h */
#define ESCKEY      27      /* ^[ */
#define HOMEKEY     71
#define UPARRKEY    72
#define PGUPKEY     73
#define LARRKEY     75
#define RARRKEY     77
#define ENDKEY      79
#define DNARRKEY    80
#define PGDNKEY     81
#define INSKEY      82
#define DELKEY      83
#define CTRLLARRKEY 115
#define CTRLRARRKEY 116
#define CTRLENDKEY  117
#define CTRLPGDNKEY 118
#define CTRLHOMEKEY 119
#define CTRLPGUPKEY 132
#define TABKEY      9
#define SHIFTTABKEY 15

/*========================= submenu declarations ============================*/
#ifdef USE_SUBMENU_CODE
extern menu_t *submenu;
extern unsigned char lastsubmenu;    /* <= numofsubmenus */
extern unsigned char submenuwattr;
extern unsigned char submenubattr;
extern unsigned char submenuhattr;
extern unsigned char submenulattr;
extern unsigned char submenucattr;
extern unsigned char submenubrdr;
extern unsigned char location_warning;
#endif

/*====================== message line declarations ==========================*/
#define INSERTSTATE_BIT 0x80    /* bit 7 */
#define CAPSLOCK_BIT    0x40    /* bit 6 */
#define NUMLOCK_BIT     0x20    /* bit 5 */
#define SCROLLLOCK_BIT  0x10    /* bit 4 */
#define ALTSHIFT_BIT    0x08    /* bit 3 */
#define CTRLSHIFT_BIT   0x04    /* bit 2 */
#define LEFTSHIFT_BIT   0x02    /* bit 1 */
#define RIGHTSHIFT_BIT  0x01    /* bit 0 */
#define DELAYTICKS      10      /* about 10/18.2 seconds */

#ifdef USE_MSGLINE_CODE
typedef char errmsgstr_t[ERR_STR_SIZE];

extern int currentmsglinenum;   /* index of the message currently shown. */
extern char enablekeystatus;
extern crtstr_t msgline[ NUM_OF_MSG_LINES ];
extern errmsgstr_t errmsgline[ NUM_OF_ERR_MSG_LINES ];
extern unsigned char msglinerow;
extern unsigned char capslockcol;
extern unsigned char errmsgattr;
extern unsigned char keystatusattr;
extern unsigned char msglineattr;
#endif

#define inserton ((keystatus & INSERTSTATE_BIT) != 0)
#define keystatus *(unsigned char far *)MK_FP(0x0040,0x0017)
#define clockreading *(int far *)MK_FP(0x0040,0x006C)  /* low memory clock */


/*======================== help window declarations =========================*/
#ifdef USE_HELPWNDW_CODE
typedef struct {
    unsigned char firstline, lastline;
    unsigned char linestoshow;
    unsigned char row, col, rows, cols;
    unsigned char battr, wattr;
    unsigned char border;
    unsigned char hwmodes;
    unsigned char msglinenum;
} helpwndw_t;

extern helpwndw_t helpwndw[NUM_OF_HELP_WNDWS];
extern char helpline[ TOTAL_HELP_LINES ][ HELP_CHARS_PER_LINE+1 ];
extern unsigned char helpbottomrow;
extern unsigned char helpwndwmodes;
extern unsigned char helpmsglinenum;
extern unsigned char helpwndwwattr;
extern unsigned char helpwndwbattr;
extern unsigned char helpwndwbrdr;
#endif


/*======================== data windows and data entry ======================*/
#ifdef USE_DATAENTRY_CODE
enum typesofdata {
    BYTES,                      /* actually chars, but numerical */
    UNSIGNED_BYTES,             /*    "       "     "      "     */
    INTS,
    UNSIGNED_INTS,
    LONGS,
    UNSIGNED_LONGS,
#ifdef USE_FLOATEMU_CODE
    FLOATS,
    DOUBLES,
#endif
    USERNUMS,
    CHARS,
    STRINGS
};

enum setnames {
    UNSIGNED_SET,
    SIGNED_SET,
#ifdef USE_FLOATEMU_CODE
    FLOAT_SET,
#endif
    CHAR_SET,
    HEX_SET,
    FILENAME_SET,
    PATH_SET,
    MASK_SET,
    NO_SET=255
};

typedef char entryset_t[ MASK_SET+1 ][255];

typedef struct {
    void *varaddr;
    int typeofdata;
    unsigned char row, col, field, maxfield;
    int precision;
    int setname;
    fptr translatefunc, checkrangefunc;
    int justify_output;
    unsigned char oattr, iattr, msglinenum, helpwndwnum;
} dataentry_t;

typedef struct {
    char title[MAX_CHARS_PER_LINE+1];
    unsigned char dwrow, dwcol;
    unsigned char battr;
    unsigned char border;
    dataentry_t entry;
} datawndw_t;

typedef char datastr_t[DATA_STR_SIZE];

typedef struct {
    char storemode, valid, datastored, newdata, pulldw;
    int fieldindex, cursorofs, hattr;
    int errmsg;
    unsigned char flex;
    char justify;
    datastr_t dataspace;
} datapad_t;

#define bytedata(pad)    pad.dataspace[0]                  /* BYTES */
#define ubytedata(pad)   (unsigned char)pad.dataspace[0]   /* UBYTES */
#define intdata(pad)     *(int *)&pad.dataspace            /* INTS */
#define uintdata(pad)    *(unsigned int *)&pad.dataspace   /* UNSIGNED_INTS */
#define longdata(pad)    *(long *)&pad.dataspace           /* LONGS */
#define ulongdata(pad)   *(unsigned long *)&pad.dataspace  /* UNSIGNED_LONGS */
#ifdef USE_FLOATEMU_CODE
#define floatdata(pad)   *(float *)&pad.dataspace          /* FLOATS */
#define doubledata(pad)  *(double *)&pad.dataspace         /* DOUBLES */
#endif
#define userdata(pad)    pad.dataspace                     /* USERNUMS */
#define chardata(pad)    pad.dataspace[0]                  /* CHARS */
#define strdata(pad)     pad.dataspace                     /* STRINGS */

#define byteptr(pad)     &pad.dataspace                    /* BYTES */
#define ubyteptr(pad)    (unsigned char *)&pad.dataspace   /* UBYTES */
#define intptr(pad)      (int *)&pad.dataspace             /* INTS */
#define uintptr(pad)     (unsigned int *)&pad.dataspace    /* UNSIGNED_INTS */
#define longptr(pad)     (long *)&pad.dataspace            /* LONGS */
#define ulongptr(pad)    (unsigned long *)&pad.dataspace   /* UNSIGNED_LONGS */
#ifdef USE_FLOATEMU_CODE
#define floatptr(pad)    (float *)&pad.dataspace           /* FLOATS */
#define doubleptr(pad)   (double *)&pad.dataspace          /* DOUBLES */
#endif
#define userptr(pad)     &pad.dataspace                    /* USERNUMS */
#define charptr(pad)     &pad.dataspace                    /* CHARS */
#define strptr(pad)      &pad.dataspace                    /* STRINGS */

#ifdef USE_FLOATEMU_CODE
#define isfloat(dbl) (fabs(dbl)>=3.4e-38 && fabs(dbl)<=3.4e+38 || dbl == 0)
#endif

extern entryset_t entryset;   /* filter sets for valid data entry characters */

extern int dwi;                        /* Top Data Window structure Index */
extern int dei;                        /* Top Data Entry structure Index */
extern datawndw_t topdatawndw;
extern dataentry_t topentry;
extern datawndw_t *datawndw;
extern dataentry_t *dataentry;

extern datastr_t datastr;
extern datapad_t datapad;
extern char autotab;
extern char autonumlock;
#endif

#define keyhit() bioskey(1)       /* bioskey(1) is better than kbhit()! */

#ifndef __PC20VAR__  /* speed up compilation - don't process if in PC20VAR.C */

/*  ----------   Prototypes from PULLC20.C   -----------  */

void showtempmsg( int attr, char *msg );
void showmsg( unsigned char msgnum );
int notjustalt(void);
void displaystatus( char *statusmsg, char statusbit, unsigned char coloffset,
                    unsigned char *lastks );
void showkeystatus( char firsttime, unsigned char *lastks );
void insert_( char *s, char c, int pos );
void delete_( char *s, int num );
void monitorkbd(void);
void readkbd( char *extkey, unsigned char *key );
void setcmdseq( seqstr_t newcmdseq );
void hiliteletter( unsigned char hline );
void hiliterow( unsigned char row, int attr );
void movehilite( unsigned char hlnew );
void gettopmenu( int submenupulled );
void savetopmenu(void);
void showmenu( int submenupulled, char savemenu );
void removemenu( int submenupulled, unsigned char msgnum );
int rollinc( int first, int numtoroll, int last );
int rolldec( int first, int numtoroll, int last );
char selectable( unsigned char hl );
void rollhilite( int dir );
void starthilite(void);
void showtopline(void);
void showtophilite(void);
void movetophilite( unsigned char mpnew );
void rollmenu( int dir );
void callfunction( fptr execptr );
void writef( unsigned char row, char *flag );
void dochoice( unsigned char *tf );
void showerrmsg( int errmsgnum );
int topkeypressed(void);
int helpkeypressed(void);
void pullhelpwndw( unsigned char wndwnum );
void turnarrows( int toggle );
void checkforpulldown( unsigned char msglinenum );
void checkforpop(void);
int popped(void);
void checkselection(void);
void pullsubmenu( unsigned char menunum, unsigned char lastspulled );
void pullmainmenu(void);
void pulltopmenu(void);
void gotomenus(void);
void gotoworkwndw(void);
void clearpopflags(void);
void gotokeydispatcher(void);

/*  ----------   Prototypes from PC20INIT.C   -----------  */

void getrowsandcols(unsigned char *last);
void setmenudefaults( unsigned char mainm, unsigned char sub, int menubrdr,
                      unsigned char *last );
void initmenusize(void);
void initmenucolor(void);
void locatemainmenus(void);
void locatesubson( menu_t *menu );
void locatesubmenus(void);
void locatehelpwndws(void);
void clearpullstats(void);
void initpull( int attr, char clearscr, char cursorok );

/*  ----------   Prototypes from PC20DATA.C   -----------  */

void togglenumlock(char toggle);
void transferdata( void *uservariable );
void stripleadingspaces( char field );
void convertdatatostr(void);
void showdatawndw( int index );
char isdoublestr( char *mystr, double *f );
char islongstr( char *mystr, long *l );
char isulongstr( char *mystr, unsigned long *ul );
void convertstrtodata(void);
void storedata(void);
void updatefield( int attr );
void movecursor(void);
unsigned char maxcursorofs(void);
unsigned char maxfieldindex(void);
void cursorfirst(void);
void cursorlast(void);
void cursorleft(void);
void cursorright(void);
void deletechar(void);
void backspace(void);
void clrdatastr(void);
void toggleinsert(void);
void addchar(void);
void extkeyedit(void);
void normkeyedit(void);
void displayfield( int attr );
void getdatawndw( int index );
void savedatawndw(void);
void getdataentry( int index );
void savedataentry(void);
void displayfields( unsigned char first, unsigned char last );
void savedata(void);
void enterdata(void);
void pulldatawndw( unsigned char wndwnum );
void wndwentryexit(void);
void enter( int recnum );
void movecursortofield(void);
void horizadj( unsigned char adjacentcol, unsigned char nearestcol,
               int first, int last, int *start );
void horizend( int dir, int first, int last, int *start );
void vertadj( unsigned char adjacentrow, unsigned char nearestrow,
              int first, int last, int *start );
void nextfield(int first, int last, int *start);
void enterseq( int first, int last, int *start );

/*  ----------   Prototypes from STRJUST.C   -----------  */

char far *strjust( const char far *instr, char far *outstr,
                   unsigned char field, char left );

/* These are prototypes for functions that must exist in PULLSTAT, PULLDATA,
   and PULLWORK.
*/

void getuserpullstats (void);                               /* PULLSTAT */
void getoverridestats (void);                               /* PULLSTAT */
void checkglobalkeys  (void);                               /* PULLSTAT */
void getdataentrystats(void);                               /* PULLDATA */
void initpulldata     (void);                               /* PULLDATA */
void kbdidle          (void);                               /* PULLWORK */
void workwndw         (void);                               /* PULLWORK */
void initpullwork     (void);                               /* PULLWORK */

#endif

