/***************************************************************************************
 *
 *  WRITEPAD(r): Handwriting Recognition Engine (HWRE) and components.
 *  Copyright (c) 2001-2016 PhatWare (r) Corp. All rights reserved.
 *
 *  Licensing and other inquires: <developer@phatware.com>
 *  Developer: Stan Miasnikov, et al. (c) PhatWare Corp. <http://www.phatware.com>
 *
 *  WRITEPAD HWRE is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
 *  AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
 *  INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
 *  FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL PHATWARE CORP.
 *  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL,
 *  INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
 *  INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE, SAVINGS
 *  OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR NOT PHATWARE CORP.
 *  HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
 *  POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
 *  See the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with WritePad.  If not, see <http://www.gnu.org/licenses/>.
 *
 **************************************************************************************/

#ifndef XRWORD_INCLUDED
#define XRWORD_INCLUDED

#include "ams_mg.h"
#include "hwr_sys.h"
#include "dti.h"
#include "triads.h"
#include "xr_names.h"
#include "xrwdict.h"

/* ----------------------- General Modes definitions --------------------- */

                                                              /* Private caps mode definitions                 */
#define XCM_FL_DEFSIZEp   XCM_FL_DEFSIZE                      /* First letter in accordance with voc/charset   */
#define XCM_FL_TRYCAPSp   XCM_FL_TRYCAPS                      /* Use capitals vars for first letter from voc/cs*/
#define XCM_AL_DEFSIZEp   (XCM_AL_DEFSIZE &~(XCM_FL_DEFSIZE)) /* All letters in accordance with voc/cs         */
#define XCM_AL_TRYCAPSp   (XCM_AL_TRYCAPS &~(XCM_FL_TRYCAPS)) /* Use capitals vars for all letters from voc/cs */
#define XCM_AL_TRYS4Cp    (XCM_AL_TRYS4C &~(XCM_AL_DEFSIZE))  /* Try also small vars for capitals form voc/cs  */
#define XCM_AL_RETC4AVp   XCM_AL_RETC4AV                      /* Return capitalization for all answer variants */

/* ----------------------- General Constants ----------------------------- */

#define PYSTO               0x7FFF                /* For initializaton of shorts */
#define BIG_NUMBER          32767

/* ---------------------- Corr matrix defines ---------------------------- */

/* FOR German version has to be off */
#define XRMC_SUPPRESSFCAP     OFF                   /* Do not allow capital letters at first pos, if no accenders */
#define XRMC_FLOOR             0                   /* Empty level of corr */
#define XRMC_BALLANCE_COEFF   50 //45                   /* Middle val of correlation  */
#define XRMC_CONST_CORR      100                   /* Matrix start reward        */
#define XRMC_DEF_CORR_VALUE (12+12+12+12+12 - XRMC_BALLANCE_COEFF)

#define XRMC_SEPLET_PEN        8                  /* Penalty for enforcing separate letter mode */

#define XRMC_USELEARNINF     0x01                 /* xrmcFlag to use learned vexes instead of default    */
#define XRMC_DISABLEON7      0x02                 /* xrmcFlag to disable use of var if its vex eq to 7  */
#define XRMC_DOTRACING       0x04                 /* xrmcFlag Command to create tracing info    */
#define XRMC_CHECKCAPBITS    0x08                 /* xrmcFlag Command to check capitalization bits in xrmc  (flag, internal to xrmc)  */
#define XRMC_DISABLECAPBITS  0x10                 /* xrmcFlag Command to disable use of capitalization bits in xrmc   */
#define XRMC_RESTRICTEDCAP   0x20                 /* xrmcFlag On usage of alt cap letter restrict to only not marked by DTI_CAP_BIT vars   */
#define XRMC_CACHESUSPEND    0x40                 /* xrmcFlag suspend cache usage   */
#define XRMC_CC_SIZE          26                   /* How many symbols are cached */
#define XRMC_CC_START         'a'                  /* Cache Starting symbols */
#define CC_INIT                0                   /* CacheCount commands        */
#define CC_CLOSE               1
#define CC_CLEAR               2
#define CC_CCOUNT              3
#define CC_NCCOUNT             4

#define XRMC_MAX_TRACE_BL     32                  /* Max memory blocks to take */
#define XRMC_TRACE_BL_SIZE  4080                  /* Size of single memory block */

#define XRMC_T_ISTEP         0x01
#define XRMC_T_PSTEP         0x02
#define XRMC_T_CSTEP         0x03

#define GET_XRCM_INP_XR(xrcm) ((*(xrcm)->xrinp)[xrcm->wwc_pos+xrcm->inverse].type)

/* ---------------------- XRWS defines ----------------------------------- */

#define XRWS_MAX_OUT_ANSWERS   5          /* Max number of answres in created RWS */
#define XRWS_VARBUFLEN        ON                   /* Variable len of intermediate vector storage */

#define STAT_QUAL              3          /* Weightyness of statistics  */
#define XRWS_MBUF_SIZE        12          /* XrWord temp buf size       */
#define XRWS_MIN_TAG_W  ((XRMC_CONST_CORR*4)/8) /* Floor of tag weight        */

#define XRWS_VOC_FL_CAPSFLAG 0x80         /* Flag of first letter capitalization */
#define XRWS_VOC_AL_CAPSFLAG 0x40         /* Flag of all  letters capitalization */
#define XRWS_VOCCAPSFLAG     0xC0         /* Flag for testing caps of frst letter*/

#define XRWS_MWORD_MIN         3          /* Minimal Length of XR to attach next word */
#define XRWS_MWORD_LP          8          /* Link penalty for activation of MWORD */

#define XRWS_CHECKPURE      0x0001        /* vs->filter flag for enabling c/n CheckPure filter */

#define XRWS_SSPENALTIES    0x0001        /* clp->flags flag for enabling SymSources penaties */

//#define XRWS_CHAR_WWCPENL(n)   ((n < 4) ? n*6+10 : 40) /* Combined mode char twwc penalty         */
//#define XRWS_DCHAR_WWCPENL(n)  ((n < 4) ? n*6+9  : 38) /* Combined mode char twwc penalty         */
//#define XRWS_TCHAR_WWCPENL(n)  ((n < 4) ? n*6+8  : 38) /* Combined mode char twwc penalty         */
//#define XRWS_LD_WWCPENL(n)     ((n < 4) ? n*6+4  : 34) /* Combined mode lex d twwc penalty         */

#define XRWS_LIMIT_WPENL      20   /* Combined mode char twwc penalty         */
#define XRWS_NOND_WPENL        4  /* Combined mode char twwc penalty         */
#define XRWS_VOC_WPENL         0  /* Combined mode char twwc penalty         */
#define XRWS_CHAR_WPENL        9  /* Combined mode char twwc penalty         */
#define XRWS_DCHAR_WPENL       5  /* Combined mode char twwc penalty         */
#define XRWS_TCHAR_WPENL       4  /* Combined mode char twwc penalty         */
#define XRWS_LD_WPENL          4  /* Combined mode lex d twwc penalty         */
#define XRWS_PUNCT_WPENL       2  /* Combined mode char twwc penalty         */
#define XRWS_GENERIC_WPENL     2  /* Combined mode char twwc penalty         */

#define XRWS_TRPENL(f)    ((3 - (f))) /* Weight triads penalty calculator */

//#define XRWS_CHAR_PENALIZE(w)  ((_INT)(((_LONG)(w))*89/100)-10)/* Ballance between vocabulary & chars in tags */
//#define XRWS_CHAR_PENALIZE(w)  ((_INT)(((_LONG)(w))*89/100)-10)/* Ballance between vocabulary & chars in tags */
//#define XRWS_CHAR_PENALIZE(w)  ((_INT)(((_LONG)(w))*89/100)-10)/* Ballance between vocabulary & chars in tags */
//#define XRWS_DTCHAR_PENALIZE(w) ((_INT)(((_LONG)(w))*97/100)-4)/* Ballance between vocabulary & chars in tags */

#define XRWS_CHAR_ANSWQUAL   300         /* Ballance voc & char answers in (*answr) */
#define XRWS_CHAR_ANSWLEVL    50         /* Answer level for char variants          */

#define XRWS_ESTM_LET_LEN      3         /* Estimated len of letter in XRs */
#define XRWS_XR_W_LEN_ESTM(x) ((x)/(XRWS_ESTM_LET_LEN) + 2) /* Estimated word len from number of XRs   */

#define XRWM_IS_VOC_ONLY(x) (((x) & XRWM_VOC) && ((x) & (XRWM_CS | XRWM_TRIAD | XRWM_LD)) == 0)
#define XRWM_IS_COMBINED(x) (((x) & XRWM_VOC) && ((x) & (XRWM_CS | XRWM_TRIAD | XRWM_LD)) != 0)

#define TagSize              100           /* Max value of tag buf size  */

/* --------------- Defines for punctuation extraction -------------------- */

#define MAX_PUNCT_LEN          9          /* Maximum length of punctuation in xr els */
#define ACCEPT_LEVEL         200          /* WWC weight to deal with (enough for punct) */
#define MAX_PUNCT_SYMBOLS     20          /* How many punct symbols may be */
                                                                
/* ------------------- Symbol filter states ------------------------------ */

#define XRWS_DGT_STATE     (0x01000000l)  /* State of digit charater       */
#define XRWS_CHR_STATE     (0x02000000l)  /* State of non-digit charater   */
#define XRWS_REINIT_STATE  (0x00FFFFFFl)  /* State for restarting triads from middle    */

/* ----------------- Defines for answer word flags ----------------------- */

#define XRWS_F_DIRECT_PASS  0x01        /* Flag that word was recognized from the begining */
#define XRWS_F_INVERSE_PASS 0x02        /* Flag that word was recognized from the end      */
#define XRWS_F_WWC_PASS     0x04        /* Flag that word was recognized from the end      */
#define XRWS_LPUNCT_PRESENT 0x08        /* Flag that word is carrying leading punctuation */
#define XRWS_EPUNCT_PRESENT 0x10        /* Flag that word is carrying ending punctuation */
#define XRWS_F_MULTIWORD    0x20        /* Flag that word is multiword combination */

/* ----------- Symbol Graph definitions ---------------------------------- */

#define RWS_MAX_ELS       256     /* Arbitrary number of elements in graph */
                                  /* Types of RecWordsGraph */
#define RWGT_WORD          1      /* XRWS word graph */
#define RWGT_WORDP         4      /* XRLW post-processed graph */
#define RWGT_SEPLET        2      /* Real sep-let graph */
#define RWGT_ANY           3      /* Some other graph ???? */

#define RWST_SYM           1      /* Types of RecWordsSymbol (Symbol)*/
#define RWST_SPLIT         2      /* Begin division of alternatives  */
#define RWST_JOIN          3      /* End   division of alternatives  */
#define RWST_NEXT          4      /* Begin next alternative          */

#define RWSS_NULL          0      /* Mark of null symbol (terminator of smth else ) */
#define RWSS_PREFIX        1      /* Mark that there is prefix in the beg of branch */
#define RWSS_SUFFIX        1      /* Mark that there is suffix in the end of branch */
#define RWSS_UNIDENTIFIED '_'     /* Mark that there were no variants in this graph column */

#define XRWG_ALST_EMP      0      /* Types of aliases: EmptyVoc*/
#define XRWG_ALST_DS       1      /*DoubleSkip                 */
#define XRWG_ALST_VS       2      /*VocSkip,                   */
#define XRWG_ALST_CR       3      /*Corr,                      */

/* ---------------------- XRW Learn define ------------------------------- */

#define MaxVarGather          80                   /* Vars for let to gather     */
#define XRWL_MAXW            300

#define LDEL_NOVARS            1              /* Defines for cause of var del (learn) */
#define LDEL_NOTUNIQ           2              /* Defines for cause of var del (learn) */



/* ######################### Structures #################################### */

/* ----------- Character filters' handle --------------------------------- */

typedef struct
{
    p_VOID        hcfl;
    p_VOID        pcfl;
    _CHAR         cflname[40];
} cflptr_type, _PTR p_cflptr_type;


/* ----------- Matrix counting ------------------------------------------- */

/* Work area tracing structures */

typedef struct
{
    _UCHAR         sym;            /* Symbol itself  */
    _UCHAR         xr;             /* XRP itself  */
    _UCHAR         st;             /* Start (on xrinp) of the xrp vector  */
    _UCHAR         len;            /* Length of xrp vector  */
    _UCHAR         vects[XRINP_SIZE]; /* Direction vectors (Not to its full length !!!)*/
} xrp_hdr_type, _PTR p_xrp_hdr_type;

typedef struct
{
    _UCHAR         sym;            /* Symbol itself  */
    _UCHAR         var_num;        /* Number of variant  */
    _UCHAR         var_len;        /* Number of xr's in the variant  */
    p_xrp_hdr_type xhdrs[DTI_XR_SIZE]; /* Pointers to XRP headers  */
} var_hdr_type, _PTR p_var_hdr_type;

typedef struct
{
    _UCHAR         sym;            /* Symbol itself  */
    _UCHAR         num_vars;       /* Max number of vars in sym  */
    _UCHAR         v_start;        /* Start pos of merging index  */
    _UCHAR         v_end;          /* End position of merging index  */
    p_var_hdr_type vhdrs[DTI_MAXVARSPERLET]; /* Pointers to var headers */
    _UCHAR         merge_vect[XRINP_SIZE]; /* Merging index  */
} sym_hdr_type, _PTR p_sym_hdr_type;

typedef struct
{
    _UCHAR         syms[2];        /* Cap/decap symbols  */
    _INT           v_start;        /* Start pos of merging index  */
    _INT           v_end;          /* End position of merging index  */
    p_sym_hdr_type shdrs[2];       /* Pointers to symbols headers  */
    _UCHAR         merge_vect[XRINP_SIZE]; /* Merging index  */
} let_hdr_type, _PTR p_let_hdr_type;

typedef struct
{
    p_UCHAR       mem[XRMC_MAX_TRACE_BL]; /*  Pointer to allocated memory */
    p_UCHAR       cur_mem;         /*  Current memory pool */
    p_SHORT       ma;
    _INT          ma_loc;
    _INT          cur_block;       /*  Size of allocated memory */
    _INT          mem_used;        /*  Amount of memory used */
    p_let_hdr_type lhdrs[w_lim];    /*  Pointers to letter headers */
} trace_hdr_type, _PTR p_trace_hdr_type;

    /* Trace Results structures */

    typedef struct
{
    _UCHAR        inp_pos;         /* XrInp position of tr el*/
    _UCHAR        xrp_num;         /* XRP position of tr el */
    _UCHAR        vect;            /* Type of step made */
    _UCHAR        emp;             /* empty now, padding */
} tr_pos_type, _PTR p_tr_pos_type;

typedef struct
{
    _UCHAR        realsym;         /* Real letter used */
    _UCHAR        var_num;         /* Num of used variant */
    _UCHAR        len;             /* Length of real trace for letter */
    _UCHAR        beg;             /* XrInp start of letter */
    _UCHAR        end;             /* XrInp end of letter */
    tr_pos_type   trp[XRINP_SIZE + DTI_XR_SIZE]; /* Trace positions for the letter (Not will be used in full !!)*/
} letlayout_hdr_type, _PTR p_letlayout_hdr_type;

typedef struct
{
    p_UCHAR       mem;             /*  Pointer to allocated memory */
    _INT          mem_size;        /*  Size of allocated memory */
    _INT          mem_used;        /*  Amount of memory used */
    p_letlayout_hdr_type llhs[w_lim];     /*  Pointers to letter headers */
} wordlayout_hdr_type, _PTR p_wordlayout_hdr_type;


typedef struct
{
    _SCHAR        dw;              /* Delta change of weight    */
    _UCHAR        pos;             /* Position of end of letter */
} xrcm_cc_el_type, _PTR p_xrcm_cc_el_type;

typedef xrcm_cc_el_type  xrcm_cc_pos_type[DTI_NUMSYMBOLS];
typedef xrcm_cc_pos_type xrcm_cc_type[XRINP_SIZE];
typedef xrcm_cc_type _PTR p_xrcm_cc_type;

typedef _SHORT cline_type[XRINP_SIZE];
typedef cline_type _PTR p_cline_type;

typedef struct
{
    _UCHAR        st;
    _UCHAR        end;
} st_end_type, _PTR p_st_end_type;

/* ----------------------------- XRCM -----------------------------------------*/

typedef struct
{
    // --------- XRP  Matrix -------------
    
    _INT          inp_start;               /* One xr inp count range */
    _INT          inp_end;                 /*   */
    
    p_cline_type  inp_line;                /* Address of source vect  */
    p_cline_type  out_line;                /* Address of output vect (may be the same)  */
    
    p_xrp_type    xrp;                     /* Address of prototype xr to count */
    xrinp_type    (_PTR xrinp)[XRINP_SIZE];/* Input xr line pointer  */
    p_xrp_hdr_type xrp_htr;                 /* XRP level trace buffer ptr */
    
    // --------- Var Matrix --------------
    
    _INT          inverse;                 /* Direction flag  */
    _INT          var_len;                 /* Prototype length */
    _INT          src_st;                  /* Source line valid values range  */
    _INT          src_end;                 /*   */
    _INT          src_pos;                 /* Estimated wwc position  */
    _INT          res_st;                  /* Resulting line valid values range  */
    _INT          res_end;                 /*   */
    _INT          count_mode;              /* Sector or full count of prototype  */
#if DTI_COMPRESSED
    p_dte_var_header_type    xrpv;                    /* Address of prototype var to count */
#else
    p_xrp_type    xrpv;
#endif
    p_var_hdr_type var_htr;                 /* Var level trace buffer ptr */
    
    // --------- Sym Matrix --------------
    
    _UCHAR        sym;                     /* Symbol to process  */
    _INT          flags;                   /* Flags for controllin XRMC  */
    p_dte_sym_header_type sfc;                     /* Sym header pointer  */
#if DTI_COMPRESSED
    p_dte_index_type plt;                     /* RAM/ROM index table with pallettes */
#endif
    st_end_type   vste[DTI_MAXVARSPERLET]; /* St and end positions of counted variants (inp pos)  */
    p_sym_hdr_type sym_htr;                 /* Sym level trace buffer ptr */
    _UCHAR        vb[DTI_MAXVARSPERLET];   /* Copy of vex buffer */
    
    _SHORT        svm;                     /* Bit masks of allowed variants */
    // --------- Letter Matrix -----------
    
    _UCHAR        let;                     /* Letter to process  */
    _INT          cmode;                   /* Capitalization flags for the letter */
    _INT          merge_results;           /* Flag of mixing output line values  */
    _INT          switch_to_best;          /* Flag to change output line to one having best WWC  */
    p_let_hdr_type let_htr;                 /* Let level trace buffer ptr */
    
    // --------- Word Matrix -------------
    
    _UCHAR        word[w_lim];             /* Word to count  */
    _INT          trace_end;               /* End pos to start trace from */
    _SHORT        var_mask[w_lim];         /* Bit masks of allowed variants */
    _SHORT        letter_weights[w_lim];   /* Weight of letters in the word */
    p_trace_hdr_type  p_htrace;                /* Pointer to trace memory header */
    
    // --------- General info ------------
    
    _INT          caps_mode;               /* Capitalization flags  */
    _INT          corr_mode;               /* Correlation compare mode  */
    _INT          en_ww;                   /* Enabled writing ways  */
    _INT          en_languages;            /* Enabled languages     */
    _INT          bad_amnesty;             /* WWC count constant  */
    _INT          xrinp_len;               /* Inp sequence length  */
    _INT          allocated;               /* Size of xrcm allocation */
    
    // --------- Results -----------------
    
    _UCHAR        realsym;                 /* Winning symbol  */
    _UCHAR        wwc_delt;                /* WWC dif betw realsym & sym */
    
    _UCHAR        nvar_vect[XRINP_SIZE];   /* Vect of var nums for the last sym */
    _INT          v_start;                 /* Global result vector valid values range  */
    _INT          v_end;                   /*   */
    
    _INT          wc;                      /* Weight at WWC_pos   */
    _INT          wwc;                     /* WWC at wwc_pos  */
    _INT          wwc_pos;                 /* Pos of max WWC  */
    _INT          end_wc;                  /* Corr value at line end  */
    
    _INT          self_weight;             /* Self weight of inp seq  */
    
    _INT          cur_ba;                  /* Current bad amnesty */
    
    p_wordlayout_hdr_type  p_hlayout;               /* Pointer to done word layout header */
    
    // --------- Pointers to storage -----
    
    p_cline_type  s_inp_line;              /* Pointer to inp vector  */
    p_cline_type  s_out_line;              /* Pointer to out vector  */
    p_cline_type  s_res_lines[DTI_MAXVARSPERLET];/* Pointers to var in/out vectors  */
    
    p_SHORT       p_self_corr;             /* Pointer to WWC reference line  */
    
    _ULONG        cc_size;                 /* Cache size  */
    p_xrcm_cc_type  cc;                      /* CacheCount data buffer  */
    
    p_dti_descr_type p_dte;                   /* DTE main table pointer*/
    p_dte_vex_type vexbuf;                  /* Allocated VEX buffer  */
    _UCHAR         link_index[XRINP_SIZE];  /* Splits locations and numbers for cache and rest */
    
    // --------- Debug -------------------
    
    _INT          cur_let_num;             /* Number of Current letter */
    _INT          cur_alt_num;             /* Num of current alternative (cap/decap)  */
    _INT          cur_var_num;             /* Number of current variant  */
    
} xrcm_type, _PTR p_xrcm_type;           /*   */

typedef struct
{
    _UCHAR         num_best_alt;     /* Num of lib alt used for recog */
    _UCHAR         xrinp_st;         /* St of corr for alt on xrinp   */
    _UCHAR         xrvoc_st;         /* St of corr on xrvoc           */
} w_alts_type;

/* ----------- XrWord ---------------------------------------------------- */

typedef signed char punct_buf_type[2][MAX_PUNCT_SYMBOLS][MAX_PUNCT_LEN+2];

typedef struct
{
    _INT          weight;
    _INT          trace_pos;
    _INT          mbuf_st;
    _INT          penalty;           /* Cur sequence gathered penalty */
    _INT          ppd_penalty;       /* Set by in-xrws-PPD to qualify the tag */
    _INT          prev_ppd_seg;      /* To what loc prev PPD was counted (xr) */
    _INT          prev_ppd_wsg;      /* To what loc prev PPD was counted (let)*/
    _INT          flags;             /* Word flags */
    _INT          best_count;
    _INT          word_offset;       /* Num let of word's last init    */
    _UCHAR        word[w_lim];
    _UCHAR        realword[w_lim];
    _UCHAR        wwc_delt[w_lim];
    _INT          sym_srcs_mask;
    fw_buf_type    l_sym;
    _SHORT        tagmattr[XRWS_MBUF_SIZE];
} tag_type, _PTR p_tag_type;

typedef struct
{
    _INT          weight;
    _INT          penl;
    _INT          stat;
    _INT          percent;
    _INT          flags;
    _INT          sources;
    _INT          chain_num;
    _INT          src_id;
    _CHAR         word[w_lim];
    _CHAR         realword[w_lim];
    _UCHAR        wwc_delt[w_lim];
} answ_type, _PTR p_answ_type;


typedef struct
{
    p_UCHAR        mem;
    _INT           tag_size;
    _INT           answr_size;
    _INT           cd_mode;
    answ_type      (_PTR answr)[NUM_RW];
    tag_type       (_PTR tags0)[TagSize];
    tag_type       (_PTR tags1)[TagSize];
    punct_buf_type  _PTR punct_buf;
    fw_buf_type    (_PTR fbuf)[XRWD_MAX_LETBUF];
    fw_buf_type    (_PTR fwb)[XRWD_MAX_LETBUF];
    _UCHAR         (_PTR charset)[256];
} xrw_alloc_type;

typedef struct
{
    _INT           lstep;
    _INT           tag_size;
    _INT           flags;
    _INT           cd_mode;
    _INT           caps_mode;
    _INT           fl_cmode;
    _INT           al_cmode;
    _INT           f_last_dict;
    _INT           xrw_max_wlen;
    _INT           xrw_min_wlen;
    _INT           xrw_mode;
    _INT           bad_level;
    _INT           max_finished_tagw;
    
    p_xrcm_type    xrcm;
    tag_type       (_PTR in_tags)[TagSize];
    tag_type       (_PTR out_tags)[TagSize];
    answ_type      (_PTR answr)[NUM_RW];
    lex_data_type  _PTR vs;
    _UCHAR         st_punct[MAX_PUNCT_SYMBOLS]; /* symbols of ending punctuation */
    _UCHAR         end_punct[MAX_PUNCT_SYMBOLS]; /* symbols of ending punctuation */
    punct_buf_type _PTR punct_buf;
    fw_buf_type    (_PTR fbuf)[XRWD_MAX_LETBUF];
    fw_buf_type    (_PTR fwb)[XRWD_MAX_LETBUF];
} clp_type, _PTR p_clp_type;

/* ----------- Batch Learning -------------------------------------------- */

#define XRWL_MAXSYMS     12
#define XRWL_LRNSUFFLEV  50

typedef struct
{
    xrdata_type   _PTR xrd;
    p_UCHAR        word;
    PS_point_type _PTR trj;
} xrwlearn_type;

typedef struct
{
    _SHORT        class_level;
    _SHORT        min_class_size;
    _SHORT        learn_suff;
    _SHORT        vocvar_reward;
} xrwlp_type;

typedef struct
{
    _WORD         num  : 4;       /* Number of class        */
    _WORD         del  : 4;       /* Reason of deletion     */
    _WORD         best : 1;       /* Best variant of class  */
    _WORD         lib  : 1;       /* Copied from default lib*/
} xlclass_type;

typedef struct
{
    _USHORT       next;           /* Short pointer to next  */
    _USHORT       num;            /* Num of w., where it was found or var_xr num*/
    xlclass_type  xlclass;        /* Class num and flags    */
    _UCHAR        xrd_beg;        /* Beg num of xrdata      */
    _UCHAR        xrd_len;        /* Len of corresp str     */
    _SHORT        maxw;           /* Max corr on ally voc v */
    _SHORT        nvars;          /* Num vars got or belong */
    _UCHAR        var_track;      /* Bit map of ally voc v  */
    _UCHAR        syms[XRWL_MAXSYMS];/* Alien syms          */
} lv_descr_type;

typedef struct
{
    _SHORT        pc_ally;        /* Perc. of ally inp v. got  */
    _SHORT        pc_unique;      /* % of uniquely got ally v. */
    _SHORT        pc_alien;       /* Sum % of got aliens       */
}libv_info_type;

/* ----------- Punctuation ----------------------------------------------- */

typedef struct
{
    _CHAR   stp;            // Starting punc symbol
    _CHAR   lstp;           // Length of start punc cutted
    _INT    wstp;           // Weight of start punc
    
    _CHAR   enp;
    _CHAR   lenp;
    _INT    wenp;
} punct_type, _PTR p_punct_type;

/* ----------- Symbol Graph definitions ---------------------------------- */

typedef struct
{                  /* Type, defining graph element             */
    _UCHAR  sym;      /* Symbol from the answer                   */
    _UCHAR  realsym;  /* Symbol really used for recognition (Cap) */
    _UCHAR  type;     /* Type of symbol: Normal/Split/Join/Alt    */
    _UCHAR  nvar;     /* Number of prototype used                 */
    _UCHAR  xrd_beg;  /* Num of begining xr-el of XrData, corresponding */
    _UCHAR  xrd_len;  /* Length of XrData string, corresponding   */
    _UCHAR  weight;   /* Percent of quality of the symbol sequence sym in */
    _UCHAR  lexw;     /* Some lexical penalties by xrw or so      */
    _SCHAR  sidew;    /* Weight for the word by side reasoning    */
    _SCHAR  letw;     /* Weight added by this letter              */
    _SCHAR  src_id;   /* ID of source of appearance of the symbol */
    _SCHAR  ppdw;     /* PPD estimate for the symbol              */
    _SCHAR  ortow;    /* ORTO estimate for the symbol             */
    _UCHAR  attr;     /* Some attribute (voc attribute)           */
    _UCHAR  d_user;   /* Here can be temp user storage byte       */
} RWS_type, _PTR p_RWS_type;

typedef struct
{                  /* Type, defining PPD element               */
    _UCHAR      alias;/* Number of XrData xr, corresponding to this */
    _UCHAR      type; /* Type of correspondence - VocSkip, InpSkip, Corr */
} RWG_PPD_el_type, _PTR p_RWG_PPD_el_type;

typedef RWG_PPD_el_type RWG_PPD_type[DTI_XR_SIZE+1]; /* Type, def PPD letter */
typedef RWG_PPD_type _PTR p_RWG_PPD_type;

/* ------------------------ Misc ------ ------------------------------------ */


/* ######################### Prototypes #################################### */

/* ------------------------ XrWord Main ------------------------------------ */
_INT     xrw_algs(p_xrdata_type xrdata, rec_w_type (_PTR rec_words)[NUM_RW], p_RWG_type rwg, rc_type  _PTR rc);
/* -------------------------- XrWordS -------------------------------------- */

_INT     xrws(p_xrdata_type xrdata, p_RWG_type rwg, rc_type  _PTR rc);

_INT     CalculateNextTag(clp_type _PTR clp);
_INT     GetFollowers(lex_data_type _PTR vs, fw_buf_type (_PTR fbuf)[XRWD_MAX_LETBUF], fw_buf_type (_PTR fwb)[XRWD_MAX_LETBUF]);
_INT     GF_TriadSymbolSet(lex_data_type _PTR vs, fw_buf_type (_PTR fwb)[XRWD_MAX_LETBUF]);
_INT     GF_CharsetSymbolSet(lex_data_type _PTR vs, fw_buf_type (_PTR fwb)[XRWD_MAX_LETBUF]);
_INT     GF_PunctSymbolSet(lex_data_type _PTR vs, fw_buf_type (_PTR fwb)[XRWD_MAX_LETBUF]);
_INT     AddSymbolSet(_INT type, fw_buf_type (_PTR fwb)[XRWD_MAX_LETBUF], fw_buf_type (_PTR fbuf)[XRWD_MAX_LETBUF]);
_INT     AskTagLoc(tag_type (_PTR tag)[TagSize], _INT   tag_size, _INT weight, lex_data_type _PTR vs);
_INT     PutInAnsw(_INT iw, _INT penl, lex_data_type  _PTR vs, answ_type (_PTR answ)[NUM_RW]);
_INT     CheckDone(tag_type (_PTR tags)[TagSize], _INT   num_tags, _INT   threshold);
_INT     CapAnswers(_INT caps_mode, answ_type (_PTR answ)[NUM_RW]);
_INT     CheckCapitalization(p_RWG_type rwg, p_rc_type rc);
_INT     CleanGraph(p_RWG_type rwg);
_INT     CheckWeights(answ_type (_PTR answ)[NUM_RW], p_RWG_type rwg);
_INT     SortGraph(_INT (_PTR index)[NUM_RW], p_RWG_type rwg);
_INT     SetWeights(p_RWG_type rwg, answ_type (_PTR answ)[NUM_RW]);
_INT     FillRWG(_INT answer_level, _INT answer_allow, p_RWG_type rwg, answ_type (_PTR answr)[NUM_RW]);
_INT     ZeroTag(tag_type (_PTR tag)[TagSize], _INT   tag_size);
_INT     CleanTags(p_lex_data_type vs, _INT prev_tag_w, _INT bad_dist, _INT tag_size, tag_type (_PTR tags)[TagSize]);
_INT     SortTags(_INT tag_size, tag_type (_PTR tags)[TagSize]);
_INT     SortAnsw(_INT self_w, answ_type (_PTR answ)[NUM_RW], _INT (_PTR index)[NUM_RW]);
_INT     GetAnswAttributes(lex_data_type _PTR vs, answ_type (_PTR answr)[NUM_RW]);
_INT     TriadCheck(_UCHAR sym, p_ULONG state, lex_data_type _PTR vs);
_INT     GetTriadAnswPenalty(lex_data_type _PTR vs);
_INT     CheckPure(_UCHAR sym, p_ULONG state, lex_data_type _PTR vs);
_INT     PunctPreCalc(p_clp_type clp, rc_type _PTR rc);
_INT     PpTags(_INT lstep, p_xrcm_type xrcm, _INT tag_size, tag_type (_PTR tags)[TagSize]);
_INT     AdjustWWC(_INT weight, _INT trace_pos, p_xrcm_type xrcm);
_INT     xrw_mem_alloc(xrw_alloc_type _PTR memptr);
_INT     xrw_mem_dealloc(xrw_alloc_type _PTR memptr);

/* --------------------------  xrSpl  -------------------------------------- */

_INT     xr_spl(p_xrdata_type xrdata, p_RWG_type rwg, rc_type  _PTR rc);

/* --------------------------  XrLet  -------------------------------------- */

_INT     xrlw(p_xrdata_type xrdata, p_RWG_type rwg, rc_type  _PTR rc);

/* -------------------------- XrW_Util ------------------------------------- */

_INT     GetCharset(p_UCHAR charset, _INT   cs_size, rc_type _PTR rc);
_INT     GetBaseBord(p_rc_type rc);
_INT     GetSymBox(_UCHAR sym, _INT st, _INT end, p_xrdata_type xrdata, p_RECT box, _INT lang );

/* --------------------------- xr_mc ------------------------------------*/

_INT     xrmatr_alloc(rc_type _PTR rc, p_xrdata_type xrd, p_xrcm_type _PTR xrcm);
_INT     xrmatr_dealloc(p_xrcm_type _PTR xrcm);
_INT     change_direction(_INT change_to, p_xrcm_type xrcm);
_INT     CacheCount(_INT mode, p_xrcm_type xrcm);
_INT     CountWord(p_UCHAR word, _INT caps_mode, _INT flags, p_xrcm_type xrcm);
_INT     CountLetter(p_xrcm_type xrcm);
_INT     CountSym(p_xrcm_type xrcm);
_INT     CountVar(p_xrcm_type xrcm);
_INT     CountXrC(p_xrcm_type xrcm);
_INT     TCountXrC(p_xrcm_type xrcm);
_INT     MergeVarResults(p_xrcm_type xrcm);
_INT     SetInitialLine(_INT count, p_xrcm_type xrcm);
_INT     SetInpLine(p_SHORT p_line, _INT st, _INT count, p_xrcm_type xrcm);
_INT     SetInpLineByValue(_INT value, _INT st, _INT count, p_xrcm_type xrcm);
_INT     GetOutTB(_SHORT (_PTR tb)[XRWS_MBUF_SIZE], _INT trace_pos, p_xrcm_type xrcm);
_INT     GetOutLine(p_SHORT p_line, _INT st, _INT count, p_xrcm_type xrcm);
_INT     SetOutLine(p_SHORT p_line, _INT st, _INT count, p_xrcm_type xrcm);
_INT     MergeWithOutLine(p_SHORT p_line, _INT st, _INT count, p_xrcm_type xrcm);
_INT     GetFinalWeight(p_xrcm_type xrcm);
_INT     TraceAlloc(_INT wl, p_xrcm_type xrcm);
_INT     TraceDealloc(p_xrcm_type xrcm);
_INT     CreateLayout(p_xrcm_type xrcm);
_INT     FreeLayout(p_xrcm_type xrcm);
p_VOID   TDwordAdvance(_INT size, p_xrcm_type xrcm);
_INT     SetWWCLine(_INT ba, p_xrcm_type xrcm);
_INT     FillLetterWeights(p_SHORT ma, p_xrcm_type xrcm);
_INT     TraceAddAlloc(p_xrcm_type xrcm);

/* --------------------- XrwLearn ---------------------------------------*/

_SHORT   XrwLearn(rc_type _PTR rc, xrwlearn_type (_PTR xrwl)[XRWL_MAXW], xrwlp_type _PTR params);
_SHORT   ExtractLetVariants(rc_type _PTR rc, xrwlearn_type (_PTR xrwl)[XRWL_MAXW], xrwlp_type _PTR params, void _PTR llv);
_SHORT   Analyser(rc_type _PTR prc, xrwlearn_type (*xrwl)[XRWL_MAXW], xrwlp_type *params, void *llv);
_SHORT   MarkDelete(xrwlearn_type (*xrwl)[XRWL_MAXW], xrwlp_type *params, void *llv);
_SHORT   MarkAdd(rc_type _PTR rc, xrwlearn_type (*xrwl)[XRWL_MAXW], xrwlp_type *params, void *llv);
_SHORT   Classificator(_UCHAR ch, rc_type _PTR rc, xrwlearn_type (*xrwl)[XRWL_MAXW], xrwlp_type *params, void *llv);
_SHORT   SameSymCorr(_UCHAR ch, rc_type _PTR rc, xrwlearn_type (*xrwl)[XRWL_MAXW], xrwlp_type *params, void *llv);
_SHORT   OtherSymCorr(_UCHAR sch, _UCHAR och, rc_type _PTR rc, xrwlearn_type (*xrwl)[XRWL_MAXW], xrwlp_type *params, void *llv);
_SHORT   SymMarkDel(_UCHAR ch, xrwlearn_type (*xrwl)[XRWL_MAXW], xrwlp_type *params, void *llv);
_SHORT   LCellToXrData(_UCHAR ch, lv_descr_type _PTR lvci, xrwlearn_type (*xrwl)[XRWL_MAXW], p_dti_descr_type dp, xrdata_type (_PTR xrd)[DTI_XR_SIZE*2]);
_SHORT   LCellToXVB(_UCHAR ch, lv_descr_type _PTR lvci, xrwlearn_type (*xrwl)[XRWL_MAXW], p_dti_descr_type dp, xrinp_type (_PTR xrv_buf)[DTI_XR_SIZE*2]);
_SHORT   CheckResult(p_VOID dp, xrwlearn_type (_PTR xrwl)[XRWL_MAXW], p_VOID llv);
_SHORT   PrepareDT(void _PTR dp, xrwlearn_type (_PTR xrwl)[XRWL_MAXW], void _PTR llv);
_SHORT   ViewELV(void _PTR dp, xrwlearn_type (_PTR xrwl)[XRWL_MAXW], xrwlp_type _PTR params, void _PTR llv);
_SHORT   ViewLR(void _PTR dp, xrwlearn_type (_PTR xrwl)[XRWL_MAXW], xrwlp_type _PTR params, void _PTR llv);
_SHORT   XLAlloc(void _PTR dp, xrwlearn_type (_PTR xrwl)[XRWL_MAXW], xrwlp_type _PTR params, void _PTR _PTR llv);
_SHORT   XLDeAlloc(void _PTR _PTR llv);

/* -------------------- Statics -----------------------------------------*/

#if  !defined(ParaLibs_j_c) 
RECO_DATA_EXTERNAL _UCHAR let_stat[128];
RECO_DATA_EXTERNAL _INT   xrwd_src_ids[XRWD_N_SRCS];
RECO_DATA_EXTERNAL _UCHAR tr_sym_set[];
RECO_DATA_EXTERNAL _UCHAR ldb_sym_set[];
#endif /* ParaLibs_j_c */

/* -------------------- Misc --------------------------------------------*/

_INT      xrp_ave_val(p_UCHAR pc, _INT len);


/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* +        Here are specific analysis functions prototypes +++++++++++++++++ */
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

_INT  xxx(xrdata_type (_PTR xrdata)[XRINP_SIZE], rec_w_type (_PTR rec_words)[NUM_RW], rc_type  _PTR rc);
_INT  xxx_init(rc_type  _PTR rc);
_INT  xxx_close(char * fname);

_INT  xxx_ha(xrdata_type (_PTR xrdata)[XRINP_SIZE], rec_w_type (_PTR rec_words)[NUM_RW], rc_type  _PTR rc);

void DumpTags(_INT tag_size, tag_type (_PTR tags)[TagSize]);

#endif  /*  XRWORD_INCLUDED.  */

