#ifndef V_GL_H
#define V_GL_H

/*
 * Macros for calling vector-style GL primitive-definition functions.
 */
#ifdef	DOUBLEVEC
#define	GL_VERTEX3V	glVertex3dv
#define	GL_NORMAL3V	glNormal3dv
#define	GL_COLOR3V	glColor3dv
#define	GL_COLOR4V	glColor4dv
#define	GL_TEXCOORD2V	glTexCoord2dv
#else	/* !DOUBLEVEC */
#define	GL_VERTEX3V	glVertex3fv
#define	GL_NORMAL3V	glNormal3fv
#define	GL_COLOR3V	glColor3fv
#define	GL_COLOR4V	glColor4fv
#define	GL_TEXCOORD2V	glTexCoord2fv
#endif	/* !DOUBLEVEC */

/*	Outline font adjustment */
typedef enum
{
	fa_left_top=0,		fa_center_top=1,	fa_right_top=2,
	fa_left_center=3,	fa_center_center=4,	fa_right_center=5,
	fa_left_bottom=6,	fa_center_bottom=7,	fa_right_bottom=8,
	fa_custom=9
}	gl_font_adjustment_t;

/*	Outline font drawing parameters */
typedef struct	gl_string_parameters_s
{
	vec_t 		scale;
	vec_t		fov;
	vboolean	use_fov;
	gl_font_adjustment_t	adjustment;
	vec3_t		custom_adjustment;
}	gl_string_parameters_t, gl_string_parameters_p;

/*
 *	TL rendering API to pass to vglDecodeFeedback()
 */
typedef	struct	gl_tl_callbacks_s
{
	/*		To draw point */
	void	(V_CALL *point)(void *dev,vec3_t,color4b_t,vec2_t);
	/*		Should draw Gouraud - shaded line */
	void	(V_CALL *line)(void *dev,vec3_t,color4b_t,vec2_t,
									 vec3_t,color4b_t,vec2_t);
	/*		To draw Gouraud - shaded polygon */
	void	(V_CALL *begin_polygon)(void *dev,int);
	void	(V_CALL *polygon_vertex)(void *dev,vec3_t,color4b_t,vec2_t);
	/*		To respond to pass-through tokens */
	void	(V_CALL	*pass_through)(void *dev,vec_t);
}	gl_tl_callbacks_t, *gl_tl_callbacks_p;

typedef	float	*GLfloat_p;

#ifdef	__cplusplus
extern "C" {
#endif	/* __cplusplus */
	/*	INI / FINI ==================================================== */
	/*	Creates OpenGL-capable overlapped (but non-user-resizeable) window. */
	vhandle_t	V_GLOBAL	vglCreateWindow(char *title,
    	u32_t x,u32_t y,u32_t width,u32_t height);
	/*	Creates OpenGL-capable fullscreen window. */
	vhandle_t V_GLOBAL	vglCreateFullscreenWindow(char *title,
    	u32_t width,u32_t height,u32_t bpp,u32_t refresh);
	/*	Creates OpenGL-capable child window (without borders etc.) */
	vhandle_t V_GLOBAL	vglCreateChildWindow(char *title,
    	u32_t x,u32_t y,u32_t width,u32_t height,void *parent);
	/*	Creates bitmap-based OpenGL-capable window. */
	vhandle_t V_GLOBAL	vglCreateMappedWindow(u32_t width,u32_t height);
	/*	Destroys window. */
	void	V_GLOBAL		vglDestroyWindow(vhandle_t win);
	/*	Makes given window current for GL calls. */
	vboolean	V_GLOBAL	vglMakeCurrent(vhandle_t win);
	/*	Returns current window. */
	vhandle_t V_GLOBAL		vglGetCurrentWindow(void);
    /*	Returns true if given extension supported by renderer */
	vboolean	V_GLOBAL	vglHasExtension(char *extension_name);
    /*	Returns true (and copies entry point) if given extension
     *	available for current renderer; otherwise returns false */
    vboolean	V_GLOBAL 	vglQueryExtension(char *extension_name,
    	void **entry);
	/*	Swaps buffers of current window. */
	void		V_GLOBAL	vglSwapBuffers(void);
	/*	Copies contents of framebuffer / offscreen bitmap into malloc()'ed
	 *	buffer and returns pointer to it. */
	u8_p		V_GLOBAL	vglReadPixels(u32_t *width,u32_t *height);

	/*	Window management ============================================= */
	/*	Returns true if threre are pending events in queue of current window */
	vboolean	V_GLOBAL	vglPending(void);
	/*	Waits for input event in current window and returns it in 'event_return'. */
	vboolean	V_GLOBAL	vglNextEvent(input_record_t *event_return);
	/*	Moves input focus to current window. */
	vboolean	V_GLOBAL	vglSetFocus(void);
	/*	Hides current window */
	vboolean	V_GLOBAL	vglHideWindow(void);
	/*	Shows current window */
	vboolean	V_GLOBAL	vglShowWindow(void);
	/*	Resizes window. */
	vboolean	V_GLOBAL	vglResizeWindow(u32_t width,u32_t height);
	/*	Moves window. */
	vboolean	V_GLOBAL	vglMoveWindow(u32_t left,u32_t top);
	/*	Captures mouse, hides mouse cursor; while captured, LibV:
	 *		- automatically position cursor a 0:0 when moved;
	 *		- record only DIFFERENCE in position.
	 */
	void		V_GLOBAL	vglCapturePointer(vboolean capture);
	/*	Font management =============================================== */
	/*	Creates stroke (outlined) font.
	 *	Input:
	 *		face_name	- font face (may be NULL | BGI font name);
     *		load_as_koi8 - use koi8-r code table, not Win1251.
	 */
	vhandle_t	V_GLOBAL	vglLoadBGIFontEx(char *file_name,
    	vboolean load_as_koi8);
    /* Same as above, uses Win1251 code table */
	vhandle_t	V_GLOBAL	vglLoadBGIFont(char *file_name);
	/* Same as vglLoadBGIFontEx(), but reads font bytes from 'in' */
	vhandle_t	V_GLOBAL	vglStreamLoadBGIFontEx(vhandle_t in,
		vboolean load_as_koi8);
#ifdef	CONFIG_GL_PRECOMPILED_FONT
	/*
	 * Selects compiled-in simple stroke font.
	 * Before this call, OpenGL context must be initialized via
	 * vglCreateWindowXXX().
	 */
	void	V_GLOBAL	vglLoadDefaultFontEx(vboolean load_as_koi8);
    /* Same as above, uses Win1251 code table */
	void	V_GLOBAL	vglLoadDefaultFont();
#endif	/* CONFIG_GL_PRECOMPILED_FONT */
	/* Destroys font */
	void	V_GLOBAL	vglDestroyFont(vhandle_t handle);
    /* Changes font adjustment */
	void	V_GLOBAL	vglSetFontAdjustment(vhandle_t handle,
		gl_font_adjustment_t adjustment);
	void	V_GLOBAL	vglSetFontCustomAdjustment(vhandle_t handle,
		vec3_t custom_adjustment);
	void	V_GLOBAL	vglSetFontScale(vhandle_t handle,
		vec_t scale);
	void	V_GLOBAL	vglSetFontFOV(vhandle_t handle,vec_t fov);
	/* Selects font in current context */
	vboolean	V_GLOBAL	vglSelectFont(vhandle_t fnt);
	/* Returns current (selected) font, font's reference counter untouched */
	vhandle_t V_GLOBAL	vglGetCurrentFont(void);
	/* Prints string. */
	void	V_GLOBAL	vglPuts(char *str);
    /*	For koi8-r fonts only: prints cyrillic characters passed
     *	without 8th bit. */
	void    V_GLOBAL	vglPutsKoi8r(char *str);
	/*	No comments. */
	void	V_GLOBAL_VA	vglPrintf(const char *fmt,...);
	/*	Returns x-extent and height (from the baseline) of given text */
	void	V_GLOBAL	vglGetTextExtents(char *str,vec_t *width,vec_t *height);
	/*	Draws single line of text; adjusts visible font size, selects
	 *	appropriate line width.
	 *	Parameters:
	 *		origin 	- relative to this point text will be aligned;
	 *		cam		- camera to look from (see v_camctl.h for definition);
	 *		text	- text to draw.
	 */
	void	V_GLOBAL	vglDrawString(vec3_t origin,cam_t *cam,char *text);
    /*	Feedback management ===========================================
     *	Puts OpenGL in feedback mode and returns pointer to
     *	malloc()'ed feedback buffer.
     *	Input:
     *		num_elements	- number of GLfloats in feedback buffer.
     */
    void_p		V_GLOBAL	vglBeginFeedback(int num_elements);
    /*
     *	Takes OpenGL out of feedback mode. If previous mode 
     *	was feedback mode, stores number of recorded GLfloats in
     *	'stored_elements' and returns true.
     */
    vboolean	V_GLOBAL	vglEndFeedback(u32_t *stored_elements);
	/*
     *	Decodes OpenGL feedback buffer.
     *	Input:
     *		back_api	- list of drawing callbacks;
     *		dev			- device handle to pass to back_api's;
     *		buffer		- filled OpenGL feedback buffer;
     *		stored_elemens - number of GLfloat's in feedback buffer.
     *	Output:
     *		None.
     */
    vboolean	V_GLOBAL	vglDecodeFeedback(gl_tl_callbacks_t *back_api,
		void *dev,void_p buffer,int stored_elements);
    /*
     *	Creates metafile context, sets it's modelview and projection matrices
     *	idential to ones in current context, calls DrawProc(param) and closes
     *	metafile.
     *	Feedback buffer size automatically increased if needed.
     */
    vboolean	V_GLOBAL    vglDrawToMetafile(
    	char *file_name,	/* can be '//./clipboard' */
    	u32_t mmWidth,		/* logical size of image */
        u32_t mmHeight,
    	void (V_CALL *DrawProc)(void *param),void *param);
	/*
	 *	Utility to produce screenshots.
	 *	File format determined by extension (bmp | tga).
	 */
	vboolean	V_GLOBAL	vglSaveFramebuffer(char *file_name,
		u32_t mmWidth,u32_t mmHeight);
	/*	Returns handle for glBindTexture() / glDeleteTextures(). */
	GLuint	V_GLOBAL		vglLoadTexture(char *file_name,
		GLenum filter,GLenum clamp,GLenum env);
	/*	Loads six sky textures for vglDrawSky() */
	vboolean	V_GLOBAL	vglLoadSkyBoxTextures(GLuint dest[],char *path,
		char *sky_name,char *file_ext);
	/*	Draws QuakeII - style sky box */
	void		V_GLOBAL	vglDrawSkyBox(GLuint sky_textures[],
		vec_t sky_intensity,vec_t sky_opacity);
#ifdef 	__cplusplus
}
#endif	/* __cplusplus */

#endif	/* V_GL_H */
