/* zorroapi.h                 CIC Proprietary
 *----------------------------------------------------------------------------
 * SCCS Version %I%, %U% %G%
 *----------------------------------------------------------------------------
 * API header file for CIC low end recognizer ZORRO.
 *
 * J. Wang          07-Mar-96   Initial.
 *----------------------------------------------------------------------------
 */
#ifndef ZORROAPI_H
#define ZORROAPI_H

#include <jotopt.h>
#include <ansicode.h>       /* The code table.      */

/*
 *----------------------------------------------------------------------------
 * The following will affect the build of the system with various options
 *
 * These options are moved to file jotopt.h as of 25-Aug-97.
 *----------------------------------------------------------------------------
 */
/* #define ZORRO_TRAINABLE     0   
                /* Set to 0 will disable internal trainer               */
/* #define ZORRO_EXTERNAL_TRAINER  1
                /* Set to 1 to use external trainer                     */
/* #define ZORRO_SPACE_DETECTION   1
                /* Default is character recognition, set to 1 to allow   */
                /*   sentence recognition                                */
/* #define ZORRO_RESOLUTION_128	1
#define ZORRO_RESOLUTION_1016     0
                /* The resolution is 1016 ppi      */
/* #define ZORRO_REENTRANT     0
                /* Set to 0 will use global variable instead of dynamicly */
                /*   allocated memory                                     */                
/* #define ZO_REC_SPECIALKEY	0
				/* Under Windows, set to 1 will recognize some special key*/
				/*   such as Home, End, PageUp, PageDown etc.			  */
/*
 *----------------------------------------------------------------------------
 * Returned ERROR code from recognizer API functions.
 *----------------------------------------------------------------------------
 */
typedef enum tagZO_RET
    {
    ZO_NOERROR,                         /* NO ERROR             */
    ZO_ERROR_UNKNOWN,                   /* Unknown ERROR        */ 
    ZO_ERROR_INPUT_METHOD,              /* ERROR in input method    */
    ZO_ERROR_MEM,                       /* Memory ERROR         */ 
    ZO_ERROR_FILE,                      /* File ERROR           */
    ZO_ERROR_TRAIN                      /* Training ERROR       */
    } ZO_RET;                                                             
    
/*
 *----------------------------------------------------------------------------
 * Input method used by user. 
 *----------------------------------------------------------------------------
 */
#define ZO_INPUT_MODELINE         0x1   /* Input by modeline            */
#define ZO_INPUT_SWITCH           0x2   /* Input by gestures and buttons*/ 
#define ZO_INPUT_TRAINER          0x4   /* Input from trainer, only used*/
                                        /*   by trainer.                */
                                        /* The above are basic input    */
                                        /*   mode. One and only one must*/
                                        /*   be set                     */
#define ZO_INPUT_DETECT_SPACE	  0x8   /* Detect space automatically   */
#define ZO_INPUT_USE_END_GESTURE  0x10  /* Use END gesture              */
#define ZO_INPUT_SENTENCE         0x20  /* Sentence input mode          */
#define ZO_INPUT_NOEXTENDCHAR	  0x40  /* Don't recognize extended char*/
										/* Before switch this, call     */
										/*   zo_flush() to flush out    */
#define ZO_INPUT_VERTICAL_RIGHTNUM 0x80 /* In vertical mode, use right  */
										/*  side of mode mark as number */
										/*  mode and left as lowercase  */
										/*  Normally the right side is  */
										/*  lowercase and left is number*/
#define ZO_INPUT_LEFTHANDER		  0x100 /* For left-hander				*/
#define ZO_INPUT_ONE_STROKE_CHAR_ONLY		0x80000000
					/* Only use 1-stroke characters	*/

/*
 *----------------------------------------------------------------------------
 * A structure describe a point
 *----------------------------------------------------------------------------
 */
typedef struct tagZO_POINT
    {
    int x;              /* X coordinate         */
    int y;              /* Y coordinate         */
    } ZO_POINT;
                        
/*
 *----------------------------------------------------------------------------
 * A structure describe a rectangle
 *----------------------------------------------------------------------------
 */
typedef struct tagZO_RECT
    {
    int left;               /* Left coordinate      */
    int top;                /* Top coordinate       */
    int right;              /* Right coordinate     */
    int bottom;             /* Bottom coordinate    */
    } ZO_RECT;                  

/*
 *----------------------------------------------------------------------------
 * A structure to describe a stroke
 *----------------------------------------------------------------------------
 */             
#define MAX_ZORRO_STROKE_POINTS 256   /* Max number of points in a stroke */
#define STANDARD_RESOLUTION 254
typedef struct tagZO_STROKE
    {
    int resolution;         /* Dot per inch of stroke   */
    ZO_RECT bound;          /* Bounding rectangle       */
    int num_points;         /* Number of points         */
    ZO_POINT *points;       /* Points array             */ 
#if ZO_DEBUG
    int     char_index;     /* For debug only           */
#endif
    } ZO_STROKE;

/*
 *----------------------------------------------------------------------------
 * A structure to describe a modeline. All the coordinates here should be
 * relative to the same coordinate space and with x-axis going right and
 * y-axis going down.
 *----------------------------------------------------------------------------
 */
#define ZO_MODELINE_HORIZONTAL  0
#define ZO_MODELINE_VERTICAL    1
typedef struct tagZO_MODELINE
    {
    ZO_RECT     rect;           /* Window rectangle for modeline*/
    int         direction;      /* Direction of modeline        */
    ZO_POINT    position;       /* Position of beginning point  */
    } ZO_MODELINE;
    
/*
 *----------------------------------------------------------------------------
 * A structure describes the recognition result
 *
 * NOTE: The num_result and resultAr contained regular recognized result.
 *       The num_macro and macroP contains recognized macro or user trained
 *       characters, if any.
 *
 *       Besides recognized characters, the result buffer also contains some
 *       other infomation useful for the caller. They are:
 *           1). Inking hint: 
 *               PZ_INK_KEEP_THIS used when current ink should
 *                 be waiting instead of disappear. For example, when the first
 *                 stroke of a 2-stroke character such as 'x' or '4' is 
 *                 recognized, or in extended mode, this special value is put 
 *                 in the result buffer as a hint. 
 *               PZ_INK_CLEAR_ALL clears all the previous waiting ink. It's
 *                 put in the resultAr when the second stroke of a 2-stroke
 *                 character comes or extended mode terminates.
 *           2). Mode switching characters:
 *               These are PZ_MODE_* characters as defined in the code file.
 *               They are put in the result buffer when a mode switch gesture
 *               is recognized. The internal mode is adjusted automatically, 
 *               and these result tell the caller to update some visual
 *               appearance for the new mode.
 *           3). Gestures:
 *               These are value like PZ_GESTURE_* for recognized gestures.
 *           4). Operations:
 *               If a result is PZ_OPERATION, the next char is an operation
 *               code as defined in oplist.c. The caller should inteprate
 *               accordingly.
 *           5). Special keys:
 *               Special keys include CONTROL, SHIFT, ALT and other keys in 
 *               the keyboard. Currently special keys are supported only in
 *               Microsoft Windows platform. For example, the user can write
 *               "C-S-A" in extended mode to get "CONTROL-SHIFT-A" effect as
 *               typed in keyboard. In such a case, the result buffer contains
 *               the sequence: PZ_SPECIALKEY, VK_CONTROL, VK_SHIFT, VK_A,
 *               PZ_SPECIALKEY. VK_* is the virtual keycode as defined in
 *               <windows.h>.
 *           6). Other indications:
 *               PZ_MACRO tells there is macro recognized. 
 *               PZ_CHANGE_LAST_CHAR means changing the last recognized 
 *                 character by current result, perhaps replacing the base 
 *                 character by ite accented version.
 *               PZ_WAIT_* means current stroke is the first stroke of a
 *                 2-stroke character and the recognizer is waiting for the
 *                 next stroke.                    
 *
 *----------------------------------------------------------------------------
 */  
#define MAX_MACRO_LEN		7	/* Max macro length				*/
#define MAX_MULTI_STROKE    32	/* Max multi-stroke numbers     */
#define MAX_REC_RESULT      10  /* Max result without macro     */
#define MAX_CAND_RESULT     5   /* Max candidates result        */
typedef struct tagZO_RESULT
    {
    int     num_result;         /* Number of result     */
    ZO_CHAR resultAr[MAX_REC_RESULT];   /* Result buffer    */
	int	    num_cand;
	ZO_CHAR candAr[MAX_CAND_RESULT];	/* Other candidates */
    int     num_macro;          /* Macro length if any      */
    ZO_CHAR *macroP;            /* Macro result buffer      */ 
#if ZO_DEBUG
    int     shape_index;        /* For debug only               */
#endif
    } ZO_RESULT;

/*
 *----------------------------------------------------------------------------
 * Jot Trainer mask bits. 
 *----------------------------------------------------------------------------
 */
#define JOT_SINGLE_STROKE_ONLY	0x00000001
#define JOT_K_LU_TWO_STROKE		0x00000002
#define JOT_J_UC_TWO_STROKE		0x00000004
#define JOT_I_LC				0x00000008
#define JOT_Q_UC_TWO_STROKE		0x00000010
#define JOT_DOLLAR_TWO_STROKE	0x00000020
#define JOT_T_LU_TWO_STROKE		0x00000040		// deactivated
#define JOT_Y_LU_TWO_STROKE		0x00000080
#define JOT_P_LU_TWO_STROKE		0x00000100
#define JOT_T_LC_HV				0x00000200
#define JOT_T_LC_VH				0x00000400
#define JOT_F_HV				0x00000800

#define JOT_TRAIN_DEFAULT	JOT_T_LC_VH	

#if ZO_DEBUG
#include <stdio.h>
#define MAX_HMM_DICT_VER 103
#define MAX_HMM_DICT_ROUTINE 180

typedef struct
    {
    int         errorB;         /* YES if reco error                        */
    int         rejectB;        /* YES if rejected                          */
    FILE        *dboutPG;       /* Debug info file                          */
    int         plotBG;         /* YES if plot data                         */
    int         two_strokeB;    /* = 1 if input 2-stroke char               */
    int         input_version;  /* Input character version                  */
    int         output_version; /* Recognized output char ver               */
    int         mode;           /* Mode of recognition                      */
    int         dbflagG;        /* Debug flag                               */
    int         sentnoWG;       /* Sentence no.                             */
    int         iretW;          /* DISAM: index of first fail routine       */
    int         nroutC;         /* DISAM: number of failures                */
    char        indexfC[128];   /* DISAM: list of version's failed indexs   */
    int         currnoW;        /* DISAM: Index of current disam routine    */
    int         search_corrB;   /* YES if searching correct char version    */
    int         dict_ver;	/* DISAM: currently search version	    */
    int		dishmmB;	/* YES if disambiguating HMM		    */
    int         hmm_stat[MAX_HMM_DICT_VER][MAX_HMM_DICT_ROUTINE]; 
                                /* DISAM: for each ver, wrong char 1st      */
                                /* fail number for each routine.            */
    int         hmm_pass[MAX_HMM_DICT_VER][MAX_HMM_DICT_ROUTINE]; 
                                /* DISAM: for each ver, corr char pass      */
                                /* number for each routine.                 */
    } ZO_DBINFO;
#endif

/*
 *----------------------------------------------------------------------------
 * API function prototypes
 *----------------------------------------------------------------------------
 */  
 
#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif                  /* __cplusplus */

/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_open
 *
 * PARAMETERS:   long   *handleP        : Will receive a handle of the instance
 *
 * PURPOSE:      Open and intialize a new instance of recognition session, 
 *               return a handle in handleP. If this handle is NULL, the 
 *               opening failed.
 *----------------------------------------------------------------------------
 */
ZO_RET zo_open
    (                             
    long        *handleP
    );

/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_close
 *
 * PARAMETERS:   long   handle  : Handle returned by zo_open
 *
 * PURPOSE:      Close the instance of recognition session represented by 
 *               handle
 *----------------------------------------------------------------------------
 */
ZO_RET zo_close
    (
    long    handle              /* Handle of this instance      */
    );

/* zo_set_macro_recog_callback
 *----------------------------------------------------------------------------
 * Set the callback function to recognize macros
 *----------------------------------------------------------------------------
 */
ZO_RET zo_set_macro_recog_callback
	(
	long handle,
	void *callback
	);

/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_mode
 *
 * PARAMETERS:   long   handle          : Handle returned by zo_open
 *               int    input_method    : Could be one of ZO_INPUT_MODELINE,
 *                                        ZO_INPUT_GESTURE or ZO_INPUT_TRAINER
 *               ZO_CHAR mode           : Could be one of PZ_MODE_DEFAULT,
 *                                        PZ_MODE_LCALPHA, PZ_MODE_UCALPHA,    
 *                                        PZ_MODE_NUMERIC,
 *                                        PZ_MODE_PUNCTUATION, PZ_MODE_EXTENDED 
 *
 * PURPOSE:      Set the current recognition mode. In general, mode is set 
 *               automatically according to the input method and user's writing.
 *               This function provided only for special cases to set
 *               mode forcefully. 
 *----------------------------------------------------------------------------
 */    
ZO_RET zo_mode
    (
    long        handle,         /* Handle of this instance      */               
    int         input_method,   /* Input method to set mode     */
    ZO_CHAR     mode            /* Mode to switch to            */
    );

/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_train
 *
 * PARAMETERS:   long   handle          : Handle returned by zo_open
 *               unsigned long			: Train information
 *
 * PURPOSE:      Set train information
 *----------------------------------------------------------------------------
 */    
ZO_RET zo_train
	(
	long	handle,				/* Handle of this instance				*/
	unsigned long	trainUL				/* Trained information					*/
	);

/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_stroke
 *
 * PARAMETERS:   long   handle          : Handle returned by zo_open
 *               int    input_method    : Could be one of ZO_INPUT_MODELINE,
 *                                        ZO_INPUT_GESTURE or ZO_INPUT_TRAINER
 *               ZO_MODELINE *mode_lineP: If the input_method above is
 *                                        ZO_INPUT_MODELINE, this parameter
 *                                        specifies the modeline. Otherwise
 *                                        it can be NULL.
 *               ZO_STROKE *strokeP     : The input stroke.
 *               ZO_RESULT *resultP     : The recognized result.
 *
 * PURPOSE:      This function is the heart of ZORRO recognizer. It accept a 
 *               single stroke and output the recognized result, probably 
 *               using the previous recognition result.  
 *----------------------------------------------------------------------------
 */
ZO_RET zo_stroke
    (
    long        handle,         /* Handle of this instance      */
    int     input_method,       /* Current input method         */
    ZO_MODELINE *mode_lineP,    /* Modeline if using MODELINE   */
    ZO_STROKE   *strokeP,       /* Input stroke                 */
    ZO_RESULT   *resultP        /* Returned result              */
    );

/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_flush
 *
 * PARAMETERS:   long   handle          : Handle returned by zo_open
 *               ZO_RESULT *resultP     : The recognized result.
 *
 * PURPOSE:      Flush the waiting result in internal buffer and reset
 *               the internal state to default. This function is used
 *               in timeout writing mode or other interruptions.
 *----------------------------------------------------------------------------
 */ 
ZO_RET zo_flush
    (
    long        handle,         /* Handle of this instance      */
    ZO_RESULT   *resultP        /* Returned result              */
    );

#if ZORRO_TRAINABLE 
/*
 *----------------------------------------------------------------------------
 * The macro editor and the core recognizer communicate by a user trained 
 * data file. The macro editor modify that file each time the user makes
 * changes, and the core recognizer load the file after each change. The 
 * macro editor also need the recognizer's help to decide if a new macro
 * is conflict with a previous trained macro or a pre-defined extended
 * character by calling zo_rec_extended_char().
 *
 * The format of the user trained data file is:
 * 
 * BYTE: 1 2 3 4 5 6 7 ...
 *       --- _______ ----
 *        |     |      |
 *       A 16-bit int containing number of macros in this file
 *              |      |
 *             A 32-bit int containing the size of data from byte 7 to eof
 *                     |
 *                    First macro, byte by byte, ended with 0, followed by its
 *                    output string, also ended by 0, followed by second 
 *                    macro and its output string, ..., the last one ended by
 *                    double 0's.
 *
 * To implement a trainer:
 *  1). Call zo_open() to open an instance, and get a handle.
 *  2). Call zo_load_train() to load the current trained data file or a empty 
 *      seed file.
 *  3). Get user's new macro and its output string.
 *  4). Call zo_rec_extended_char() to verify conflict and update the data file.
 *      If conflict and user selects overriding the old one, still update the 
 *      data file.
 *  5). Call zo_unload_train() and zo_load_train() to update recognizer of
 *      the new data file.
 *  6). Repeat 3 - 5 until user finished this session.
 *  7). Call zo_unload_train() to unload trianer from recognizer and call 
 *      zo_close() to close the recognizer instance.
 *
 *----------------------------------------------------------------------------
 */
  
/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_load_train
 *
 * PARAMETERS:   long   handle          : Handle returned by zo_open
 *               char *train_fileS      : File name for trained data
 *
 * PURPOSE:      Load the trained data in train_fileS to the session 
 *               represented by handle. This function should be called after
 *               zo_open if the session uses trained data.
 *----------------------------------------------------------------------------
 */   
ZO_RET zo_load_train
    (
    long        handle,         /* Handle of this instance      */
    char *train_fileS           /* Train data file name         */
    );

/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_unload_train
 *
 * PARAMETERS:   long   handle          : Handle returned by zo_open
 *
 * PURPOSE:      Unload the trained data in the session represented by handle.
 *               This function should be called before zo_close or when the 
 *               user disables training.
 *----------------------------------------------------------------------------
 */   
ZO_RET zo_unload_train
    (
    long        handle         /* Handle of this instance      */
    );  
#endif

#if ZORRO_EXTERNAL_TRAINER
/*
 *-----------------------------------------------------------------------------
 * API FUNCTION: zo_rec_macro
 *
 * PARAMETERS:  int     num_input       : Number of input macro name
 *              char    *inputS         : String contains input macro
 *              int     *num_outputP    : Returned number of output characters
 *              char    **outputP       : Returned pointer to a string of
 *                                          macro output
 *
 * RETURNS: In addition to return recognized output for macro in parameters,
 *          this function should return 1 if the macro is recognized, otherwise
 *          return 0.
 *
 * COMMENTS: This function is supplied by an external trainer. It's not
 *          implemented in the core.
 *-----------------------------------------------------------------------------
 */     
int 
#ifdef __WINDOWS__
__declspec( dllexport )
#endif
zo_rec_macro
    (
    int         num_input,      /* Number of input macro name   */
    char        *inputS,        /* Input macro string           */
    int         *num_outputP,   /* Number of output characters  */
    char        **outputP       /* Returned pointer to a string */
                                /*   for recognized output      */
    );
typedef int (*PFN_ZORECMACRO)
    (
    int         num_input,      /* Number of input macro name   */
    char        *inputS,        /* Input macro string           */
    int         *num_outputP,   /* Number of output characters  */
    char        **outputP       /* Returned pointer to a string */
                                /*   for recognized output      */
    );
        
#endif

#if ZORRO_TRAINABLE || ZORRO_EXTERNAL_TRAINER
/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_rec_extended_char
 *
 * PARAMETERS:   long   handle          : Handle returned by zo_open
 *               ZO_CHAR *compositionS  : Array contains the compositions
 *               int num_composition    : Number of compositions in the array
 *               ZO_RESULT *resultP     : Recognized result.
 *
 * PURPOSE:      This function only used in trainer. When the user writes a
 *               sequence of characters to train a macro or a new symbol, this
 *               function can tell if that sequence is already used by some
 *               predefined macro or previously trained macro.
 *----------------------------------------------------------------------------
 */
ZO_RET zo_rec_extended_char
    (
    long        handle,         /* Handle of this instance      */
    ZO_CHAR *compositionS,      /* Array contained compositions */
    int     num_composition,    /* Number of compositions       */
    ZO_RESULT   *resultP        /* Recognized result            */
    );

#endif

                                                            
#if ZO_DEBUG    
/*
 *----------------------------------------------------------------------------
 * API FUNCTION: zo_shape_to_result
 *
 * PARAMETERS:   unsigned int shape_index : Index of a shape
 *               ZO_CHAR  mode            : One of the PZ_MODE_* characters
 *               ZO_CHAR  *charP          : Returned result char
 *
 * PURPOSE:      This function currently only used in debugging. It takes an
 *               index to the defined shape and returns the character that
 *               shape corresponds in the given mode. 
 *----------------------------------------------------------------------------
 */
ZO_RET zo_shape_to_result
    (
    unsigned int shape_index,       /* Shape index (model index)    */
    ZO_CHAR mode,                   /* Mode                         */
    ZO_CHAR *charP                  /* Result char                  */    
    );      
#endif  /* #if ZO_DEBUG */
      
#endif

#ifdef __cplusplus
            }
#endif  /* __cplusplus */
