/* :ts=8 */

#ifndef GENERAL_H
#define GENERAL_H

/************************************************************************/
/*									*/
/* 			General includefile for ICoons.			*/
/*									*/
/* This file defines most of the types and constants used in the program*/
/*									*/
/************************************************************************/

#ifndef TRUE

#define TRUE 	1
#define FALSE 	0

#endif

#define ABS(x)		((x) < 0 ? -(x) : (x))
#define MAX(x,y)	((x) > (y) ? (x) : (y))
#define MIN(x,y)	((x) < (y) ? (x) : (y))
#define SGN(x) 		((x) < 0 ? -1 : 1)
	
	/* Name of config file:					*/
#define Default_Config_File_Name "ICoons.cfg"

	/* Size of character buffers:				*/
#define Buffer_Length   255

	/* Tiny number, used for "fuzzyness" of doubles:	*/
#define FTINY		(double) 1e-6

	/* Max size for file and path names:			*/
#define File_Name_Length	20
#define Path_Name_Length	100

	/* Max possible resolution for splines:			*/
#define Max_Spline_Resolution	10

	/* Max possible resolution for patches:			*/
#define Max_Patch_Resolution	20

	/* Max Nbr. of points:					*/
#define Max_Nbr_Points		500

	/* Possible values for Flags fields (may be ORed):	*/
#define Flags_Hidden		0x01
#define Flags_Selected		0x02
#define Flags_Marked		0x04

#define Mask_VSelected		0x03
#define Mask_VMarked		0x05

	/* Macros to manipulate Flags fields:			*/
#define Do_Mark(X)   	(X).Flags |= Flags_Marked
#define Do_Hide(X)   	(X).Flags |= Flags_Hidden
#define Do_Select(X)   	(X).Flags |= Flags_Selected
#define Do_Unmark(X)   	(X).Flags &= ~Flags_Marked
#define Do_Unhide(X)   	(X).Flags &= ~Flags_Hidden
#define Do_Deselect(X)  (X).Flags &= ~Flags_Selected

#define Is_Marked(X) 	((X).Flags & Flags_Marked)
#define Is_Hidden(X) 	((X).Flags & Flags_Hidden)
#define Is_Visible(X) 	(!Is_Hidden(X))
#define Is_Selected(X) 	((X).Flags & Flags_Selected)

	/* Is visible and selected:	*/
#define Is_VSelected(X) (((X).Flags & Mask_VSelected) == Flags_Selected)

	/* Is visible and marked:	*/
#define Is_VMarked(X) (((X).Flags & Mask_VMarked) == Flags_Marked)


	/* Possible values for What parameter (may be ORed)	*/
#define What_SX		0x01	/* Draw splines in 3d X view	*/
#define What_SY		0x02	/* Draw splines in 3d Y view	*/
#define What_SZ		0x04	/* Draw splines in 3d Z view	*/
#define What_SP		0x08	/* Draw splines in persp view	*/

#define What_KX		0x10	/* Draw knots in 3d X view	*/
#define What_KY		0x20	/* Draw knots in 3d Y view	*/
#define What_KZ		0x40	/* Draw knots in 3d Z view	*/
#define What_KP		0x80	/* Draw knots in persp view 	*/

	/* Combination of What masks:				*/

#define What_S3		0x07	/* Draw splines in all 3d views	*/
#define What_K3		0x70	/* Draw knots in all 3d views	*/
#define What_S		0x0f	/* Draw splines in all views	*/
#define What_K		0xf0	/* Draw knots in all views 	*/
#define What_X		0x11	/* Draw all in X view		*/
#define What_Y		0x22	/* Draw all in Y view		*/
#define What_Z		0x44	/* Draw all in Z view		*/
#define What_P		0x88	/* Draw all in persp view	*/
#define What_All	0xff	/* Draw everything          	*/

typedef unsigned char	Byte_T;
typedef short		Boolean_T;

typedef double 		Vector_T[3];
typedef double 		Vector4_T[4];

typedef double 		Matrix_T[3][3];
typedef double 		Matrix4_T[4][4];

	/* Type for drawing mode:				*/
typedef enum {
    DM_Normal,	/* Normal draw mode		*/
    DM_Erase,	/* Erase draw mode		*/
    DM_Plane	/* Draw in separate plane	*/
} Draw_Mode_T;

	/* Type for rendering mode:				*/
typedef enum {
    RM_Line,
    RM_Flat,
    RM_Gouraud,
    RM_Phong
} Rendering_Mode_T;

	/********************************************************/
	/*							*/
	/* Type for a point:					*/
	/*							*/
	/*   Flags:						*/
	/* 	Flags for this point (selected, marked etc.)	*/
	/*							*/
	/*   Reference_Count:					*/
	/* 	Nbr of knots referencing this point.		*/
	/* 	If Reference_Count <= 0, then this point isn't	*/
	/* 	in use.						*/
	/*   Work:						*/
	/* 	Work variable used in file.c			*/
	/*							*/
	/*   Pos:						*/
	/* 	Position of point in world coordinates.		*/
	/*							*/
	/********************************************************/

typedef	struct {
	Byte_T		Flags;
	short		Reference_Count;
	short		Work;
	Vector_T	Pos;
} Point_T;

	/********************************************************/
	/*							*/
	/* Type for a knot:					*/
	/*							*/
	/*   Next: 						*/
	/* 	Pointer to next knot in this spline. 		*/
	/*	If this is a looping spline, then the last knot	*/
	/*	will point to the first knot; otherwise it will	*/
	/*	point to NULL.					*/
	/*							*/
	/*   Previous: 						*/
	/* 	Pointer to previous knot in this spline.	*/
	/*	If this is a looping spline, then the first knot*/
	/*	will point to the last knot; otherwise it will	*/
	/*	point to NULL.					*/
	/*							*/
	/*   Flags:						*/
	/* 	Flags for this knot (selected, marked etc.)	*/
	/*							*/
	/*   Point_Id:						*/
	/* 	Idx in point array for associated point.	*/
	/*							*/
	/*   NX, NY, NZ, NP:					*/
	/* 	Nbr of entries in ViewX, ViewY, ViewZ and ViewP	*/
	/*							*/
	/*   ViewX, ViewY, ViewZ, ViewP:			*/
	/*	Polyline data (screen coordinates) for the 	*/
	/* 	spline from this knot to next knot.		*/
	/* 	Data exist for each of the four views.		*/
	/*							*/
	/*   Tension:						*/
	/* 	Tension of this knot.				*/
	/*							*/
	/*   Bias:						*/
	/* 	Bias of this knot.				*/
	/*							*/
	/*   Continuity:					*/
	/* 	Continuity of this knot.			*/
	/*							*/
	/********************************************************/

typedef struct Knot_Tag {
	struct Knot_Tag	*Next;
	struct Knot_Tag	*Previous;
	Byte_T		Flags;
	short		Point_Id;
	Byte_T		NX, NY, NZ, NP;
	short		ViewX[Max_Spline_Resolution+1][2];
	short		ViewY[Max_Spline_Resolution+1][2];
	short		ViewZ[Max_Spline_Resolution+1][2];
	short		ViewP[Max_Spline_Resolution+1][2];
	double		Tension;
	double		Bias;
	double		Continuity;
} Knot_T;

	/********************************************************/
	/*							*/
	/* Type for a spline:					*/
	/*							*/
	/*   Next: 						*/
	/* 	Pointer to next spline. NULL if this is last	*/
	/*	spline.						*/
	/*							*/
	/*   Previous: 						*/
	/* 	Pointer to previous spline. NULL if this is 	*/
	/*	first spline.					*/
	/*							*/
	/*   Flags:						*/
	/* 	Flags for this spline (selected, marked etc.)	*/
	/*							*/
	/*   Nbr_Knots:						*/
	/* 	Number of knots in this spline.			*/
	/*							*/
	/*   Loop:						*/
	/* 	TRUE if this spline is a closed loop.		*/
	/*							*/
	/*   First:						*/
	/* 	Pointer to first knot in this spline.		*/
	/*							*/
	/*   Last:						*/
	/* 	Pointer to last knot in this spline.		*/
	/*							*/
	/********************************************************/

typedef struct Spline_Tag {
	struct Spline_Tag *Next;
	struct Spline_Tag *Previous;
	Byte_T		  Flags;
	short		  Nbr_Knots;
	Boolean_T	  Loop;
	Knot_T		  *First;
	Knot_T		  *Last;
} Spline_T;


	/********************************************************/
	/*							*/
	/* Type for a state:					*/
	/*							*/
	/* This defines the current state of the program.	*/
	/*							*/
	/*   Handle_Event:					*/
	/* 	Function to be called for IDCMP events.		*/
	/*							*/
	/*   Timeout:						*/
	/* 	Function to be called when a timeout happens.	*/
	/*							*/
	/*   Redraw:						*/
	/* 	Function to be called to redraw the screen.	*/
	/*							*/
	/*							*/
	/********************************************************/

typedef struct {
	Boolean_T 	(*Handle_Event)();
	void 		(*Timeout)();
	void 		(*Redraw)();
} State_T;

/* Vector manipulation macros: */
#include "vector.h"

#endif
