/*****************************************************************************
* Generic parser for the "Irit" solid modeller.				     *
*									     *
* Written by:  Gershon Elber				Ver 0.2, Sep. 1991   *
*****************************************************************************/

#ifndef	IRIT_PRSR_H
#define	IRIT_PRSR_H

#include <setjmp.h>

#include "irit_sm.h"
#include "cagd_lib.h"
#include "trim_lib.h"
#include "triv_lib.h"
#include "genmat.h"

/* Dont change the order of these objects (or there values as overloaded     */
/* tables (see overload.c) are hardwired to it. If you add objects update    */
/* that module properly.						     */
typedef enum {
    IP_OBJ_UNDEF = 0,

    IP_OBJ_POLY,                     /* These are the objects in overload.c. */
    IP_OBJ_NUMERIC,
    IP_OBJ_POINT,
    IP_OBJ_VECTOR,
    IP_OBJ_PLANE,
    IP_OBJ_MATRIX,
    IP_OBJ_CURVE,
    IP_OBJ_SURFACE,
    IP_OBJ_STRING,
    IP_OBJ_LIST_OBJ,
    IP_OBJ_CTLPT,
    IP_OBJ_TRIMSRF,
    IP_OBJ_TRIVAR,

    ANY_OBJ = 100		 /* Match any object type, in type checking. */
} IPObjStructType;

typedef enum {			 /* Possible error code during data parsing. */
    IP_NO_ERR = 0,

    IP_ERR_NUMBER_EXPECTED,
    IP_ERR_OPEN_PAREN_EXPECTED,
    IP_ERR_CLOSE_PAREN_EXPECTED,
    IP_ERR_LIST_COMP_UNDEF,
    IP_ERR_UNDEF_EXPR_HEADER,
    IP_ERR_PT_TYPE_EXPECTED,
    IP_ERR_OBJECT_EMPTY,
    IP_ERR_FILE_EMPTY,
    IP_ERR_MIXED_TYPES,
    IP_ERR_STR_NOT_IN_QUOTES,
    IP_ERR_OBJECT_EXPECTED,
    IP_ERR_CAGD_LIB_ERR,
    IP_ERR_TRIM_LIB_ERR,
    IP_ERR_TRIV_LIB_ERR,
    IP_ERR_STACK_OVERFLOW,
    IP_ERR_DEGEN_POLYGON,
    IP_ERR_DEGEN_NORMAL,
    IP_ERR_SOCKET_BROKEN,
    IP_ERR_SOCKET_TIME_OUT,
    IP_ERR_BIN_IN_TEXT,
    IP_ERR_BIN_UNDEF_OBJ,

    IP_WRN_OBJ_NAME_TRUNC = 100
} IritPrsrErrType;

#define IP_LOAD_COLOR           14  /* Index color default - loaded objects. */

#define IRIT_DATA_HEADER(File, Name) \
	fprintf(File, "Irit %s, %s,\nCreator: %s,\nDate: %s.\n\n", \
		VERSION, COPYRIGHT, Name, IritRealTimeDate());

/*****************************************************************************
* Global data structures:						     *
* Objects in the system might be (real) scalars, (R3) vectors, matrices      *
* (4 by 4 - transformation matrix), strings of chars, lists of objects, or   *
* geometric objects. All but the last are simple and all their data is saved *
* in the object space itself. The last (geometric) object points on a	     *
* curve or a surface or a polygonal list of the form:			     *
*									     *
* Polygon -> Polygon -> Polygon -> Polygon -> .... -> NULL		     *
*    |		|	   |	      |					     *
*    V          V          V          V					     *
*  VList      VList      VList      VList	(VList = Vertex List)	     *
*									     *
* Each VList is usually a CIRCULAR vertex list. Each VList element           *
* (IPVertexStruct) implicitly defines an edge from this vertex, to the next. *
* As each edge is used by exactly two polygons, a pointer to the other       *
* polygon using this edge exists in the IPVertexStruct as PAdj. Each polygon *
* has also its Plane definition for fast processing, with its normal         *
* pointing INTO the object.						     *
*   Few other tags & flags are included in the data structures for different *
* modules.								     *
*   Note, vertices are not shared by few VLists/Polygons although it may     *
* decrease memory usage (suprisingly, not much). The main reason to that is  *
* the basic assumption of this solid modeller, which is simplicity...	     *
*****************************************************************************/

/*****************************************************************************
* Vertex Type - holds single 3D point, including some attributes on it as    *
* Tags. The 3D coordinates are saved in Pt. Pointer to next in chain	     *
* is Pnext, and the pointer to the adjacent polygon (to the edge defined by  *
* this Vertex and Vertex -> Pnext) is PAdj.				     *
*****************************************************************************/

/* Internal edge, or edge generated by the polygon decomposition stage when  */
/* only convex polygons are allowed. This edge was not in the input	     */
/* non-convex polygon, and therefore one may not want to see/display it.     */
/* Note bits 4-7 (high nibble of Tags) are reserved for the different	     */
/* modules to perform their local tasks and so should not be used here.	     */
#define IP_VRTX_INTERNAL_TAG	0x01    /* Internal Tag - Edge is internal.  */
#define IP_VRTX_NORMAL_TAG	0x02     /* Normal Tag - Vertex has normal.  */

#define IP_IS_INTERNAL_VRTX(Vrtx)	(Vrtx -> Tags & IP_VRTX_INTERNAL_TAG)
#define IP_SET_INTERNAL_VRTX(Vrtx)	(Vrtx -> Tags |= IP_VRTX_INTERNAL_TAG)
#define IP_RST_INTERNAL_VRTX(Vrtx)	(Vrtx -> Tags &= ~IP_VRTX_INTERNAL_TAG)
#define IP_HAS_NORMAL_VRTX(Vrtx)	(Vrtx -> Tags & IP_VRTX_NORMAL_TAG)
#define IP_SET_NORMAL_VRTX(Vrtx)	(Vrtx -> Tags |= IP_VRTX_NORMAL_TAG)
#define IP_RST_NORMAL_VRTX(Vrtx)	(Vrtx -> Tags &= ~IP_VRTX_NORMAL_TAG)

typedef struct IPVertexStruct {
    struct IPVertexStruct *Pnext;		        /* To next in chain. */
    struct IPAttributeStruct *Attrs;
    struct IPPolygonStruct *PAdj;		     /* To adjacent polygon. */
    PointType Coord;			       /* Holds X, Y, Z coordinates. */
    NormalType Normal;		       /* Hold Vertex normal into the solid. */
    ByteType Count, Tags;				 /* Some attributes. */
} IPVertexStruct;

/*****************************************************************************
* Polygon Type - holds single polygon - Its Plane definition, and a pointer  *
* to its vertices contour list V. As for IPVertexStruct, different attributes*
* can be saved in Tags. PAux can be used locally by different modules, for   *
* local usage only, and nothing sould be assumed on entry.		     *
*****************************************************************************/

/* Note bits 4-7 (high nibble of Tags) are reserved for the different	     */
/* modules to perform their local tasks and so should not be used here.	     */
#define IP_POLY_CONVEX_TAG	0x01	   /* Convex Tag - Set if is convex. */
#define IP_POLY_BBOX_TAG	0x02  /* BBox Tag - Set if BBox is computed. */
#define IP_POLY_PLANE_TAG	0x04    /* Plane Tag - set of has plane def. */

#define	IP_IS_CONVEX_POLY(Poly)		((Poly) -> Tags & IP_POLY_CONVEX_TAG)
#define	IP_SET_CONVEX_POLY(Poly)	((Poly) -> Tags |= IP_POLY_CONVEX_TAG)
#define	IP_RST_CONVEX_POLY(Poly)	((Poly) -> Tags &= ~IP_POLY_CONVEX_TAG)
#define	IP_HAS_BBOX_POLY(Poly)		((Poly) -> Tags & IP_POLY_BBOX_TAG)
#define	IP_SET_BBOX_POLY(Poly)		((Poly) -> Tags |= IP_POLY_BBOX_TAG)
#define	IP_RST_BBOX_POLY(Poly)		((Poly) -> Tags &= ~IP_POLY_BBOX_TAG)
#define IP_HAS_PLANE_POLY(Poly)		((Poly) -> Tags & IP_POLY_PLANE_TAG)
#define IP_SET_PLANE_POLY(Poly)		((Poly) -> Tags |= IP_POLY_PLANE_TAG)
#define IP_RST_PLANE_POLY(Poly)		((Poly) -> Tags &= ~IP_POLY_PLANE_TAG)

typedef struct IPPolygonStruct {
    struct IPPolygonStruct *Pnext;		        /* To next in chain. */
    struct IPAttributeStruct *Attrs;
    VoidPtr PAux;
    int IAux, IAux2;
    PlaneType Plane;			 /* Holds Plane as Ax + By + Cz + D. */
    BBoxType BBox;					/* BBox of polygons. */
    IPVertexStruct *PVertex;		    		/* To vertices list. */
    ByteType Count, Tags;			         /* Some attributes. */
} IPPolygonStruct;

/*****************************************************************************
* Object Type - main system structure, which holds all the objects defined   *
* in the system like Numeric, Geometric etc.				     *
*   Note that as the number of objects will be usually extermely low (100 is *
* high estimate!) we can waste some memory here...			     *
*****************************************************************************/

#define IP_IS_UNDEF_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_UNDEF)
#define IP_IS_POLY_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_POLY)
#define IP_IS_NUM_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_NUMERIC)
#define IP_IS_POINT_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_POINT)
#define IP_IS_VEC_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_VECTOR)
#define IP_IS_PLANE_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_PLANE)
#define IP_IS_CTLPT_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_CTLPT)
#define IP_IS_MAT_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_MATRIX)
#define IP_IS_STR_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_STRING)
#define IP_IS_OLST_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_LIST_OBJ)
#define IP_IS_CRV_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_CURVE)
#define IP_IS_SRF_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_SURFACE)
#define IP_IS_TRIMSRF_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_TRIMSRF)
#define IP_IS_TRIVAR_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_TRIVAR)

#define IP_IS_GEOM_OBJ(Obj)	(IP_IS_UNDEF_OBJ(Obj) || \
				 IP_IS_POLY_OBJ(Obj) || \
				 IP_IS_POINT_OBJ(Obj) || \
				 IP_IS_CTLPT_OBJ(Obj) || \
				 IP_IS_VEC_OBJ(Obj) || \
				 IP_IS_CRV_OBJ(Obj) || \
				 IP_IS_SRF_OBJ(Obj) || \
				 IP_IS_TRIMSRF_OBJ(Obj) || \
				 IP_IS_TRIVAR_OBJ(Obj))

#define IP_IS_FFGEOM_OBJ(Obj)	(IP_IS_CRV_OBJ(Obj) || \
				 IP_IS_SRF_OBJ(Obj) || \
				 IP_IS_TRIMSRF_OBJ(Obj) || \
				 IP_IS_TRIVAR_OBJ(Obj))

#define IP_IS_POLYGON_OBJ(Obj)	  (((Obj) -> Tags & 0x03) == 0)
#define IP_SET_POLYGON_OBJ(Obj)	  ((Obj) -> Tags = ((Obj) -> Tags & 0xfc))
#define IP_IS_POLYLINE_OBJ(Obj)	  (((Obj) -> Tags & 0x03) == 1)
#define IP_SET_POLYLINE_OBJ(Obj)  ((Obj) -> Tags = ((Obj) -> Tags & 0xfc) + 1)
#define IP_IS_POINTLIST_OBJ(Obj)  (((Obj) -> Tags & 0x03) == 2)
#define IP_SET_POINTLIST_OBJ(Obj) ((Obj) -> Tags = ((Obj) -> Tags & 0xfc) + 2)

/* Maximum size of object list to start with (reallocated dynamically). */
#define MAX_OBJ_LIST	10

typedef struct IPObjectStruct {
    struct IPObjectStruct *Pnext;		        /* To next in chain. */
    struct IPAttributeStruct *Attrs;
    char Name[OBJ_NAME_LEN];				  /* Name of object. */
    IPObjStructType ObjType;	    /* Object Type: Numeric, Geometric, etc. */
    ByteType Count;	       /* Count Number of references to this object. */
    unsigned int Tags;				         /* Some attributes. */
    union {
	IPPolygonStruct *Pl;		       	       /* Polygon/line list. */
	CagdCrvStruct *Crvs;			      /* Free form curve(s). */
	CagdSrfStruct *Srfs;			    /* Free form surface(s). */
	TrimSrfStruct *TrimSrfs;	    /* Free form trimmed surface(s). */
	TrivTVStruct *Trivars;		         /* Free form trivariate(s). */
	RealType R;				       /* Numeric real data. */
	PointType Pt;			         /* Numeric real point data. */
	VectorType Vec;			        /* Numeric real vector data. */
	PlaneType Plane;		         /* Numeric real plane data. */
	CagdCtlPtStruct CtlPt;			      /* Control point data. */
	MatrixType *Mat;	    /* Numeric 4 by 4 transformation matrix. */
	struct {
	    struct IPObjectStruct **PObjList;		 /* List of objects. */
	    int ListMaxLen;	      /* Maximum number of elements in list. */
	} Lst;
	char *Str;			  /* General string for text object. */
	VoidPtr *VPtr;
    } U;
} IPObjectStruct;

typedef void (*IritPrsrPrintFuncType)(char *);

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

int IritPrsrOpenDataFile(char *FileName, int Read, int Messages);
int IritPrsrOpenStreamFromFile(FILE *f, int Read, int IsBinary, int IsPipe);
int IritPrsrOpenStreamFromSocket(int Soc, int Read, int IsBinary);
void IritPrsrCloseStream(int Handler, int Free);
IPObjectStruct *IritPrsrGetDataFiles(char **DataFileNames,
				     int NumOfDataFiles,
				     int Messages,
				     int MoreMessages);
IPObjectStruct *IritPrsrGetObjects(int Handler);
int IritPrsrSenseBinaryFile(char *FileName);
IPObjectStruct *IritPrsrProcessReadObject(IPObjectStruct *PObj);
IPObjectStruct *IritPrsrFlattenTree(IPObjectStruct *PObj);
void IritPrsrStdoutObject(IPObjectStruct *PObj);
void IritPrsrStderrObject(IPObjectStruct *PObj);
void IritPrsrPutObjectToFile(FILE *f, IPObjectStruct *PObj);
void IritPrsrPutObjectToHandler(int Handler, IPObjectStruct *PObj);
int IritPrsrParseError(int LineNum, char **ErrorMsg);
void IritPrsrPropagateAttrs(IPObjectStruct *PObj, IPAttributeStruct *Attrs);
void IritPrsrInputUnGetC(int Handler, char c);
void IritPrsrSetPolyListCirc(int Circ);
int IritPrsrSetFlattenObjects(int Flatten);
void IritPrsrSetReadOneObject(int OneObject);
void IritPrsrSetPrintFunc(IritPrsrPrintFuncType PrintFunc);
void IritPrsrFatalError(char *Msg);
void IritPrsrSetFloatFormat(char *FloatFormat);
void IritPrsrUpdatePolyPlane(IPPolygonStruct *PPoly);
void IritPrsrUpdatePolyPlane2(IPPolygonStruct *PPoly, VectorType Vin);
void IritPrsrUpdateVrtxNrml(IPPolygonStruct *PPoly, VectorType DefNrml);
IPObjectStruct *IritPrsrReverseObjList(IPObjectStruct *PObj);
void IritPrsrReverseVrtxList(IPPolygonStruct *Pl);

/* Binary stream functions. */
IPObjectStruct *IritPrsrGetBinObject(int Handler);
void IritPrsrPutBinObject(int Handler, IPObjectStruct *PObj);

/* Will be set to VIEW_MAT and PERS_MAT respectively if found in parsed data.*/
extern MatrixType IritPrsrViewMat, IritPrsrPrspMat;
extern int IritPrsrWasViewMat, IritPrsrWasPrspMat;

/* Gets lists of all freeform curves/(trimmed) surfaces/trivariates in the   */
/* datafile, process them as needed.					     */
/*   May return a processed version to be put on returned list from          */
/* IritPrsrGetObjects (polygonal approximation of the free form data for     */
/* example), or NULL otherwise.						     */
/*   This function is responsible to free the freeform data given if not     */
/* needed any more.							     */
/*   Is function is a call back function that must be provided by the using  */
/* application.	A default function will just concat the data into one list.  */
typedef struct IritPrsrFreeFormStruct {
    IPObjectStruct *CrvObjs;
    IPObjectStruct *SrfObjs;
    IPObjectStruct *TrimSrfObjs;
    IPObjectStruct *TrivarObjs;
} IritPrsrFreeFormStruct;
IPObjectStruct *IritPrsrProcessFreeForm(IritPrsrFreeFormStruct *FreeForms);

IPObjectStruct *IritPrsrConcatFreeForm(IritPrsrFreeFormStruct *FreeForms);

/* Convexity test for a polygon. */
int IritPrsrIsConvexPolygon(IPPolygonStruct *Pl);

/* Last element retrieval routines. */
IPObjectStruct *IritPrsrGetLastObj(IPObjectStruct *OList);
IPObjectStruct *IritPrsrGetPrevObj(IPObjectStruct *OList, IPObjectStruct *O);
IPObjectStruct *IritPrsrAppendObjLists(IPObjectStruct *OList1,
				       IPObjectStruct *OList2);
IPPolygonStruct *IritPrsrGetLastPoly(IPPolygonStruct *PList);
IPPolygonStruct *IritPrsrGetPrevPoly(IPPolygonStruct *PList,
				     IPPolygonStruct *P);
IPPolygonStruct *IritPrsrAppendPolyLists(IPPolygonStruct *PList1,
					 IPPolygonStruct *PList2);
IPVertexStruct *IritPrsrGetLastVrtx(IPVertexStruct *VList);
IPVertexStruct *IritPrsrGetPrevVrtx(IPVertexStruct *VList, IPVertexStruct *V);
IPVertexStruct *IritPrsrAppendVrtxLists(IPVertexStruct *VList1,
					IPVertexStruct *VList2);
int IritPrsrObjListLen(IPObjectStruct *O);
int IritPrsrPolyListLen(IPPolygonStruct *P);
int IritPrsrVrtxListLen(IPVertexStruct *V);

/* Coercion of objects. */
CagdPointType IritPrsrCoerceCommonSpace(IPObjectStruct *PtObjList, int Type);
CagdPointType IritPrsrCoercePtsListTo(IPObjectStruct *PtObjList, int Type);
IPObjectStruct *IritPrsrCoerceObjectTo(IPObjectStruct *PObj, int NewType);

/* Special objects' read and write functions. These functions are used to   */
/* read and write objects of other libraries to and from data files.        */

CagdCrvStruct *CagdCrvReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdCrvStruct *CagdCrvReadFromFile2(int Handler, char **ErrStr, int *ErrLine);
int CagdCrvWriteToFile(CagdCrvStruct *Crvs,
		       char *FileName,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int CagdCrvWriteToFile2(CagdCrvStruct *Crvs,
			int Handler,
			int Indent,
			char *Comment,
			char **ErrStr);
int CagdCrvWriteToFile3(CagdCrvStruct *Crvs,
			FILE *f,
			int Indent,
			char *Comment,
			char **ErrStr);

CagdSrfStruct *CagdSrfReadFromFile(char *FileName,
				   char **ErrStr,
				   int *ErrLine);
CagdSrfStruct *CagdSrfReadFromFile2(int Handler, char **ErrStr, int *ErrLine);
int CagdSrfWriteToFile(CagdSrfStruct *Srfs,
		       char *FileName,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int CagdSrfWriteToFile2(CagdSrfStruct *Srfs,
			int Handler,
			int Indent,
			char *Comment,
			char **ErrStr);
int CagdSrfWriteToFile3(CagdSrfStruct *Srfs,
			FILE *f,
			int Indent,
			char *Comment,
			char **ErrStr);
CagdCrvStruct *BzrCrvReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdCrvStruct *BzrCrvReadFromFile2(int Handler,
				   CagdBType NameWasRead,
				   char **ErrStr,
				   int *ErrLine);
int BzrCrvWriteToFile(CagdCrvStruct *Crvs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int BzrCrvWriteToFile2(CagdCrvStruct *Crvs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
CagdSrfStruct *BzrSrfReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdSrfStruct *BzrSrfReadFromFile2(int Handler,
				   CagdBType NameWasRead,
				   char **ErrStr,
				   int *ErrLine);
int BzrSrfWriteToFile(CagdSrfStruct *Srfs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int BzrSrfWriteToFile2(CagdSrfStruct *Srfs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
CagdCrvStruct *BspCrvReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdCrvStruct *BspCrvReadFromFile2(int Handler,
				   CagdBType NameWasRead,
				   char **ErrStr,
				   int *ErrLine);
int BspCrvWriteToFile(CagdCrvStruct *Crvs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int BspCrvWriteToFile2(CagdCrvStruct *Crvs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
CagdSrfStruct *BspSrfReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdSrfStruct *BspSrfReadFromFile2(int Handler,
				   CagdBType NameWasRead,
				   char **ErrStr,
				   int *ErrLine);
int BspSrfWriteToFile(CagdSrfStruct *Srfs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int BspSrfWriteToFile2(CagdSrfStruct *Srfs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);

TrivTVStruct *TrivTVReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
TrivTVStruct *TrivTVReadFromFile2(int Handler, char **ErrStr, int *ErrLine);
TrivTVStruct *TrivBzrTVReadFromFile(char *FileName,
				    char **ErrStr,
				    int *ErrLine);
TrivTVStruct *TrivBzrTVReadFromFile2(int Handler, CagdBType NameWasRead,
				     char **ErrStr,
				     int *ErrLine);
TrivTVStruct *TrivBspTVReadFromFile(char *FileName,
				    char **ErrStr,
				    int *ErrLine);
TrivTVStruct *TrivBspTVReadFromFile2(int Handler,
				     CagdBType NameWasRead,
				     char **ErrStr,
				     int *ErrLine);
int TrivTVWriteToFile(TrivTVStruct *TVs,
		      char *FileName, 
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int TrivTVWriteToFile2(TrivTVStruct *TVs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int TrivTVWriteToFile3(TrivTVStruct *TVs,
		       FILE *f,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int TrivBzrTVWriteToFile(TrivTVStruct *TVs,
			 char *FileName,
			 int Indent,
			 char *Comment,
			 char **ErrStr);
int TrivBzrTVWriteToFile2(TrivTVStruct *TVs,
			  int Handler,
			  int Indent,
			  char *Comment,
			  char **ErrStr);
int TrivBspTVWriteToFile(TrivTVStruct *TVs,
			 char *FileName,
			 int Indent,
			 char *Comment,
			 char **ErrStr);
int TrivBspTVWriteToFile2(TrivTVStruct *TVs,
			  int Handler,
			  int Indent,
			  char *Comment,
			  char **ErrStr);

TrimSrfStruct *TrimReadTrimmedSrfFromFile(char *FileName,
					  char **ErrStr,
					  int *ErrLine);
TrimSrfStruct *TrimReadTrimmedSrfFromFile2(int Handler,
					   CagdBType NameWasRead,
					   char **ErrStr,
					   int *ErrLine);
int TrimWriteTrimmedSrfToFile(TrimSrfStruct *TrimSrfs,
			      char *FileName,
			      int Indent,
			      char *Comment,
			      char **ErrStr);
int TrimWriteTrimmedSrfToFile2(TrimSrfStruct *TrimSrfs,
			       int Handler,
			       int Indent,
			       char *Comment,
			       char **ErrStr);
int TrimWriteTrimmedSrfToFile3(TrimSrfStruct *TrimSrfs,
			       FILE *f,
			       int Indent,
			       char *Comment,
			       char **ErrStr);


#ifdef DEBUG
void IritPrsrDbg(void);
#endif /* DEBUG */

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

#endif	/* IRIT_PRSR_H */
