#ifndef _GRF4INTERNAL_H_

/* Event flags */

#define RESIZE_EVENT	1
#define REDRAW_EVENT	2
#define MOTION_EVENT	3
#define BUTTON_EVENT	4
#define WINEXIT_EVENT	5

struct grf4fxnTable {
	void (*getWindowSize)();
	long (*capacity)();
	void (*cycle)();
	void (*wait)();
	 int (*select)();
	void (*ortho)();
	void (*window)();
	void (*loadTrans)();
	void (*color)();
	void (*clear)();
	void (*flush)();
	void (*move)();
	void (*draw)();
	void (*move2)();
	void (*draw2)();
	void (*drawPrism)();
	void (*drawSphere)();
	void (*drawPolygon)();
	void (*drawLineSet)();
	PRISM* (*genDisc)();
	PRISM* (*genCone)();
	PRISM* (*genPrism)();
	SPHERE* (*genSphere)();
	POLYGON* (*genPolygon)();
	POLYGON* (*genRegPolygon)();
	LINESET* (*genLineSet)();
	double (*setDepth)();
	int (*overPrism)();
	int (*overSphere)();
	void (*eventHandler)();

	void (*drawButton)();
	void (*getButtonExtent)();
	
	void (*getButtonState)();
	void (*getCursorState)();

	void (*pxlDraw)();
	void (*pxlClear)();
	void (*pxlFlush)();

	void* (*defLight)();
	void* (*defMaterial)();
	void* (*defMaterialD)();
	void (*setMaterial)();
	void (*setLight)();
	void (*resetLights)();
  };

struct localFxnTable {
	void (*draw);
	void (*clear);
	void (*flush);
  };

typedef struct buttonDesc {
	struct buttonDesc *next;
	int num;
	char *name;
	int flags;
	int sizeK;
	int x, y, w, h;
	int coffX;
	int coffY;
	int minw;
	int minh;
	int (*fxn)();
	long arg;
	int row;
	int rowSizeK;
	int rowMinW;
	int rowN;
  } BUTTON_DESC;

#if HLS

#define HIDE_EVENT	1
#define EXPOSE_EVENT	2

#define P_DONT_INTERSECT	0
#define P_INTERSECT		1
#define P_POLY1_INSIDE		2
#define P_POLY2_INSIDE		3

typedef struct pevent {
	struct pevent *next;	/* used for event list */
	float r;		/* point along edge/vector of event */
	int type;		/* type of event: expose or hide */
} PEVENT;

typedef struct vector {
	/* Describes a single vector */

	struct vector *next;	/* forms double linked list of */
	struct vector *prev;	/*   vectors that must be drawn */
	float x1, y1, ez1;	/* endpoints coordinates for the vector */
	float x2, y2, ez2;	/*   x,y in screen and ez in eye coords */

	int visible;		/* indicates entire vector is invisible */
	PEVENT *events;		/* list of hide/expose events */
	
	/* fields below are used by the intersection code */

	float rOut;		/* point where vector exits polygon */
	float rInto;		/* point where vector enters polygon */
} VECTOR;

typedef struct pedge {
	/* Describes a vertex associated with a polygon, as well as
	   the edge formed by travelling in the counter-clockwise
	   ('next') direction to the next vertex.

	   An edge can be obscured by other polygons. Information
	   on how the edge is obscured is kept as follows:

	   'visible' denotes whether the beginning of the edge (at
	   the vertex) is visible. 'nextEvents' is a list of hide
	   and expose events for the edge. If 'visible' is true and
	   'nextEvents' is NULL, the edge is completely visible. */

	struct pedge *next;	/* pointers for linked list of */
	struct pedge *prev;	/*   vertices/edges */
	PEVENT *nextEvents;	/* list of hide/expose events */
	PEVENT *prevEvents;	/* closest event on previous edge, if any
				   (not used at time of this writing) */

	float x, y;		/* x and y screen coordinates for vertex */
	float ez;		/* z eye coordinates for vertex */
	int visible;		/* true if the vertex is visible. */

	/* the fields below are used by the polygon intersect code. */

	int intersect;		/* there is an intersection on this edge */
#define INTO	1		/* edge is ``entering'' the other polygon */
#define OUT	2		/* edge is ``exiting'' the other polygon */
	float rInto;		/* distance along edge for enter point */
	float rOut;		/* distance along edge for exit point */
} PEDGE;

typedef struct polygon {
	struct polygon *next;	/* prev and next create a double linked */
	struct polygon *prev;	/* list of the polygons to be drawn */
	int visible;		/* is polygon is completely invisible? */ 
	int n;			/* number of edges in the polygon */

	/* polygons edges are stored as a double circular linked list
	   of vertices, in counter-clockwise order */

	PEDGE *edges;		/* pointer to edge list */
	float nrml[3];		/* normal vector for the polygon */

	float xmax, xmin;	/* these define a bounding box for the */
	float ymax, ymin;	/* polygon. x and y are in screen */
	float ezmax, ezmin;	/* coordinates; ez is in eye coordinates */
	int objCnt;		/* indicates parent object, if any */
} SCR_POLYGON;

typedef struct _IEDGE {

	/* vertices/edges for a polygon created by the intersection
	   of two polygons */

	struct _IEDGE *next;
	struct _IEDGE *prev;

	int intersection;	/* vertex is an intersection point */
	SCR_POLYGON *poly;	/* pointer to current inside polygon */
	PEDGE *edgeIn;		/* pointer to current inside edge */

	/* these next three fields are set only if there is an 
	   intersection. */

	float rIn;		/* inside edge distance to intersection */
	PEDGE *edgeOut;		/* pointer to current outside edge */
	float rOut;		/* outside edge distance to intersection */

} IEDGE;

typedef struct {
	/* Polygon created by the intersection of two polygons */

	int n;			/* number of vertices */
	IEDGE *edges;		/* pointer to list of edges */
} INTER_POLYGON;

VECTOR* newVector();
PEDGE* newPedge();
PEVENT* newPevent();
SCR_POLYGON* newPolygon();

#endif
#endif
