/*ScianPictures.h
  Eric Pepke
  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 POLYPOINT	7	/*A polypoint*/
#define POLYTRI		8	/*Triangular strip*/
#define NPICITEMTYPES	9	/*Numcber of pic types*/

/*Vertex flags*/
#define VF_DEFORMED	1	/*Set iff vertex currently deformed*/
#define VF_COLORED	2	/*Set iff vertex currently colored*/
#define VF_SAMEPLACE	4	/*Set iff vertex should be considered in the
				  same place as last for color and deform*/
#define VF_FIRSTCANON	8	/*Set iff vertex is a first canonical vertex*/
#define VF_NEXTCANON	16	/*Set iff vertex is a next to last canonical vertex*/
#define VF_DONTDRAW	32	/*Don't draw as a point*/

/*Vertex tuple*/
typedef struct vertx
    {
	float normal[3];	/*Normal at that vertex*/
	float position[3];	/*Position of that vertex*/
	short colorIndex;	/*Color within color table*/
	short flags;		/*Flags for vertex*/
	struct vertx *next;	/*Pointer to next vertex in list*/
    } 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 proximity;	/*Extra proximity*/
	short flags;
    } PicItem, *PicItemPtr;

/*Values for picture item flags*/
#define PF_CANONVERTICES	1	/*Vertices are in canonical order*/

/*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
#define DEPTHCUELIGHT	3

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

/*Polygon or poly line or poly point*/
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, Polypoint, Polytri, *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*/
	VertexPtr centerVertex;	/*The center of the sphere*/
	float radius;		/*The radus of the sphere*/
    } 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;
#ifdef MAKEOBJ
	Object picObj;		/*The picture object for Silicon Graphics*/
#endif
	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];				\
									\
		sample = SampleSpatScalar(DEFORMFIELD, DEFORMFORM,	\
			 3, position, true);				\
		if (sample != missingData)				\
		{							\
		(v) -> position[0] = 			\
			((v) -> position[0] + (v) -> normal[0] * 	\
			(sample * globalFactor + globalOffset)) ;	\
		(v) -> position[1] = 			\
			((v) -> position[1] + (v) -> normal[1] * 	\
			(sample * globalFactor + globalOffset));	\
		(v) -> position[2] = 			\
			((v) -> position[2] + (v) -> normal[2] * 	\
			(sample * globalFactor + globalOffset));	\
		}							\
	}								\
	else								\
	{								\
		(v) -> position[0] = 			\
			((v) -> position[0] + (v) -> normal[0] * 		\
			(globalFixed * globalFactor + globalOffset));	\
		(v) -> position[1] = 			\
			((v) -> position[1] + (v) -> normal[1] * 		\
			(globalFixed * globalFactor + globalOffset));	\
		(v) -> position[2] = 			\
			((v) -> position[2] + (v) -> normal[2] * 		\
			(globalFixed * globalFactor + globalOffset));	\
	}								\

/*Vertex drawing macros.  Hate to do it like this, but...

  The name is by this convention:

  PRNS(vertexPointer, nVertices)
  ^^^^
  ||||
  |||+- Color shading, either (N)one, (M)ono, or (S)mooth
  ||+-- Light shading, either (N)one, (M)ono, (S)mooth, or (D)epthcue
  |+--- Color mode, either (R)GB or (C)MAP
  +---- This is always a P, for prepare to draw vertices

  VRNS(vertex)
  ^^^^
  ||||
  |||+- Color shading, either (N)one, (M)ono, or (S)mooth
  ||+-- Light shading, either (N)one, (M)ono, (S)mooth, or (D)epthcue
  |+--- Color mode, either (R)GB or (C)MAP
  +---- This is always a V, for draw vertex

  They all have to be separate for efficiency's sake
*/

#define EXPMINMAX(t, min, max) if ((t) > (max)) (max) = (t); if ((t) < (min)) (min) = (t);

/*Color map macros*/
#define PCNN(vP, nV)
#define VCNN(v) v3f((*v) -> position);

#define PCNM(vP, nV) {int k; long cMin, cMax; VertexPtr (*v); v=vP; cMin=cMax=(*v) -> colorIndex; for(k=1;k<nV;++k) {++v; EXPMINMAX((*v)->colorIndex, cMin, cMax);} color(curBeg + (cMin + cMax) / 2);}
#define PCNMSKIP(vP, nV) {int k; long cMin, cMax; VertexPtr (*v); v=vP; cMin=cMax=(*v) -> colorIndex; for(k=1;k<nV;++k) {v+=nX; EXPMINMAX((*v)->colorIndex, cMin, cMax);} color(curBeg + (cMin + cMax) / 2);}
#define VCNM(v) v3f((*v) -> position);

#define PCNS(vP, nV)
#define VCNS(v) color(curBeg + (*v) -> colorIndex); v3f((*v) -> position);


#define PCMN(vP, nV)
#define VCMN(v) color((int) (curBeg + 2 + ((*v) -> normal[0] * 0.5 + 0.5) * (curNColors - 5))); v3f((*v) -> position);

#define PCMM PCNM
#define VCMM VCNM

#define PCMS PCNS
#define VCMS VCNS


#define PCSN PCMN
#define VCSN VCMN

#define PCSM PCMM
#define VCSM VCMM

#define PCSS PCMS
#define VCSS VCMS


#define PCDN PCNN
#define VCDN VCNN

#define PCDM PCNM
#define PCDMSKIP PCNMSKIP
#define VCDM VCNM

#define PCDS PCNS
#define VCDS VCNS


/*RGB macros*/
#define PRNN(vP, nV)
#define VRNN(v) v3f((*v) -> position);

#define PRNM(vP, nV) {int k; long cMin, cMax; VertexPtr (*v); v = vP; cMin = cMax = (*v) -> colorIndex; for(k=1;k<nV;++k) {++v; EXPMINMAX((*v)->colorIndex, cMin, cMax);} c3s(curColors[(cMin + cMax) / 2]);}
#define PRNMSKIP(vP, nV) {int k; long cMin, cMax; VertexPtr (*v); v = vP; cMin = cMax = (*v) -> colorIndex; for(k=1;k<nV;++k) {v+=nX; EXPMINMAX((*v)->colorIndex, cMin, cMax);} c3s(curColors[(cMin + cMax) / 2]);}
#define VRNM(v) v3f((*v) -> position);

#define PRNS(vP, nV)
#define VRNS(v) c3s(curColors[(*v) -> colorIndex]); v3f((*v) -> position);


#define PRMN PRNN
#define VRMN(v) n3f((*v) -> normal); v3f((*v) -> position);

#define PRMM PRNM
#define VRMM(v) n3f((*v) -> normal); v3f((*v) -> position);

#define PRMS PRMM
#define VRMS(v) c3s(curColors[(*v) -> colorIndex]); n3f((*v) -> normal); v3f((*v) -> position);


#define PRSN PRMN
#define VRSN VRMN

#define PRSM PRMM
#define VRSM VRMM

#define PRSS PRMM
#define VRSS VRMS

/*Depth cue*/
#define PRDN(vP, nV) 
#define VRDN(v)  v3f((*v) -> position);

#define PRDM(vP, nV)  {int k; long cMin, cMax; VertexPtr (*v); v = vP; cMin = cMax = (*v) -> colorIndex; for(k=1;k<nV;++k) {++v; EXPMINMAX((*v)->colorIndex, cMin, cMax);}\
	k = (cMin + cMax) / 2;	\
	lRGBrange(0,		\
		  0,		\
		  0,		\
		  curColors[k][0],		\
		  curColors[k][1],		\
		  curColors[k][2], curZMin, curZMax);}
#define PRDMSKIP(vP, nV)  {int k; long cMin, cMax; VertexPtr (*v); v = vP; cMin = cMax = (*v) -> colorIndex; for(k=1;k<nV;++k) {v+=nX; EXPMINMAX((*v)->colorIndex, cMin, cMax);}\
	k = (cMin + cMax) / 2;	\
	lRGBrange(0,		\
		  0,		\
		  0,		\
		  curColors[k][0],		\
		  curColors[k][1],		\
		  curColors[k][2], curZMin, curZMax);}
#define VRDM(v) v3f((*v) -> position);

#define PRDS(vP, nV)
#define VRDS(v)	{int k; k = (*v) -> colorIndex;		\
	lRGBrange(0,		\
		  0,		\
		  0,		\
		  curColors[k][0],		\
		  curColors[k][1],		\
		  curColors[k][2], curZMin, curZMax);		\
		  v3f((*v) -> position);}

/*Versions for rect mesh with center nodes*/
#define MCRPCNM(vP) color(curBeg + (*(vP)) -> colorIndex);
#define MCRPRNM(vP) c3s(curColors[(*(vP)) -> colorIndex]);

#ifdef PROTO
ObjPtr NewPicture(void);
PolyPtr AppendPolyToPicture(ObjPtr, long, Vertex[]);
PolyPtr AppendPolylineToPicture(ObjPtr, int, int, long, Vertex[]);
PolyPtr AppendSPolylineToPicture(ObjPtr, int, int, long, VertexPtr[]);
PolyPtr AppendSPolypointToPicture(ObjPtr, int, long, VertexPtr[]);
PolyPtr AppendPolyToPolys(PolysPtr, long, Vertex[]);
PolyPtr AppendSPolyToPolys(PolysPtr, long, VertexPtr[]);
PolyPtr TesselateSPolyToPicture(ObjPtr, long, 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, int, int, ObjPtr);
void PrepareToDraw(Bool, int, int, ObjPtr);
void DoneDrawing();
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);
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, int);
void FreeVertex(VertexPtr);
void ConvertFrustumOntoPicture(ObjPtr, float end1[3], float, float end2[3], float, int, Bool);
PolysPtr ConvertSphereOntoPicture(ObjPtr, VertexPtr, real, int, int);
void ZeroPictureTime(void);
long GetPictureTime(void);
#else
Bool AppendPolyToPicture();
PolyPtr AppendPolylineToPicture(ObjPtr, int, int, int, Vertex[]);
PolyPtr AppendSPolypointToPicture(ObjPtr, int, int, int, Vertex[]);
Bool AppendPolyToPolys();
Bool AppendFrustumToPicture();
PolyPtr AppendSPolyToPolys(PolysPtr, int, VertexPtr[]);
PolysPtr AppendPolysToPicture();
void ConvertFrustumOntoPicture();
Bool AppendSphereToPicture();
ObjPtr NewPicture();
void DrawPicture();
void PrepareToDraw();
void DoneDrawing();
void GetPictureBounds();
void InitPictures();
void KillPictures();
void ColorPictureByObject();
void DeformPictureByObject();
void CalcPictureNormals();
void UnColorPicture();
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();
PolysPtr ConvertSphereOntoPicture();
void ZeroPictureTime(void);
long GetPictureTime(void);
#endif
