/*************************************************************************
	File:	wave_prvt.h

	FormZ data model translator sample.  Imports and exports Wavefront OBJ files.

	COPYRIGHT (C) 2001.  All Rights Reserved.
	auto*des*sys, Inc., Columbus, Ohio, USA.
*************************************************************************/

#ifndef __WAVE_PRVT_H
#define __WAVE_PRVT_H 1


#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>

#include "fzrt_api.h"

#include "fz_api.h"
#include "fzpl_plugin.h"

#include "fz_ffmt_api.h"
#include "fz_proj_api.h"
#include "fz_wind_api.h"
#include "fz_layr_api.h"
#include "fz_objt_api.h"
#include "fz_grup_api.h"
#include "fz_rmtl_api.h"
#include "fz_lite_api.h"
#include "fz_math_api.h"
#include "fz_type_api.h"
#include "fz_iost_api.h"
#include "fz_syst_api.h"
#include "fz_fuim_api.h"
#include "fz_ncrv_api.h"
#include "fz_nsrf_api.h"

#include "wave_pblc.h"


/************************************************************************/
/*				Translator defines										*/
/************************************************************************/


#define WAVE_ICON				140
#define WAVE_FICON				152

/* Resource file string list ID's. */
#define WAVE_STRINGS			1
#define WAVE_MESSAGES			4098
#define	WAVE_PROG_MSGS			4099

/* Resource file string ID's. */
#define	WRITING_WAVE_FILE		1
#define OPENING_WAVE_FILE		2
#define	NUM_BYTES_READ			3

#define WAVE_ABSINDX_STR		6
#define WAVE_GRPASOBJ_STR		7
#define WAVE_NAME_STR			8
#define WAVE_VENDOR_STR			9

#define WAVE_READ_ERR_STR		2
#define WAVE_WRITE_ERR_STR		3



#define WAVE_READ_ERR_ID		1
#define WAVE_WRITE_ERR_ID		2



#define		WAVE_MIN(a,b)	(((a)<(b))?(a):(b))

/* WaveFront translator errors. */
#define	WAVE_SYNTAX_ERR					1
#define	WAVE_UNKNOWN_KEYWORD_ERR		2
#define	WAVE_NO_SUCH_VERTEX_ERR			3
#define	WAVE_NULL_OBJECT_ERR			4
#define	WAVE_STRUCTURE_ERR				5
#define	WAVE_CONSISTENCY_ERR			6

#define	WAVE_FNAMETOOLONG_ERR			7
#define WAVE_ONOFFEXPECTED_ERR			8
#define WAVE_UNEXPECTEDKEYWORD_ERR		9
#define WAVE_UNEXPECTEDOPTION_ERR		10
#define WAVE_NEWMTLEXPECTED_ERR			11
#define WAVE_UNKNOWNOPTIONTYPE_ERR		12
#define WAVE_UNKNOWNNAMETYPE_ERR		13
#define WAVE_UNKNOWNCOLILLUMTYPE_ERR	14
#define WAVE_UNKNOWNTMAPTYPE_ERR		15
#define WAVE_UNKNOWNRMAPTYPE_ERR		16
#define WAVE_RFLEXTEXPECTED_ERR			17
#define WAVE_MTLEXTEXPECTED_ERR			18
#define WAVE_READUNSUPPORTEDIMAGE_ERR	19
#define WAVE_RGBMLZEXPECTED_ERR			20

#define WAVE_STRING_TOO_LONG			21
#define WAVE_UNEXPECTED_CHARACTER		22


/* Wavefront file processing codes. */
/* Begin controled object type. */
#define		WAVE_NONE					0
#define		WAVE_CURV					1
#define		WAVE_CURV2					2
#define		WAVE_SURF					3

/* Wavefront curve/surface types.*/
#define		WAVE_CSTYPE_BMATRIX			1
#define		WAVE_CSTYPE_BEZIER			2
#define		WAVE_CSTYPE_BSPLINE			3
#define		WAVE_CSTYPE_CARDINAL		4
#define		WAVE_CSTYPE_TAYLOR			5

/* Wavefront color and illumination types. */
#define		WAVE_CI_NONE				0
#define		WAVE_CI_AMB					1
#define		WAVE_CI_DIFF				2
#define		WAVE_CI_SPEC				3
#define		WAVE_CI_TRANS				4
#define		WAVE_CI_ILUM				5
#define		WAVE_CI_DSOLV				6
#define		WAVE_CI_SPEXP				7
#define		WAVE_CI_SHRP				8
#define		WAVE_CI_OPDNS				9


/* Wavefront texture map types. */
#define		WAVE_TXTR_TYPE_NONE			0
#define		WAVE_TXTR_TYPE_AMB			1
#define		WAVE_TXTR_TYPE_DIFF			2
#define		WAVE_TXTR_TYPE_SPEC			3
#define		WAVE_TXTR_TYPE_SPEXP		4
#define		WAVE_TXTR_TYPE_DSOLV		5
#define		WAVE_TXTR_TYPE_AA			6
#define		WAVE_TXTR_TYPE_DCAL			7
#define		WAVE_TXTR_TYPE_BUMP			8

/* Wavefront texture options. */
#define		WAVE_TXTR_OPT_NONE			0
#define		WAVE_TXTR_OPT_BLENDU		1
#define		WAVE_TXTR_OPT_BLENDV		2
#define		WAVE_TXTR_OPT_CLAMP			3
#define		WAVE_TXTR_OPT_MM			4
#define		WAVE_TXTR_OPT_OFFSET		5
#define		WAVE_TXTR_OPT_SCALE			6
#define		WAVE_TXTR_OPT_TURB			7
#define		WAVE_TXTR_OPT_RES			8

/* Wavefront Color Correction Options */
#define		WAVE_CC_OPT_NONE			0
#define		WAVE_CC_OPT_CC				1

/* Wavefrom Texture Map Channel Options */
#define		WAVE_CHAN_OPT_NONE			0
#define		WAVE_CHAN_OPT_IMFCHAN		1

/* Wavefrom Bump Map Options */
#define		WAVE_BUMP_OPT_NONE			0
#define		WAVE_BUMP_OPT_BM			1

/* Object signaling keyword during import. */
#define		WAVE_SIGN_IS_G				1
#define		WAVE_SIGN_IS_S				2
#define		WAVE_SIGN_IS_MG				3
#define		WAVE_SIGN_IS_O				4


/* Defines for custom export options. */
#define WAVE_READ_USE_SIGNG_BIT					1
#define WAVE_READ_USE_SIGNG_FLAG				(1 << WAVE_READ_USE_SIGNG_BIT)

#define WAVE_WRITE_USEABSOLUTEINDICES_BIT		1
#define WAVE_WRITE_USEABSOLUTEINDICES_FLAG		(1 << WAVE_WRITE_USEABSOLUTEINDICES_BIT)

/* Export Constants. */
#define WAVE_TOKEN_MAXLEN 256

/* Import macros. */
#define ANINDEX(W, N) (((_write_flags & WAVE_WRITE_USEABSOLUTEINDICES_FLAG))?((W)->normal_seed + 1 + (N)):(N))
#define APINDEX(W, P) (((_write_flags & WAVE_WRITE_USEABSOLUTEINDICES_FLAG))?((W)->point_seed + 1 + (P)):(P))
#define AP2INDEX(W, P) (((_write_flags & WAVE_WRITE_USEABSOLUTEINDICES_FLAG))?((W)->point2_seed + 1 + (P)):(P))
#define AC2INDEX(W, C) (((_write_flags & WAVE_WRITE_USEABSOLUTEINDICES_FLAG))?((W)->curv2_seed + 1 + (C)):(C))
#define AUVINDEX(W, UV) (((_write_flags & WAVE_WRITE_USEABSOLUTEINDICES_FLAG))?((W)->uv_seed + 1 + (UV)):(UV))



/************************************************************************/
/*				Translator data types									*/
/************************************************************************/

/* Export working data structure */
typedef struct
{
	fzrt_int				windex;			/* project window index */
	char				workname[256];	/* the name of the file */
	fzrt_floc_ptr		floc;			/* the directore of the file */
	FILE				*fp;			/* the open file */
	char				nl_str[4];		/* line termination characters */
	fz_ffmt_ref_td		ffmt_id;		/* the format reference id */
	fzrt_int				pos,			/* progress bar position */
						max_pos;		/* progress bar maximum position */
	short				inv_norms;		/* TRUE if Inverse Normals transform option is set */
	short				inv_faces;		/* TRUE if Inverse Faces transform option is set */

										/* Export Temporary storage */
	fzrt_int				obj_seed;		/* object's seed number */
	fzrt_int				normal_seed,	/* normal's seed number */
						point_seed,		/* 3D point's seed number */
						point2_seed,	/* 2D point's seed number */
						curv2_seed,		/* 2D curve's seed number */
						uv_seed;		/* texture uv coordinate's seed number */

	fzrt_boolean		do_tmaps;		/* TRUE if export texture is not off */
	short				num_dec;		/* number of decimal points for numeric output */	/* TAH 07/17/03 */
	char				lib_name[256];	/* ".mtl" file name */
} wave_out_td;



/* face color table */
typedef struct
{
	fzrt_int				num,	/* used item num in table */
						size;	/* allocated item num in table */
	fz_tag_td			*tab;	/* item records */
} wave_facemtltab_td;

/* segment to uv link table */
typedef struct
{
	fzrt_int				num,	/* used item num in table */
						size;	/* allocated item num in table */
	fzrt_int				*tab;	/* item records */
} wave_seglinktab_td;

/* face marker table */
typedef struct
{
	fzrt_int				num,	/* used item num in table */
						size;	/* allocated item num in table */
	char				*tab;	/* item records */
} wave_facemarktab_td;

/* uv coordinate table */
typedef struct
{
	fzrt_int			num,	/* used item num in table */
					size;	/* allocated item num in table */
	fz_xy_td		*tab;	/* item records */
} wave_uvtab_td;

/* item in "wave_mtllinktab_td" table */
typedef struct
{
	char		libname[256],	/* wavefront's library name */
				matname[256];	/* wavefront's material name */
	fzrt_int		active;			/* the material has been activated by a "usemtl" statement */
	fz_tag_td	stag;			/* link to formZ's surface index */
} wave_mtllink_td;

/* wavefront material to fz surface, link table */
typedef struct
{
	fzrt_int				num,	/* used item num in table */
						size;	/* allocated item num in table */
	wave_mtllink_td		*tab;	/* item records */
} wave_mtllinktab_td;

/* wavefront map data */
typedef struct
{
	char		name[256];		/* ambient map name */
	fzrt_int		flags;
	fz_xyz_td	o,
				s,
				t;
	double		factor,	
				base,
				gain,
				textres;		/* map resolution */
} wave_map_td;

/* wavefront mtl data */
typedef struct
{
	/* material name statement */
	char		name[256];		/* material name */

	/* color and illumination statements */
	fz_xyz_td	Ka,				/* ambient reflectivity */
				Kd,				/* diffuse reflectivity */
				Ks,				/* specular reflectivity */
				Tf;				/* transmission filter */
	fzrt_int		illum;			/* illumination model */
	double		d,				/* disolve factor */
				Ns,				/* specular exponent */
				sharpness,
				Ni;				/* refraction index */

	/* texturemap statements */
	wave_map_td	map_Ka,		/* ambient map name */
				map_Kd,		/* diffuse map name */
				map_Ks,		/* specular map name */
				map_Ns,		/* specular exponent map name */
				map_d,		/* dissolve map name */
				decal,		/* decal map name */
				bump;		/* bump map name */
	double		bm;			/* bump factor */
	short		map_aat;
	fzrt_int		refl;
	wave_map_td	refl_map[6];
} wave_mtl_td;

typedef struct wave_table_entry_td	*wave_table_entry_ptr;

/* Export working data structure */
typedef struct
{
	fzrt_int					windex;
	char					fname[256];	
	fzrt_floc_ptr			floc,
							saved_floc;
	FILE					*fp;
										
	char					token[WAVE_TOKEN_MAXLEN];
	fz_ffmt_ref_td			ffmt_id;
	char					message[256];
	fzrt_int					pos,
							max_pos;

	wave_table_entry_ptr	lookup_table;
	short					group_sign;

	fz_xyzw_td				*vertices;			/* Array of vertices. */
	fzrt_int					s_vertices,			/* Number of vertices allocated for the array. (The size of the array) */
							n_vertices,			/* Number of vertices in the array. */
							*vertices_links;	/* Vertex connectivity. */

	char					obj_name[256];		/* Object name. */
	fz_objt_ptr				obj;				/* The formZ object. */
	fzrt_int					ncord;				/* Number of vertices in the object. */

	fzrt_boolean			rational;
	short					cstype,

							begin_curvsurf;
	fzrt_int					u_degree,
							v_degree,
							n_u_knots,
							n_v_knots,
							s_u_knots,
							s_v_knots,
							n_control_geom,
							s_control_geom,
							*control_geom;
	double					*u_knot_vec,
							*v_knot_vec;

	fzrt_int					n_segt,			/* Number of edges in segt array. */
							s_segt;			/* Number of edges allocated for segt array. */
	fzrt_int					*segt;			/* Array of object edges. */
	fzrt_int					n_faces,		/* Number of faced in faces array. */
							s_faces;		/* Number of faces allocated for faces array. */
	fzrt_int					*faces;			/* Array of object faces. */
	wave_facemtltab_td		*facemltab;		/* Face material table. */

	fzrt_boolean			do_tmaps;

	wave_seglinktab_td		*seglinktab;
	wave_facemarktab_td		*facemarktab;
	wave_uvtab_td			*uvtab;
	wave_mtllinktab_td		*mtllinktab;
	fz_tag_td				stag;
	fzrt_boolean			do_points;
	fzrt_boolean			do_smooth;
} wave_in_td;

/* Import token/action table */
typedef fzrt_error_td	long_func_wave_lookup(wave_in_td *wave, FILE *fp);
typedef struct wave_table_entry_td
{
	char *text;
	long_func_wave_lookup *func;
} wave_table_entry_td;





/************************************************************************/
/*				Plugin and function set stuff							*/
/************************************************************************/

	/* application provided function sets to hold on to */
extern const fzpl_fset_glue_fset	*_fset_glue;
extern fz_ffmt_fset					_ffmt_funcs;
extern fz_ffmt_data_model_fset			_ffmt_3d_funcs;
extern fz_math_fset					_math_funcs;
extern fz_model_fset					_model_funcs;
extern fz_objt_attr_fset				_objt_attr_funcs;
extern fz_ncrv_fset					_ncrv_funcs;
extern fz_nsrf_fset					_nsrf_funcs;
extern fz_lite_fset					_lite_funcs;
extern fz_proj_fset					_proj_funcs;
extern fz_wind_fset					_wind_funcs;
extern fz_layr_fset					_layr_funcs;
extern fz_grup_fset					_grup_funcs;
extern fz_rmtl_fset					_rmtl_funcs;
extern fz_type_fset					_type_funcs;
extern fz_iost_fset					_iost_funcs;
extern fz_syst_fset					_syst_funcs;
extern fz_fuim_fset					_fuim_funcs;
extern fz_fzrt_mem_fset				_fzrt_mem_funcs;
extern fz_fzrt_file_fset				_fzrt_file_funcs;
extern fz_fzrt_base_fset				_fzrt_base_funcs;
extern fzpl_plugin_query_fset		_plugin_query_funcs;

	/* plugin's runtime id */
extern fzrt_unsigned_int					_wave_plugin_runtime_id;

	/* translator's format reference id */
extern fz_ffmt_ref_td					_wave_ref;

	/* translator's resource file id */
extern fzrt_fzr_ref_td					_fz_rsrc_ref;
	
	/* export custom options */
extern fzrt_int								_write_flags;

	/* import custom options */
extern fzrt_int								_read_flags;





/************************************************************************/
/*							FUNCTION PROTOTYPES							*/
/************************************************************************/

/* Function prototypes for reading */
extern fzrt_error_td wave_read(fzrt_int windex, fz_ffmt_ref_td ffmt_id, fzrt_floc_ptr floc);
extern fzrt_boolean wave_is_wave(fzrt_floc_ptr, const fzrt_ptr, fzrt_int);

/* Function prototypes for writing */
extern fzrt_error_td wave_write_begin(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void **inst, fzrt_floc_ptr floc);
extern fzrt_error_td wave_write_end(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void **inst, fzrt_floc_ptr floc, fzrt_error_td err);
extern fzrt_error_td wave_write_file_begin(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fzrt_floc_ptr floc);
extern fzrt_error_td wave_write_file_end(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fzrt_floc_ptr floc);
extern fzrt_error_td wave_write_group_begin(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_tag_td *fz_tag, char *name);
extern fzrt_error_td wave_write_group_end(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_tag_td *fz_tag, char *name);
extern fzrt_error_td wave_write_points(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fz_xyz_td *vertex_normals, fz_xy_td *vertex_texture_uvs);
extern fzrt_error_td wave_write_lines(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fz_xyz_td *vertex_normals, fz_xy_td *vertex_texture_uvs);
extern fzrt_error_td wave_write_pline(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fz_xyz_td *vertex_normals, fz_xy_td *vertex_texture_uvs);
extern fzrt_error_td wave_write_faces(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fz_xyz_td *face_normals, fz_xyz_td *vertex_normals, fz_xy_td *vertex_texture_uvs);
extern fzrt_error_td wave_write_mesh(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fz_xyz_td *face_normals, fz_xyz_td *vertex_normals, fz_xy_td *vertex_texture_uvs);
extern fzrt_error_td wave_write_trimmed(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fzrt_boolean start, fzrt_boolean end, fzrt_boolean do_tmap);
extern fzrt_error_td wave_can_do_smooth(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fzrt_boolean do_tmap, fz_ffmt_data_model_write_smod_meth_enum *smod_method);
extern fzrt_error_td wave_write_ctrl(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fzrt_boolean do_tmap);
extern fzrt_boolean wave_can_do_ctrl(fzrt_int windex, fz_ffmt_ref_td ffmt_id, void *inst, fz_objt_ptr obj, fzrt_boolean do_tmap, fz_ffmt_data_model_write_cntl_meth_enum cntl_method);

/* Function prototypes for translator options */
extern fzrt_error_td wave_write_opts_default(fz_ffmt_ref_td ffmt_id);
extern fzrt_error_td wave_read_opts_default(fz_ffmt_ref_td ffmt_id);
extern fzrt_error_td wave_out_dlog_cust_func(fz_fuim_tmpl_ptr fuim_tmpl, short parent, fz_ffmt_ref_td ref_id);
extern fzrt_error_td wave_in_dlog_cust_func(fz_fuim_tmpl_ptr fuim_tmpl, short parent, fz_ffmt_ref_td ref_id);
extern fzrt_error_td wave_read_opts_get_flags(fz_ffmt_ref_td ffmt_id, fzrt_int *flags, fzrt_int *opts_flags);
extern fzrt_error_td wave_write_opts_get_flags(fz_ffmt_ref_td ffmt_id, fzrt_int *flags, fzrt_int *opts_flags);
extern fzrt_error_td wave_write_err_lable(fzrt_int windex, fz_ffmt_ref_td ffmt_id, char *str, fzrt_int max_len, short *err_id);
extern fzrt_error_td wave_opts_io(fz_iost_ptr iost, fz_iost_dir_td_enum dir, fzpl_vers_td * const version, fzrt_unsigned_int size);

/* Function prototypes for translator info */
extern fzrt_error_td wave_get_name(char *fmt_name, fzrt_int fmt_name_max_len);
extern fzrt_error_td wave_get_id(fzrt_UUID_td fmt_id);
extern fzrt_error_td wave_get_info(
			char			*sortby,
			fzrt_int			sortby_max_len,
			char			*file_ext,
			fzrt_int			file_ext_max_len,
			char			*keywd,
			fzrt_int			keywd_max_len,
			fzrt_int			*attr_flags
			);
extern fzrt_error_td wave_get_ftype(
			fzrt_ostype		*type,
			fzrt_ostype		*creator
			);
extern fzrt_error_td wave_get_icon(
			fzrt_icon_ptr 	*icon
			);
extern fzrt_error_td wave_2d_tmap_list(fz_ffmt_ref_td ffmt_id, fz_ffmt_ref_td *wave_list, fzrt_int *wave_list_knt_ptr);
extern fzrt_boolean wave_error_str_func(fzrt_int err, char *str, short str_len);

#endif /*__WAVE_PRVT_H*/
