
#ifndef __PGGL__
#define __PGGL__
#include <photon/PhT.h>
#include <photon/PhProto.h>
#include <photon/PmT.h>
#include <photon/PhMsg.h>
#include <photon/PdDirect.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <GL/gl.h>

/*	TODO:  Uncomment this line to enable the plugin code (once the OpenGL
 *	plugin for io-graphics is ready */

/* #define OPENGL_PLUGIN_READY */
#ifdef __cplusplus
extern "C"
{
#endif

typedef struct _pdogldc 
{
	PhDrawContext_t dc;				/* the binding draw context...most of this is wasted space...maybe we can shrink it? */
	PhConnectId_t connect_id;
#ifdef OPENGL_PLUGIN_READY	
	uint32_t num_osc;				/* the number of offscreen contexts used for rendering */
	PdOffscreenContext_t **ids;		/* the contexts that opengl will render into */
	PhRid_t target_rid;				/* the rid that this context is to blit to (for swap buffers) */

/* need to add opengl state here...	
 * shared memory implementation for local...phrelay 
 * will be forced to use service messages for some gl calls

 * I think we also need the client push and pop stuff
 * in here. */
	uint32_t reserved [20]; 
#else
    /* The ugly hack, don't use any of these members, they won't exist in the future (or at least not in this form) 
	 * Right now they are considered for internal use by the library only. */

	void *fxctx;	/* Full screen glide only */
	void *osctx;	/* The fallback */
	PhDim_t colbuf_size;		/* dimensions of rendering buffer */
	PhDim_t disp_size;		/* dimensions of the display size */
	uint32_t bpl;			/* bytes per line of the rendering display */
	uint32_t bpp;			/* bits per pixel of the renderer */
	PhImage_t *image;		/* pointer to the software buffer (OSmesa only) */
	char **buffers;			/* pointer to software rendering buffers */
	uint32_t flags;			/* misc flags */
	PgDisplaySettings_t *orig_display;
	PhRid_t *target_rid;
	uint32_t reserved [10];	
#endif
} PdOpenGLContext_t;

/* Internal flags, may disappear in the future */

#define PHOGL_INTERNAL_CENTER	  0x01 	/* Center */
#define PHOGL_INTERNAL_FULLSCREEN 0x02  /* fullscreen */
#define PHOGL_INTERNAL_BEST		  0x04	/* Best Fit */


/* Attribute flags for Creation of OpenGL Contexts in Photon */

#define PHOGL_ATTRIB_NONE 				0	/* attrib terminator */

#define PHOGL_ATTRIB_FULLSCREEN	 		1	/* tells the rendering subsystem wether you're fullscreen or windowed 
											 * (there may be cases where you can get HW Accel with 
											 * fullscreen but not windowed) */
#define PHOGL_ATTRIB_FULLSCREEN_BEST	2	/* Tell the system when going full screen to choose the best resolution available
											 * for the requested rendering buffer (you ask for 320x200 fullscreen, but the
											 * video driver only can go as low as 640x480, the display will be 640x480
											 * This will always choose a display that is >= the rendering buffer, if 
											 * the rendering buffer is larger than the largest display it will still fail. */
#define PHOGL_ATTRIB_FULLSCREEN_CENTER	3	/* For PdOpenGLSwapBuffers, center the rendering buffer if the display 
											 * is larger than the rendering buffer. (Fullscreen only) */


#define PHOGL_ATTRIB_DEPTH_BITS			4	/* followed by uint64, requested z-buffer bit depth         */
#define PHOGL_ATTRIB_STENCIL_BITS		5   /* followed by uint64, requested stencil-buffer bit depth   */
#define PHOGL_ATTRIB_STEREO				6	/* requestes stereo rendering (for VR glasses and the like) */

#define PHOGL_ATTRIB_BUFFER				7	/* followed by a PdOffscreenContext_t *, says that this 
											 * offscreen context_t should be used as a rendering buffer
											 * you can have multple PHOGL_ATTRIB_BUFFER calls in the attrib list
											 * but they all must have the same properties.  They will be inserted
											 * in the order they appear. */

#define PHOGL_ATTRIB_DIRECT				8	/* Fastest possible method of rendering, must be used in conjunction with
											 * fullscreen.  This loads the OpenGL rendering subsystem into your programs
											 * address space, as well as the hw driver.  The OpenGL system will inherit 
											 * the apps memory management scheme as a result (like page swapping), but
											 * the app must be setuid root, since it will be hitting registers on 
											 * the grafx card through the driver dll.  Danger is if the app crashes and
											 * leaves the hardware in a bad state (stray pointer bangs a register or 
											 * something), the photon system may not be able to
											 * recover, and the user may have to reboot.  Another drawback is that
											 * you will not be able to use any photon draw primatives while in this
											 * mode.  (So you can't drop a widget into your currently active opengl 
											 * render buffer, shouldn't normally be an issue with games, which is what 
											 * this mode is really meant for).  This will also put you into direct mode
											 * if you already aren't.  (can't have other apps using io-graphics to render
											 * while your app is banging on registers).
											 *
											 * This is the method that Mesa + glide uses, it should work with the
											 * native io-graphics drivers as well. */
											
#define PHOGL_ATTRIB_FORCE_SW			9	/* Force a software renderer. */
#define PHOGL_ATTRIB_FORCE_HW			10	/* Force a renderer that has at least some hardware support */
#define PHOGL_ATTRIB_FAVOR_HW			11	/* Never use a software routine for rendering, if the hardware can't do 
											 * the exact,operation, then it will do the closest one it can 
											 * (games would likely use this one to keep frame rates up on low 
											 * end video cards), Cad, Level Editors, 3d paint programs, etc. 
											 * wouldn't.  This assumes at least a flat shaded, texture mapped
											 * triangle routine with a z buffer (possibly more to be defined...).
											 * Can't be used in conjunction with FORCE_SW, implies FORCE_HW. */

#define PHOGL_GET_BUFFER_DISPLAY		-1
#define PHOGL_GET_BUFFER_RENDER			0

/* function prototypes */

PdOpenGLContext_t * PdCreateOpenGLContext(int num_buf, PhDim_t *dim, int bpp, uint64_t *attrib);
int PdOpenGLContextSetRid (PdOpenGLContext_t *oglc, PhRid_t rid);
int PdOpenGLContextSwapBuffers(PdOpenGLContext_t *oglc);

/* Not yet implemented or supported */
PdOffscreenContext_t *PdGetOpenGLContextBuffer(PdOpenGLContext_t *oglc, int rendering_buffer);
int PdOpenGLContextResize (PdOpenGLContext_t *oglc, PhDim_t *dim);

#ifdef __cplusplus
};
#endif

#endif
