/*ScianPictures.h
  External stuff and data structures for ScianPictures.c
*/

#define CARDBASIS	1	/*Basis for cardinal spline*/

#define SOLIDLINE	0	/*Solid line*/
#define DASHEDLINE	1	/*Line style for dashed line*/
#define DOTTEDLINE	2	/*Line style for dotted line*/

/*Values for picture item type.  Must go from 0 up by ones*/
#define POLYGON		0	/*Type for a polygon*/
#define FRUSTUM		1	/*Conical frustum*/
#define SPHERE		2	/*Sphere*/
#define RECTMESH	3	/*Rectangular mesh*/
#define PLANARPOLYGON	4	/*Planar polygon*/
#define POLYGONS	5	/*A bunch of polygons*/
#define POLYLINE	6	/*A polyline*/
#define NPICITEMTYPES	7	/*Number of pic types*/

/*Vertex flags*/
#define VF_DEFORMED	1	/*Set iff vertex currently deformed*/

/*Vertex tuple*/
typedef struct vertx
    {
	float normal[3];	/*Normal at that vertex*/
	float position[3];	/*Position of that vertex*/
	int colorIndex;		/*Color within color table*/
	struct vertx *next;	/*Pointer to next vertex in list*/
	int flags;		/*Flags for vertex*/
    } Vertex, *VertexPtr;

/*Item in a picture*/
typedef struct picitem
    {
	struct picitem *next;	/*Next item in list*/
	short type;		/*Type of item.  Based on this, it's really
				  interpreted as something else*/
	short colorShading;	/*Color shading*/
	short lightShading;	/*Light shading*/
	short proximity;	/*Extra proximity*/
    } PicItem, *PicItemPtr;

/*Don't change the values of these defines!*/
/*Values for color shading*/
#define NOCOLOR		0
#define MONOCOLOR	1
#define SMOOTHCOLOR	2

/*Values for light shading*/
#define NOLIGHT		0
#define MONOLIGHT	1
#define SMOOTHLIGHT	2

/*Values for current color mode*/
#define CMODECMAP	0
#define CMODERGB	1

/*Polygon or poly line*/
typedef struct
    {
	PicItem item;		/*The item part*/
	int lineWidth;		/*Line width*/
	VertexPtr centerVertex;	/*The vertex at the center*/
	long nVertices;		/*Number of vertices*/
	VertexPtr vertices[1];  /*The vertices*/
    } Polygon, Polyline, *PolyPtr;

/*A bunch of polygons, all with the same colorShading and lightShading*/
typedef struct
    {
	PicItem item;		/*The item part*/
	Bool enclosed;		/*True iff totally enclosed*/
	struct pic *picture;	/*The picture it belongs to, for backing up*/
	PolyPtr polygons;	/*The polygons*/
	PolyPtr lastItem;
    } Polygons, *PolysPtr;

/*Conical frustum*/
typedef struct
    {
	PicItem item;		/*The item part*/
	float end1[3];		/*First endpoint*/
	float rad1;		/*Radius at first endpoint*/
	float end2[3];		/*Second endpoint*/
	float rad2;		/*Radius at second endpoint*/
	int colorIndex;		/*Color index*/
    } Frustum, *FrustumPtr;

/*Sphere*/
typedef struct
    {
	PicItem item;		/*The item part*/
	float center[3];	/*The center of the sphere*/
	float radius;		/*The radus of the sphere*/
	int colorIndex;		/*The color indices*/
    } Sphere, *SpherePtr;

/*Rectangular mesh*/
typedef struct
    {
	PicItem item;		/*The item part*/
	Bool inCenter;		/*Nodes are in center rather than around*/
	long xDim;		/*Y dimension*/
	long yDim;		/*X dimension*/
	VertexPtr vertices[1];	/*The vertices*/
    } RectMesh, *RectMeshPtr;

/*Picture*/
typedef struct pic
    {
	Thing thing;
	VertexPtr vertices;	/*The vertices used in the picture*/
	VertexPtr lastVertex;	/*The last vertex for adding onto the list*/
	PicItemPtr items;	/*The list of actual items*/
	PicItemPtr lastItem;
    } Picture, *PicPtr;

#define RECTMESHVERTEX(rectMesh, i, j) ((j) * 2 + (i) * (2 * (rectMesh) -> yDim - 1))
#define RECTMESHCENTER(rectMesh, i, j) ((j) * 2 + 1 + (i) * (2 * (rectMesh) -> yDim - 1))

/*Deforms vertex v*/

#define DEFORMVERTEX(v) if (globalDeformObject)				\
	{								\
		real position[3];					\
		real sample;						\
									\
		position[0] = (v) -> position[0];				\
		position[1] = (v) -> position[1];				\
		position[2] = (v) -> position[2];				\
									\
		if (SampleSpatField(DEFORMFIELD, DEFORMFORM, 1, &sample,\
			 3, position, true));				\
		if (sample != missingData)				\
		{							\
		(v) -> position[0] = globalXScale *			\
			((v) -> position[0] + (v) -> normal[0] * 	\
			(sample * globalFactor + globalOffset)) ;	\
		(v) -> position[1] = globalYScale *			\
			((v) -> position[1] + (v) -> normal[1] * 	\
			(sample * globalFactor + globalOffset));	\
		(v) -> position[2] = globalZScale *			\
			((v) -> position[2] + (v) -> normal[2] * 	\
			(sample * globalFactor + globalOffset));	\
		}							\
	}								\
	else								\
	{								\
		(v) -> position[0] = globalXScale *			\
			((v) -> position[0] + (v) -> normal[0] * 		\
			(globalFixed * globalFactor + globalOffset));	\
		(v) -> position[1] = globalYScale *			\
			((v) -> position[1] + (v) -> normal[1] * 		\
			(globalFixed * globalFactor + globalOffset));	\
		(v) -> position[2] = globalZScale * 			\
			((v) -> position[2] + (v) -> normal[2] * 		\
			(globalFixed * globalFactor + globalOffset));	\
	}								\


#ifdef PROTO
ObjPtr NewPicture(void);
PolyPtr AppendPolyToPicture(ObjPtr, int, Vertex[]);
PolyPtr AppendPolylineToPicture(ObjPtr, int, int, int, Vertex[]);
PolyPtr AppendPolyToPolys(PolysPtr, int, Vertex[]);
PolyPtr AppendSPolyToPolys(PolysPtr, int, VertexPtr[]);
FrustumPtr AppendFrustumToPicture(ObjPtr, float end1[3], float, float end2[3], float, int);
PolysPtr AppendPolysToPicture(ObjPtr);
SpherePtr AppendSphereToPicture(ObjPtr, float center[3], float, int);
RectMeshPtr AppendRectMeshToPicture(ObjPtr, long, long, Bool);
void DrawPicture(ObjPtr, Bool, ObjPtr);
void GetPictureBounds(ObjPtr, real bounds[6]);
void InitPictures(void);
void KillPictures(void);
void ColorPictureByObject(ObjPtr, ObjPtr, Bool);
void DeformPictureByObject(ObjPtr);
void CalcPictureNormals(ObjPtr);
void UnColorPicture(ObjPtr);
void SetPicColorShading(ObjPtr pic, int shading);
void SetPicLightShading(ObjPtr pic, int shading);
VertexPtr RectMeshVertex(RectMeshPtr rectMesh, long i, long j);
VertexPtr RectMeshCenter(RectMeshPtr rectMesh, long i, long j);
void InterpRectCenters(RectMeshPtr);
void InterpRectVertices(RectMeshPtr);
void CalcRectNormals(RectMeshPtr);
ObjPtr ConvertPicture(ObjPtr, ObjPtr);
ObjPtr ConvertOntoPicture(ObjPtr, ObjPtr, ObjPtr);
void ColorItemsByObject(PicItemPtr curItem, ObjPtr colorObj, Bool);
void DeformItemsByObject(PicItemPtr curItem);
void ColorItemByObject(PicItemPtr curItem, ObjPtr colorObj, Bool);
void DeformItemByObject(PicItemPtr curItem);
void ColorItemsWithIndex(PicItemPtr curItem, int);
void ColorItemWithIndex(PicItemPtr curItem, int);
void ColorPictureByPicture(ObjPtr, ObjPtr, ObjPtr);
PicItemPtr ColorItemsByItems(PicItemPtr destItem, ObjPtr owner, PicItemPtr curItem);
VertexPtr NewVertex(ObjPtr);
void FreeVertex(VertexPtr);
void ConvertFrustumOntoPicture(ObjPtr, float end1[3], float, float end2[3], float, int, Bool);
#else
Bool AppendPolyToPicture();
Bool AppendPolyToPolys();
Bool AppendFrustumToPicture();
PolyPtr AppendSPolyToPolys(PolysPtr, int, VertexPtr[]);
PolysPtr AppendPolysToPicture();
void ConvertFrustumOntoPicture();
Bool AppendSphereToPicture();
ObjPtr NewPicture();
void DrawPicture();
void GetPictureBounds();
void InitPictures();
void KillPictures();
void ColorPictureByObject();
void DeformPictureByObject();
void CalcPictureNormals();
void UnColorPicture();
void SetPicColorShading();
void SetPicLightShading();
VertexPtr RectMeshVertex();
VertexPtr RectMeshCenter();
void InterpRectCenters();
void InterpRectVertices();
void CalcRectNormals();
ObjPtr ConvertPicture();
ObjPtr ConvertOntoPicture();
PolysPtr SphereToPolys();
void ColorItemsByObject();
void DeformItemsByObject();
void ColorItemByObject();
void DeformItemByObject();
void ColorItemsWithIndex();
void ColorItemWithIndex();
void ColorPictureByPicture();
PicItemPtr ColorItemsByItems();
VertexPtr NewVertex();
void FreeVertex();
void ConvertFrustumOntoPicture();
#endif
