/********************************************************************/
/*                                                                  */
/* Project: MAT.EXE                                                 */
/*                                                                  */
/* Header:  EXPIMP.H                                                */
/*                                                                  */
/* Purpose: MAT export/import with WordPerfect & Word for Windows   */
/*                                                                  */
/* Author:  Tomas RYLEK                                             */
/*                                                                  */
/********************************************************************/

#ifndef __EXPORT_IMPORT__
#define __EXPORT_IMPORT__

#define DEBUG 0

#include <stdarg.h>
#include "mat.h"

/*************************** debug support **************************/

#if DEBUG
#define __leftError() int_error(format(__FILE__ ", %d: "
#define __showError(e) __leftError() e, __LINE__))
#define isTrue(x) if(x) ; else __showError("false " #x)
#define neverComes() __showError("invalid variant")
#ifdef __FLAT__
int __IntResult();
#pragma aux __IntResult = "" value [eax];
long __LongResult();
#pragma aux __LongResult = "" value [eax];
#else
inline int __IntResult() { return _AX; }
inline long __LongResult() { return _AX + 65536L * _DX; }
#endif
#define fnReturns(x) \
	{ \
		static int i = __IntResult(); \
		if(i != x) \
			__leftError() "returns %d instead of %d", __LINE__, i, (x))); \
	}
#define fnReturnsLong(x) \
	{ \
		static long l = __LongResult(); \
		if(l != x) \
			__leftError() "returns %ld instead of %ld", __LINE__, i, (x))); \
	}
#define returnsNonzero() if(__IntResult()) ; else __showError("returns zero")
#define returnsZero() if(!__IntResult()) ; else __showError("returns nonzero")
#define ifDebug(x) x
#else
#define isTrue(x)
#define neverComes()
#define fnReturns(x)
#define fnReturnsLong(x)
#define returnsZero()
#define returnsNonzero()
#define ifDebug(x)
#endif

/****************************** macros ******************************/

#define elemOf(var) (sizeof(var) / sizeof(*(var)))

/******************************* types ******************************/

#define VOID                void

#ifdef __FLAT__
#define FAR
#define NEAR
#define HUGE
#define PASCAL
#define CDECL
#else
#define FAR                 far
#define NEAR                near
#define HUGE                huge
#define PASCAL              pascal
#define CDECL               cdecl
#endif

/****** Simple types & common helper macros *********************************/

typedef int                 BOOL;
#define FALSE               0
#define TRUE                1

typedef unsigned char       BYTE;
typedef unsigned short      WORD;
typedef unsigned long       DWORD;
typedef unsigned int        UINT;
typedef signed long         LONG;

#ifndef max
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

/****** Common pointer types ************************************************/

#ifndef NULL
#define NULL                0
#endif

typedef char NEAR*          PSTR;
typedef char NEAR*          NPSTR;


typedef char FAR*           LPSTR;
typedef const char FAR*     LPCSTR;

typedef BYTE NEAR*          PBYTE;
typedef BYTE FAR*           LPBYTE;

typedef int NEAR*           PINT;
typedef int FAR*            LPINT;

typedef WORD NEAR*          PWORD;
typedef WORD FAR*           LPWORD;

typedef LONG NEAR*          PLONG;
typedef LONG FAR*           LPLONG;

typedef DWORD NEAR*         PDWORD;
typedef DWORD FAR*          LPDWORD;

typedef void FAR*           LPVOID;

#ifndef __FLAT__
#define MAKELP(sel, off)    ((void FAR*)MAKELONG((off), (sel)))
#define SELECTOROF(lp)      HIWORD(lp)
#define OFFSETOF(lp)        LOWORD(lp)
#endif

#define FIELDOFFSET(type, field)    ((int)(&((type NEAR*)1)->field)-1)

/* macros */

#define local(type)   static type FAR PASCAL /* local function           */
#define global(type)  type FAR PASCAL        /* global within MAT system */
#define cglobal(type) type FAR CDECL         /* global for FIDLER        */

/* constants */

enum
{
	READ_MODE       = 0,
	WRITE_MODE      = 1,
	TAB_GRAIN       = 5,         /* tab distance                     */
	DOT_LIMIT       = 5,         /* minimum dots to guess table      */

	OUTPUT_MAT_LINE =  60,       /* line width for import            */
	MAX_LEFT_MARGIN =  50,       /* maximum left margin              */
	MIN_RGHT_MARGIN =  10,       /* minimum right margin             */
	MIN_GAP         =  10,       /* minimum gap between margins      */
	TEMP_BUF_OFFSET =  80,       /* offset of buffer within MAT line */
	TAB_OFFSET      = 160,       /* offset of 2nd buffer             */

	WPU_TO_MAT      = 120,       /* wpus per 1 mat character         */
};

/* types */

typedef char HUGE *pointer;

typedef struct /* MWP options */
{
	int autoCTR; /* 1 = guessing centered / right aligned lines */
}
str_export_options;

typedef struct /* info about MAT file */
{
	int tab1; /* 1st tab stop */
	int cml;  /* currently active left margin */
	int cmr;  /* currently active right margin */
	int ctr2; /* line centre * 2 */
}
mat_info_type;

typedef struct /* info about MAT line */
{
	char eof;     /* 1 = end of file */
	char full;    /* 1 = this line is not empty */
	char hardCR;  /* hard-CR after this line */
	char hardFF;  /* hard page before this line */
	char spacing; /* line spacing */
	char hyphen;  /* hyphenation detected */
	char table;   /* this line is probably part of a table */

#define SPACING_1_0 1
#define SPACING_1_5 2
#define SPACING_2_0 3

	char align;   /* guessed alignment type */
	char malign;  /* unconstrained alignment type */

#define LA_LEFT   0
#define LA_CENTRE 1 /* bitfield combined with LA_RIGHT in malign */
#define LA_RIGHT  2

	int left;  /* position of 1st non-blank character */
	int right; /* position of last non-blank character */
	int spc1;  /* width of space after 1st word */
	int lpw2;  /* logical position of 2nd word in line */

	int title; /* title level or 0 if this is no title */
}
mat_line_type;

typedef struct /* paragraph description */
{
	char eof;    /* end of text, no paragraph */
	char full;   /* 1 = some text in paragraph; 0 = 1 blank line */
	char hardFF; /* hard FF before paragraph */
	char align;  /* paragraph alignment (same as LA_???) */
	char table;  /* this paragraph probably contains a table */

	int left;    /* left shoulder of paragraph */
	int left0;   /* left shoulder of 1st paragraph line */
	int left1;   /* left shoulder of 1st paragraph line - dynamic */
	int lines;   /* number of lines in paragraph */
	
	int title;   /* when nonzero, para is this level 1 line title */
}
mat_para_type;

typedef struct /* WP 5.x file header */
{
	long flag;

#define WP_FLAG (0xFFL + 0x100L * 'W' + 0x10000L * 'P' + 0x1000000L * 'C')

	long   start_of_document;
	BYTE   product_type;
	BYTE   file_type;
	BYTE   major_version;
	BYTE   minor_version;
	short  encryption_key;
	short  reserved;
}
str_wp5x_header;

typedef struct /* current state of WP file processor */
{
	BYTE bTabType[OUTPUT_MAT_LINE]; /* tab flags */

/* low 2 bits hold one of the JU_??? constants */
#define TAB_DOT    4
#define TAB_UNUSED ((BYTE)-1)

	WORD line_height;   /* (wpu) line height, 0 = auto line height */
	int  wTLMargin;     /* (wpu) temporary left margin */
	int  wTRMargin;     /* (wpu) temporary right margin */
	char justification; /* justification mode (one of the JU_???'s) */

#define JU_LEFT    0
#define JU_FULL    1
#define JU_CENTRE  2
#define JU_RIGHT   3

	char modfs;      /* size modifier */

#define MS_NORMAL       0
#define MS_EXTRA_LARGE  1
#define MS_VERY_LARGE   2
#define MS_LARGE        3
#define MS_SMALL        4
#define MS_FINE         5

	char underline_mode; /** underline mode - ignored at present */

#define UM_SPACES 1
#define UM_TABS   2

	int  attrib;       /* appearance attributes */

#define AT_SMALL_CAPS TUS1
}
WP_STATE[1], *PWP_STATE;

/* data */

extern jmp_buf error_pointer; /* common error exit vector */
extern long    pgss_total; /* total for progress show functions */
extern int     progress;
extern int     global_code;

extern mat_info_type mat_info;

extern str_export_options export_options; /* options for MAT export    */
extern pointer txtptr; /* current input text pointer (within MAT file) */
extern pointer txtlim; /* MAT input text limit                         */
extern pointer outptr; /* current output text pointer                  */
extern long    Biglen; /* maximum text length                          */
extern int     lshort; /* no right halves when set                     */

extern mat_line_type linfo;
extern mat_para_type pinfo;

/* functions */

/********************************************************************/
/********************************************************************/
/*                                                                  */
/*                   Common source for all filters.                 */
/*                                                                  */
/********************************************************************/
/********************************************************************/

global(int)        bind(int l, int x, int h);
#ifndef __FLAT__
global(LPVOID)     floor_seg(void HUGE *x);
global(LPVOID)     hpnorm(void HUGE *ptr);
#endif//ifndef
global(BOOL)       istable(BYTE x);
global(int)        isbound(int l, int x, int h);
global(int)        islbound(long l, long x, long h);
global(int)        imax(int x, int y);
global(int)        imin(int x, int y);
global(unsigned)   umin(unsigned x, unsigned y);
global(long)       lmin(long x, long y);
global(int)        ilbind(int l, long x, int h);
global(long)       lbind(long l, long x, long h);
global(unsigned)   uceil(unsigned x, unsigned y);
global(unsigned)   uscale(unsigned x, unsigned y, unsigned z);
global(int)        irgcmp(int l, int x, int h);
global(int)        icmp(int x, int y);
global(void)       do_error(void);
global(int)        file_read(void *to, int num);
global(void)       file_xread(void *to, int len);
global(int)        file_xbyte(void);
global(int)        file_xword(void);
global(void)       file_rseek(int offset);
global(void)       file_write(const void *from, int num);
global(void)       file_wword(int x);
cglobal(void)      file_data(int d1, ...);
global(void)       get_mat_info(void);
global(void)       export_form(void);
global(void)       fetch_line(void);
global(pointer)    fetch_para(pointer from);
global(void)       clear_line(void);
global(void)       flush_line(int hRT, int hPG, int spacing, int csConvert);
global(void)       flclr_line(int hRT, int hPG, int spacing, int csConvert);
global(void)       paste_line(int x, int len, int just, int nblanks);
global(void)       progress_show(long value);
global(void)       progress_file(void);

/********************************************************************/
/********************************************************************/
/*                                                                  */
/*               Word for Windows-specific definitions.             */
/*                                                                  */
/********************************************************************/
/********************************************************************/

typedef WORD LID; /* language ID */
typedef WORD PN;
typedef long FC;
typedef long CP;
typedef WORD SHD;

typedef struct /* border code */
{
	WORD dxpLineWidth : 3; /* single line/border width in 0.75 points */
	WORD brcType      : 2; /* border type; 0 none,1 single,2 thick,3 double */
	WORD fShadow      : 1; /* shadow flag (1 = shadow on) */
	WORD ico          : 5; /* color code */
	WORD dxpSpace     : 5; /* pnt width of space btw border & text in border */
}
BRC;

typedef struct /* border code for WfW 1.0 */
{
	WORD dxpLine2Width   : 3; /* pxl width of 2nd line of border */
	WORD dxpSpaceBetween : 3; /* pxl distance btw both lines of border */
	WORD dxpLine1Width   : 3; /* pxl width of 1st border line */
	WORD dxpSpace        : 5; /* space btw border & text in border */
	WORD fShadow         : 1; /* 1 = shadow on */
	WORD fSpare          : 1; /* reserved */
}
BRC10;

typedef struct /* CHP/CHPX character properties */
{
	WORD fBold      : 1; /* 1 = bold on /// 1 = opposite than default */
	WORD fItalic    : 1; /* 1 = itl. on /// 1 = opposite */
	WORD fRMarkDef  : 1; /* 1 = revision mark strikethru /// 1 = opposite */
	WORD fOutline   : 1; /* 1 = outlined /// opposite */
	WORD fFldVanish : 1; /* <needs work> */
	WORD fSmallCaps : 1; /* 1 = small caps /// opposite */
	WORD fCaps      : 1; /* 1 = disp. with caps /// opposite */
	WORD fVanish    : 1; /* 1 = vanished */
	WORD fRMark     : 1;
	WORD fSpec      : 1; /* 1 = special W character /// opposite */
	WORD fStrike    : 1; /* 1 = strikethrough /// opposite */
	WORD fObj       : 1; /* 1 = embedded object /// opposite */
	WORD fShadow    : 1; /* not in specification !!! */
	WORD            : 3; /* reserved */

	WORD fsIco      : 1; /* ignored / para chp.ico differs from CHP */
	WORD fsFtc      : 1; /* ignored / chp.ftc is different */
	WORD fsHps      : 1; /* ignored / chp.hps is different */
	WORD fsKul      : 1; /* ignored / chp.kul is different */
	WORD fsPos      : 1; /* ignored / chp.hpsPos is different */
	WORD fsSpace    : 1; /* ignored / chp.qpsSpace is different */
	WORD fsLid      : 1; /* ignored / chp.lid is different */
	WORD            : 9; /* ignored */

	WORD ftc;            /* font code */
	WORD hps;            /* font size in 1/2 points */

	WORD qpsSpace   : 6; /* space flw char in 1/4pt; x > 55 => x -= 64 */
	WORD fSysVanish : 1; /* Word internal */
	WORD wSpace2    : 1; /* reserved */
	WORD ico        : 5; /* text color, page #39 */
	WORD kul        : 3; /* undl: 0 none,1 sngl,2 byword,3 dbl, 4 dotted */

	signed char hpsPos;  /* pos in 1/2points; 0=normal,+sups,-subs */
	BYTE  wSpare3;       /* reserved */

	LID   lid;
	FC    fcPic;
#define fcObj fcPic
}
CHP, CHPX;

typedef struct /* DTTM : Date and Time */
{
	WORD mint : 6; /* minutes, 0-59 */
	WORD hr   : 5; /* hours, 0-23 */
	WORD dom  : 5; /* day of month, 1-31 */
	WORD mon  : 4; /* month, 1-12 */
	WORD yr   : 9; /* years minus 1900 */
	WORD wdy  : 3; /* 0 sun, 1 mon, 2 tue, 3 wen, 4 thu, 5 fri, 6 sat */
}
DTTM;

typedef struct /* DOP : document properties */
{
	WORD  fFacingPages   : 1; /* 1 = facing pages should be printed */
	WORD  fWidowControl  : 1; /* 1 = widow control is on */
	WORD  fPMHMainDoc    : 1; /* 1 = doc is a main doc for Print Merge Helper */
	WORD  grfSuppression : 2; /* 0 = form letter ln suppr. / 1 = no suppr */
	WORD  fpc            : 2; /* footnote pos: 0=as endn,1=pgbot,2=immediately */
	WORD                 : 1; /* unused */
	WORD  grpflhdt       : 8; /* spec of doc headers and footers */

	WORD  fFtnRestart    : 1; /* 1 - reset footnote number to 1 on each page */
	WORD  nFtn           : 15; /* initial footnote number for document */

	BYTE  irmBar;
	BYTE  irmProps       : 7;
	BYTE  fRevMarking    : 1;

	WORD  fBackup        : 1;
	WORD  fExactCWords   : 1;
	WORD  fPagHidden     : 1;
	WORD  fPagResults    : 1;
	WORD  fLockAtn       : 1;
	WORD  fMirrorMargins : 1; /* 1 = swap margins on left/right pages */
	WORD  fKeepFileFormat: 1; /* sav as original file format when 1 */
	WORD  fDfltTrueType  : 1; /* use TT fonts by default */
	WORD  fPagSuppressTopSpacing : 1;
	WORD                 : 7;

	WORD  fSpares        : 16;
	WORD  dxaTab;             /* default tab width, dflt 720 twips */
	WORD  wSpare;
	WORD  dxaHotZ;
	WORD  wSpare2;
	WORD  wSpare3;
	DTTM  dttmCreated;
	DTTM  dttmRevised;
	DTTM  dttmLastPrint;
	short nRevision;
	long  tmEdited;
	long  cWords;
	long  cCh;
	short cPg;
	short rgwSpaceDocSum[2];
}
DOP;

typedef struct /* FIB : file information block */
{
	WORD  wIdent;   /* magic number: 0xA5DB */
	WORD  nFib;     /* FIB version written */
	WORD  nProduct; /* product version written by */
	WORD  lid;      /* language stamp - localized version */

	PN    pnNext;
	WORD  fDot        : 1;
	WORD  fGlsy       : 1;
	WORD  fComplex    : 1; /* 1 = complex, fast-saved file */
	WORD  fHasPic     : 1; /* file contains pictures */
	WORD  cQuickSaves : 4; /* count of times file was quicksaved */
	WORD  fEncrypted  : 1; /* 1 = encrypted */
	WORD              : 7; /* unused */

	WORD  nFibBack;
	long  lKey;            /* file encrypted key */
	WORD  rgwSpare0[3];    /* reserved */
	FC    fcMin;           /* file offset of 1st character in text */
	FC    fcMac;           /* file offset of last char + 1 */
	FC    cbMac;           /* file offset of last char written to file + 1 */
	FC    fcSpare0;        /* reserved */
	FC    fcSpare1;        /* reserved */
	FC    fcSpare2;        /* reserved */
	FC    fcSpare3;        /* reserved */
	CP    ccpText;         /* length of main document text stream */
	CP    ccpFtn;          /* length of footnote subdocument text stream */
	CP    ccpHdd;          /* length of header subdoc */
	CP    ccpMcr;          /* length of macro subdoc */
	CP    ccpAtn;          /* length of annotation subdoc */
	CP    ccpSpare0;       /* reserved */
	CP    ccpSpare1;       /* reserved */
	CP    ccpSpare2;       /* reserved */
	CP    ccpSpare3;       /* reserved */
	FC    fcStshfOrig;     /* foffset of orig. allocation of STSH in file. */
	WORD  cbStshfOrig;     /* count of bytes in original STSH allocation */
	FC    fcStshf;         /* file offset of STSH in file */
	WORD  cbStshf;         /* count of bytes in current STSH allocation */
	FC    fcPlcffndRef;    /* foffset of footnote ref. PLC. */
	WORD  cbPlcffndRef;    /* count of bytes of ftn reference PLC, 0 if none */
	FC    fcPlcffndTxt;    /* file offset of footnote text PLC */
	WORD  cbPlcffndTxt;
	FC    fcPlcfandRef;    /* file offset of annotation reference PLC */
	WORD  cbPlcfandRef;
	FC    fcPlcfandTxt;    /* file offset of annotation text PLC */
	WORD  cbPlcfandTxt;
	FC    fcPlcfsed;       /* file offset of section descriptor PLC */
	WORD  cbPlcfsed;       /* count of bytes of section descriptor PLC */
	FC    fcPlcfpgd;       /* foffs of page descriptor PLC for main doc */
	WORD  cbPlcfpgd;       /* count of bytes of page descriptor PLC */
	FC    fcPlcfphe;       /* foffset of PLC of paragraph heights */
	WORD  cbPlcfphe;       /* count of bytes of para height PLC,0 = noncomplex */
	FC    fcSttbfglsy;     /* file offset of glossary string table */
	WORD  cbSttbflgsy;     /* count of bytes of glossary string table */
	FC    fcPlcfglsy;      /* foffset of glossary PLC */
	WORD  cbPlcfglsy;      /* cob in ^ */
	FC    fcPlcfhdd;       /* BYTE offset of header PLC */
	WORD  cbPlcfhdd;       /* cob */
	FC    fcPlcfbteChpx;   /* character property bin table PLC */
	WORD  cbPlcfbteChpx;
	FC    fcPlcfbtePapx;   /* foff para property bin table PLC */
	WORD  cbPlcfbtePapx;
	FC    fcPlcfsea;       /* PLC reserved for private use */
	WORD  cbPlcfsea;
	FC    fcSttbfffn;
	WORD  cbSttbfffn;
	FC    fcPlcffldMom;
	WORD  cbPlcffldMom;
	FC    fcPlcffldHdr;
	WORD  cbPlcffldHdr;
	FC    fcPlcffldFtn;
	WORD  cbPlcffldFtn;
	FC    fcPlcffldAtn;
	WORD  cbPlcffldAtn;
	FC    fcPlcffldMcr;
	WORD  cbPlcffldMcr;
	FC    fcSttbfbkmk;
	WORD  cbSttbfbkmk;
	FC    fcPlcfbkf;
	WORD  cbPlcfbkf;
	FC    fcPlcfbkl;
	WORD  cbPlcfbkl;
	FC    fcCmds;
	WORD  cbCmds;
	FC    fcPlcmcr;
	WORD  cbPlcmcr;
	FC    fcSttbfmcr;
	WORD  cbSttbfmcr;
	FC    fcPrDrvr;        /* foff of printer info */
	WORD  cbPrDrvr;
	FC    fcPrEnvPort;     /* print environment in portrait mode */
	WORD  cbPrEnvPort;
	FC    fcPrEnvLand;     /* landscape mode */
	WORD  cbPrEnvLand;
	FC    fcWss;           /* foff of Window Save State data structure */
	WORD  cbWss;
	FC    fcDop;           /* foff of doc property data structure */
	WORD  cbDop;
	FC    fcSttbfAssoc;
	WORD  cbSttbfAssoc;
	FC    fcClx;           /* information for complex files */
	WORD  cbClx;
	FC    fcPlcfpgdFtn;    /* file offset of page descriptor PLC for ftn */
	WORD  cbPlcfpgdFtn;
	FC    fcAutosaveSource; /* name of original file */
	WORD  cbAutosaveSource;
	FC    fcSpare5;
	WORD  cbSpare5;
	FC    fcSpare6;
	WORD  cbSpare6;
	short wSpare4;
	PN    pnChpFirst;
	PN    pnPapFirst;
	PN    cpnBteChp;       /* count of CHPX FKPs in file */
	PN    cpnBtePap;       /* count of PAPX FKPs in file */
}
FIB;

/* this is only an informal definition
typedef struct // FKP: formatted disk page
{
	FC   rgfc[?]; // CHPX: each FC is the limit of a run exception text
	BYTE rgb[4 * (fkp.crun + 1)]; // each BYTE = CHPX / PAPX offset
	...
}
FKP;
*/

/* FLD is not supported */
#define sizeof_FLD 2

/* OBJHEADER is not supported */
#define sizeof_OBJHEADER 8

typedef struct /* PHE: paragraph height */
{
	WORD  fSpare     : 1;
	WORD  fUnk       : 1;
	WORD  fDiffLines : 1;
	WORD             : 5;
	WORD  clMac      : 8;

	short dxaCol;
#define dylLine    dxaCol
#define dylHeight  dxaCol
	short fStyleDirty;
}
PHE;

typedef struct /* TC: table cell descriptors */
{
	WORD  fFirstMerged : 1;  /* set 1 in 1st merged cell */
	WORD  fMerged      : 1;  /* set 1 when merged with preceding cell */
	WORD  fUnused      : 14; /* reserved */

	BRC   brcTop;            /* top border of table cell */
	BRC   brcLeft;           /* left border of table cell */
	BRC   brcBottom;         /* bottom border of table cell */
	BRC   brcRight;          /* right border of table cell */
}
TC;

typedef struct /* TAP: table properties */
{
	short jc;
	short dxaGapHalf;
	short dyaRowHeight;

	WORD  fCaFull   : 1;
	WORD  fFirstRow : 1;
	WORD  fLastRow  : 1;
	WORD  fOutline  : 1;
	WORD            : 12;

	short itcMac;
	short dxaAdjust;
#define MAX_CELLS 32
	short rgdxaCenter[MAX_CELLS + 1];
	TC    rgtc[MAX_CELLS];
	SHD   rgshd[MAX_CELLS];
}
TAP;

typedef struct /* TBD: tab descriptor */
{
	BYTE jc  : 3; /* just code: 0=left,1=center,2=right,3=dec,4=bar */
	BYTE tlc : 3; /* tab leader: 0=none, 1=dot, 2=hyphen, 3=single line */
	BYTE     : 2; /* reserved */
}
TBD;

typedef struct /* PAP: paragraph properties */
{
	BYTE  stc;              /* style code - index into STSH structure */
	BYTE  jc;               /* just code; 0 left, 1 center, 2 right, 3 full */
	BYTE  fSideBySide;      /* side-by-side paragraph */
	BYTE  fKeep;            /* keep entire para on 1 page if possible */
	BYTE  fKeepFollow;      /* keep this&next para on same page if possible */
	BYTE  fPageBreakBefore; /* start para on new page */

	BYTE  fUnused : 4;     /* reserved */
	BYTE  pcVert  : 2;     /* coord frame: 0=rel.mrgn,1=rel.page,2=rel.text */
	BYTE  pcHorz  : 2;     /* coord frame: 0=rel.clmn,1=rel.mrgn,2=rel.page */

	BYTE  brcp;            /* rect. brd: 1=none,2=below,15=around,16=left bar */
	BYTE  brcl;            /* border line style: 0=sngl,1=thick,2=dbl,3=shadw */
	BYTE  nfcSeqNumb;      /* auto numbering format code */
	BYTE  nnSeqNumb;       /* auto numbering option */
	BYTE  fNoLnn;          /* no ln numbering for this para (exception) */
	short dxaRight;        /* signed indent from right margin */
	short dxaLeft;         /* signed indent from left margin */
	short dxaLeft1;        /* 1st line indent relative to dxaLeft */
	short dyaLine;         /* line height; 0=auto; >0=>at least, <0 precise */
	WORD  dyaBefore;       /* hole before para */
	WORD  dyaAfter;        /* hole after para */
	PHE   phe;             /* height of current paragraph */
	char  flnTable;        /* 1 = para is in a table row */
	char  fTtp;            /* 1 = para is only row mark; ends a table row */
	WORD  ptap;            /* (TAP near *) - used internally by Word */
	short dxaAbs;          /* +=hor.dist; 0=para at left; -=special; page #51 */
	short dyaAbs;          /* +=vrt.dist; 0=unconstrained; -=special */
	short dxaWidth;        /* !=0 .. para must be dxaWidth wide */
	BRC   brcTop;          /* border above para */
	BRC   brcLeft;         /* border to the left of para */
	BRC   brcBottom;       /* border below para */
	BRC   brcRight;        /* border to the right of para */
	BRC   brcBetween;      /* border between conforming paras */
	BRC   brcBar;          /* border on outsize of text when facing pages */
	short dxaFromText;     /* horz. dist. to be mantained from abs. para */
	short dyaFromText;     /* vert. */
	BYTE  wr;              /* Wrap Code for absolute objects */
	BYTE  zz;              /* currently unused */
	BYTE  fTransparent;    /* currently unused */
	BYTE  bSpare;          /* currently unused */
	WORD  dyaHeight  : 15; /* height of abs. obj, 0 = Auto */
	WORD  fMinHeight : 1;  /* 0 = exact, 1 = at least */
	SHD   shd;             /* shading */
	short itbdMac;         /* nr of tab stops for para; 0 <= <= 50 */
#define MAX_TABS 50 /* maximum number of tabs */
	short rgdxaTab[MAX_TABS]; /* array of positions of itbdMac tab stops */
	TBD   rgtbd[MAX_TABS];    /* array of tab descriptors */
}
PAP;

typedef struct /* PAPX: paragraph property exceptions */
{
	BYTE cb;        /* count of words / bytes in PAPX */
	BYTE stc;       /* style code of the style from which props are inherited */
	PHE  phe;       /* encoding of para height info for para */
	BYTE grpprl[2]; /* a list of sprms encoding differences */
}
PAPX;

typedef struct /* PCD: Piece Descriptor */
{
	BYTE fNoParaLast : 1; /* 1 = no end-of-para marks */
	BYTE fPaphNil    : 1; /* used internally by Word */
	BYTE             : 6;

	BYTE fn;              /* used internally by Word */
	FC   fc;              /* foffset of beginning of piece */
	BYTE prm[2];          /* sprm or an index number of grpprl with sprms */
}
PCD;

typedef struct /* PGD: page descriptor */
{
	WORD  fContinue   : 1;
	WORD  fUnk        : 1;
	WORD              : 1;
	WORD  fRight      : 1;
	WORD  fPgnRestart : 1;
	WORD  fEmptyPage  : 1; /* on blank pg fGhost redef fEmptyPage and fAllFtn */
	WORD  fAllFtn     : 1;
	WORD              : 1;
	WORD  bkc         : 8;

	WORD  lnn;
	short cl;
	WORD  pgn;
	short dcpDepend;
}
PGD;

typedef struct tagRECT
{
    short left;
    short top;
    short right;
    short bottom;
} RECT;

typedef struct tagMETAFILEPICT
{
    short  mm;
    short  xExt;
    short  yExt;
    WORD   hMF;
} METAFILEPICT;

typedef struct tagBITMAP
{
    short     bmType;
    short     bmWidth;
    short     bmHeight;
    short     bmWidthBytes;
    BYTE      bmPlanes;
    BYTE      bmBitsPixel;
    void FAR *bmBits;
} BITMAP;

typedef struct /* PIC: picture descriptor */
{
	long lcb;
	WORD cbHeader;
	METAFILEPICT mfp;

	union
	{
		BITMAP bm;
		RECT   rcWinMF;
	}
	bmrc;

	short  dxaGoal;
	short  dyaGoal;
	WORD   mx;
	WORD   my;
	short  dxaCropLeft;
	short  dyaCropTop;
	short  dxaCropRight;
	short  dyaCropBottom;

	WORD   brcl        : 4;
	WORD   fFrameEmpty : 1;
	WORD               : 11;

	BRC    brcTop;
	BRC    brcLeft;
	BRC    brcBottom;
	BRC    brcRight;
	short  dxaOrigin;
	short  dyaOrigin;
	char   rgb[2]; /* variable */
}
PIC;

/* informal definition
typedef struct // PLCF: plex of CPs stored in file
{
	FC rgfc[];
	struct rgstruct[];
}
PLCF;
*/

typedef struct /* SED: section descriptor */
{
	WORD fSwap : 1;  /* runtime - change orientation bef. printing */
	WORD fUnk  : 1;  /* internal */
	WORD fn    : 14; /* internal */
	FC   fcSepx;     /* file offset to beginning of SEPX stored for section */
}
SED;

typedef struct /* SEP: section properties */
{
	BYTE  bkc;
	BYTE  fTitlePage;
	short ccolM1;
	short dxaColumns;
	char  bUnused1;
	BYTE  nfcPgn;
	WORD  pgnStart;
	WORD  wSpare1;
	BYTE  fPgnRestart;
	BYTE  fEndNote;
	char  lnc;
	char  grpflhdt;
	WORD  nLnnMod;
	short dxaLnn;
	WORD  dyaHdrTop;
	WORD  dyaHdrBottom;
	char  fLBetween;
	char  vjc;
	short lnnMin;
	BYTE  morPage;
	char  bUnused2;
	WORD  xaPage;
	WORD  yaPage;
	WORD  dxaLeft;
	WORD  dxaRight;
	short dyaTop;
	short dyaBottom;
	WORD  dzaGutter;
	WORD  dmBinFirst;
	WORD  dmBinOther;
	WORD  dxaColumnWidth;
}
SEP;

typedef struct /* SEPX: section property exceptions */
{
	BYTE cb; /* count of bytes in remainder of SEPX */
	char grpprf[1]; /* list of difference sprms */
}
SEPX;

enum
{
	// 0-9
	sprmUNDEF0,
	sprmUNDEF1,
	sprmPStc,
	sprmPStcPermute,
	sprmPIncLevel,
	sprmPJc,
	sprmPFSideBySide,
	sprmPFKeep,
	sprmPFKeepFollow,
	sprmPPageBreakBefore,

	// 10-19
	sprmPBrcl,
	sprmPBrcp,
	sprmPNfcSeqNumb,
	sprmPNoSeqNumb,
	sprmPFNoLineNumb,
	sprmPChgTabsPapx,
	sprmPDxaRight,
	sprmPDxaLeft,
	sprmPNest,
	sprmPDxaLeft1,

	// 20-29
	sprmPDyaLine,
	sprmPDyaBefore,
	sprmPDyaAfter,
	sprmPChgTabs,
	sprmPFlnTable,
	sprmPTtp,
	sprmPDxaAbs,
	sprmPDyaAbs,
	sprmPDxaWidth,
	sprmPPc,

	// 30-39
	sprmPBrcTop10,
	sprmPBrcLeft10,
	sprmPBrcBottom10,
	sprmPBrcRight10,
	sprmPBrcBetween10,
	sprmPBrcBar10,
	sprmPFromText10,
	sprmUNDEF37,
	sprmPBrcTop,
	sprmPBrcLeft,

	// 40-49
	sprmPBrcBottom,
	sprmPBrcRight,
	sprmPBrcBetween,
	sprmPBrcBar,
	sprmUNDEF44,
	sprmPWHeightAbs,
	sprmUNDEF46,
	sprmPShd,
	sprmPDyaFromText,
	sprmPDxaFromText,

	// 50-59
	sprmUNDEF50,
	sprmUNDEF51,
	sprmUNDEF52,
	sprmCFStrikeRM,
	sprmCFRMark,
	sprmCFFldVanish,
	sprmUNDEF56,
	sprmCDefault,
	sprmCPlain,
	sprmUNDEF59,

	// 60-69
	sprmCFBold,
	sprmCFItalic,
	sprmCFStrike,
	sprmCFOutline,
	sprmCFShadow,
	sprmCFSmallCaps,
	sprmCCaps,
	sprmCFVanish,
	sprmCFtc,
	sprmCKul,

	// 70-79
	sprmCSizePos,
	sprmCQpsSpace,
	sprmCLid,
	sprmCIco,
	sprmCHps,
	sprmCHpsInc,
	sprmCHpsPos,
	sprmCHpsPosAdj,
	sprmCMajority,
	sprmUNDEF79,

	// 80-89
	sprmUNDEF80,
	sprmUNDEF81,
	sprmUNDEF82,
	sprmUNDEF83,
	sprmUNDEF84,
	sprmUNDEF85,
	sprmUNDEF86,
	sprmUNDEF87,
	sprmUNDEF88,
	sprmUNDEF89,

	// 90-99
	sprmUNDEF90,
	sprmUNDEF91,
	sprmUNDEF92,
	sprmUNDEF93,
	sprmPicBrcl,
	sprmPicScale,
	sprmPicBrcTop,
	sprmPicBrcLeft,
	sprmPicBrcBottom,
	sprmPicBrcRight,

	// 100-109
	sprmUNDEF100,
	sprmUNDEF101,
	sprmUNDEF102,
	sprmUNDEF103,
	sprmUNDEF104,
	sprmUNDEF105,
	sprmUNDEF106,
	sprmUNDEF107,
	sprmUNDEF108,
	sprmUNDEF109,

	// 110-119
	sprmUNDEF110,
	sprmUNDEF111,
	sprmUNDEF112,
	sprmUNDEF113,
	sprmUNDEF114,
	sprmSDmBinFirst,
	sprmSDmBinOther,
	sprmSBkc,
	sprmSFTitlePage,
	sprmSColumns,

	// 120-129
	sprmSDxaColumns,
	sprmSFAutoPgn,
	sprmSNfcPgn,
	sprmSDyaPgn,
	sprmSDxaPgn,
	sprmSFPgnRestart,
	sprmSFEndnote,
	sprmSLnc,
	sprmSGprflhdt,
	sprmSNLnnMod,

	// 130-139
	sprmSDxaLnn,
	sprmSDyaHdrTop,
	sprmSDyaHdrBottom,
	sprmSLBetween,
	sprmSVjc,
	sprmSLnnMin,
	sprmSPgnStart,
	sprmSBOrientation,
	sprmUNDEF138,
	sprmSXaPage,

	// 140-149
	sprmSYaPage,
	sprmSDxaLeft,
	sprmSDxaRight,
	sprmSDyaTop,
	sprmSDyaBottom,
	sprmSDzaGutter,
	sprmTJc,
	sprmTDxaLeft,
	sprmTDxaGapHalf,
	sprmUNDEF149,

	// 150-159
	sprmUNDEF150,
	sprmUNDEF151,
	sprmTDefTable10,
	sprmTDyaRowHeight,
	sprmTDefTable,
	sprmTDefTableShd,
	sprmUNDEF156,
	sprmTSetBrc,
	sprmTInsert,
	sprmTDelete,

	// 160-
	sprmTDxaCol,
	sprmTMerge,
	sprmTSplit,
	sprmTSetBrc10,
	sprmTSetShd,

	sprmMax,
};

enum // type size checks
{
	CHP_SERR  = (sizeof(CHP)  !=  18),
	DTTM_SERR = (sizeof(DTTM) !=   4),
	DOP_SERR  = (sizeof(DOP)  !=  52),
	FIB_SERR  = (sizeof(FIB)  != 326),
	PHE_SERR  = (sizeof(PHE)  !=   6),
	SERR_1 = CHP_SERR | DTTM_SERR | DOP_SERR | FIB_SERR | PHE_SERR,

	TC_SERR   = (sizeof(TC)   !=  10),
	TAP_SERR  = (sizeof(TAP)  != 462),
	TBD_SERR  = (sizeof(TBD)  !=   1),
	PAP_SERR  = (sizeof(PAP)  != 216),
	PAPX_SERR = (sizeof(PAPX) !=  10),
	SERR_2 = TC_SERR | TAP_SERR | TBD_SERR | PAP_SERR | PAPX_SERR,

	PCD_SERR  = (sizeof(PCD)  !=   8),
	PGD_SERR  = (sizeof(PGD)  !=  10),
	PIC_SERR  = (sizeof(PIC)  !=  60),
	SED_SERR  = (sizeof(SED)  !=   6),
	SEP_SERR  = (sizeof(SEP)  !=  50),
	SERR_3 = PCD_SERR | PGD_SERR | PIC_SERR | SED_SERR | SEP_SERR,

	SEPX_SERR = (sizeof(SEPX) !=   2),
	SERR_4 = SEPX_SERR,

	SERR = SERR_1 | SERR_2 | SERR_3 | SERR_4,
};

int mwp(char *fn, int code); // 0 = OK, -1 = creation, -2 = write error
int wpm(char *fn, int code); // 0 = OK, -1 = open, -2 = syntax error
int mww(char *fn, int code); // 0 = OK, -1 = creation, -2 = write error
int wwm(char *fn, int code); // 0 = OK, -1 = open, -2 = syntax error

#endif
