#ifndef	GL_VGL_H
#define	GL_VGL_H

/*
 * UI event types.
 * Stored in ui_event_t -> type
 */
typedef enum
{
	ui_no_event,

	/* key & mouse buttons press or release events */
	ui_key_event,

	/* there is no special event for this type */
	ui_pointer_motion_event,

	/* generic type: configure_window_event_t */
	ui_window_focus_in_event,
	ui_window_focus_out_event,
	ui_window_expose_event,
	ui_window_map_event,
	ui_window_unmap_event,
	ui_window_move_event,
	ui_window_size_event,

	/* got message from window manager */
	ui_wm_event,

	ui_max_event
}	ui_event_type_t;

/*
 * Scancodes for "Windows" PC keyboard + 3-button mouse
 *
 * Stored in ui_key_event_t -> scan
 */
typedef enum
{
	sc_unknown,

	sc_escape,
	sc_f1,
	sc_f2,
	sc_f3,
	sc_f4,
	sc_f5,
	sc_f6,
	sc_f7,
	sc_f8,
	sc_f9,
	sc_f10,
	sc_f11,
	sc_f12,
	sc_print,
	sc_scroll_lock,
	sc_pause,

	sc_grave,
	sc_1,
	sc_2,
	sc_3,
	sc_4,
	sc_5,
	sc_6,
	sc_7,
	sc_8,
	sc_9,
	sc_0,
	sc_minus,
	sc_equal,
	sc_backslash,
	sc_backspace,

	sc_tab,
	sc_q,
	sc_w,
	sc_e,
	sc_r,
	sc_t,
	sc_y,
	sc_u,
	sc_i,
	sc_o,
	sc_p,
	sc_lbracket,
	sc_rbracket,
	sc_enter,

	sc_caps_lock,
	sc_a,
	sc_s,
	sc_d,
	sc_f,
	sc_g,
	sc_h,
	sc_j,
	sc_k,
	sc_l,
	sc_semicolon,
	sc_apostrophe,

	sc_lshift,
	sc_z,
	sc_x,
	sc_c,
	sc_v,
	sc_b,
	sc_n,
	sc_m,
	sc_comma,
	sc_period,
	sc_slash,
	sc_rshift,

	sc_lcontrol,
	sc_lsuper, /* Left WIN */
	sc_lalt,
	sc_space,
	sc_ralt,
	sc_rsuper, /* Right WIN */
	sc_menu,
	sc_rcontrol,

	sc_insert,
	sc_home,
	sc_prior,
	sc_delete,
	sc_end,
	sc_next,

	sc_up,
	sc_down,
	sc_left,
	sc_right,

	sc_num_lock,
	sc_kp_slash,
	sc_kp_multiply,
	sc_kp_subtract,
	sc_kp_home,
	sc_kp_up,
	sc_kp_prior,
	sc_kp_add,
	sc_kp_left,
	sc_kp_begin,
	sc_kp_right,
	sc_kp_end,
	sc_kp_down,
	sc_kp_next,
	sc_kp_enter,
	sc_kp_insert,
	sc_kp_delete,
	
	sc_lbutton,
	sc_mbutton,
	sc_rbutton,

	sc_wheelup,
	sc_wheeldown,

	sc_maxcode
} ui_scancode_t;

/*
 * Mouse buttons state masks.
 * Stored in ui_event_t -> button
 */
#define	UI_LBUTTON_MASK	(1<<0)
#define	UI_MBUTTON_MASK (1<<1)
#define	UI_RBUTTON_MASK (1<<2)

/*
 * Modifier key state masks.
 * Stored in ui_event_t->state
 */
#define	UI_NUM_LOCK_MASK	(1<<0)	/* X11: Mod2 */
#define	UI_CAPS_LOCK_MASK	(1<<1)
#define	UI_SCROLL_LOCK_MASK	(1<<2)	/* X11: Mod5 */
#define	UI_SHIFT_MASK		(1<<3)
#define	UI_CONTROL_MASK		(1<<4)
#define	UI_ALT_MASK			(1<<5)	/* X11: Mod1 */
#define	UI_SUPER_MASK		(1<<6)	/* X11: Mod4 */

/*
 * WM requests: only one is known at this time
 */
typedef enum
{
	ui_wm_unknown,

	ui_wm_close,

	ui_wm_max
}	ui_wm_event_t;

typedef struct ui_key_event_s
{
	vboolean press;	/* == true if key/button is pressed */
	unsigned scan;	/* scancode: cpecific for LibV, defined above */
	unsigned acode;	/* 8-bit character code for current locale */
	unsigned ucode;	/* machine-endian 16-bit unicode */
}	ui_key_event_t, *ui_key_event_p;

typedef struct ui_configure_event_s
{
	vboolean focused;	/* == true if window has input focus */
	vboolean visible;	/* == true if window is visible (mapped) */
	/* damaged rectangle for Expose event */
	unsigned exposed_left, exposed_top, exposed_right, exposed_bottom;
	int x, y;			/* position of window */
	unsigned width, height;	/* size of window */
	/* window manager request */
	unsigned wm_event;
}	ui_configure_event_t, *ui_configure_event_p;

typedef struct ui_event_s
{
	int		type;
	/*
	 * Win32: time in seconds since creation of window.
	 * X11: time since first key/button/motion event.
	 */
	vec_t	time;
	int		client_x, client_y; /* mouse pointer position */
	int		client_dx, client_dy; /* mouse pointer deltas */
	int		screen_x, screen_y; /* pointer position in screen coords */
	unsigned button; /* mouse buttons */
	unsigned state; /* keyboard modifiers */
	ui_key_event_t key;
	ui_configure_event_t configure;
}	ui_event_t, *ui_event_p;


#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
	vboolean vglInit(char *caption,int x, int y, int width, int height,
		vboolean fullscreen,vboolean can_resize,
		vboolean need_depth,vboolean need_stencil,vboolean need_dst_alpha);
	void V_GLOBAL	vglSwap(void);
	void V_GLOBAL	vglDestroy(void);
	/*
	 * vglGetVersionString()
	 *
	 * Can be used only after successful call to vglInit() (LibV GL context
	 * for current thread must be valid).
	 *
	 * Returns pointer to static string describing the version of current
	 * OpenGL connection in form "MAJOR.MINOR[.SUBVERSION]". Assures that
	 * all stuff necessary for the given version are really available
	 * (at least, in software emulation).
	 */
	VGLEXTAPI char * VGLEXTAPIENTRY vglGetVersionString (void);

	/*
	FIXME - STUBS -> arch/common/uicore.c
	 * Event management functions (all functions assume that
	 * current GL context for calling thread is valid.
	 */

	/*
	 * Conversion between scancodes and their names.
	 * The name formed by striping "sc_" prefix.
	 */
	char_p		V_GLOBAL	uiKeyscan2Name(unsigned scan);
	unsigned	V_GLOBAL	uiName2Keyscan(char *name);
	/*
	 * Returns number of events waiting in queue of active GL
	 * window. Polls the system queue, but _never_ blocks.
	 */
	vboolean V_GLOBAL	uiPending(void);
	/*
	 * Removes all messages from queues (both from system and
	 * window's), never blocks.
	 */
	void V_GLOBAL	uiFlushQueue(void);
	/*
	 * Returns pointer to n#th event from head of the queue.
	 * Neither polls system, nor blocks.
	 */
	ui_event_p	V_GLOBAL	uiPeekEvent(vsize_t offset_from_first_push);
	/* Same as above, but returns n#th event from tail of the queue. */
	ui_event_p	V_GLOBAL	uiPeekLastEvent(vsize_t offset_from_last_push);
	/*
	 * Removes the oldest event waiting in queue of active GL
	 * window. Polls the system queue and _may_ block.
	 */
	vboolean	V_GLOBAL	uiNextEvent(ui_event_p ev_return);
#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif	/* GL_VGL_H */
