#include <../arch/arch.h>

#ifdef	ARCH_WINDOWING_SUPPORTED

void V_GLOBAL
uiAutoRepeat(vboolean enable)
{
	CALLER_NAME(uiAutoRepeat)
	gl_context_p ctx;
	IF_NO_GLCONTEXT(ctx)
		return;
	ctx->wnd->auto_repeat_disabled = !enable;
}

void V_GLOBAL
uiAutoWarp(vboolean enable)
{
	CALLER_NAME(uiAutoWarp)
	gl_context_p ctx;
	arch_window_p aw;
	IF_NO_GLCONTEXT(ctx)
		return;
	aw = ctx->wnd;
	if(enable)
	{
		int cx, cy;
		if(aw->auto_warp_enabled)
			return;
		aw->auto_warp_enabled = true;
		aw->auto_warp_saved_x = aw->last_mx;
		aw->auto_warp_saved_y = aw->last_my;
		cx = aw->width >> 1;
		cy = aw->height >> 1;
		aw->last_vmx = 0;
		aw->last_vmy = 0;
		aw->last_mx = cx;
		aw->last_my = cy;
		archWinShowPointer(aw, false);
		if(archWinWarpPointer(aw, cx, cy))
		{
			archWinGrabMouse(aw, true);
			return;
		}
		aw->auto_warp_enabled = false;
		aw->last_mx = aw->last_vmx = aw->auto_warp_saved_x;
		aw->last_my = aw->last_vmy = aw->auto_warp_saved_y;
		archWinShowPointer(aw, true);
	}
	if(!aw->auto_warp_enabled)
		return;
	aw->auto_warp_enabled = false;
	aw->last_mx = aw->last_vmx = aw->auto_warp_saved_x;
	aw->last_my = aw->last_vmy = aw->auto_warp_saved_y;
	archWinGrabMouse(aw, false);
	archWinWarpPointer(aw, aw->auto_warp_saved_x, aw->auto_warp_saved_y);
	archWinShowPointer(aw, true);
}

vboolean V_GLOBAL
uiPending()
{
	CALLER_NAME(uiPending)
	gl_context_p ctx;
	IF_NO_GLCONTEXT(ctx)
		return false;
	archWinPoll(ctx->wnd,false);
	return ctx->wnd->msg_que ? true : false;
}

ui_event_p V_GLOBAL
uiPeekEvent(vsize_t offset_from_first_push)
{
	CALLER_NAME(uiPeekEvent)
	ui_event_p ptr;
	gl_context_p ctx;
	IF_NO_GLCONTEXT(ctx)
		return NULL;
	if(!eventDeqPeekBack(ctx->wnd->msg_que,offset_from_first_push,&ptr))
		return NULL;
	return ptr;
}

ui_event_p V_GLOBAL
uiPeekLastEvent(vsize_t offset_from_last_push)
{
	CALLER_NAME(uiPeekLastEvent)
	ui_event_p ptr;
	gl_context_p ctx;
	IF_NO_GLCONTEXT(ctx)
		return NULL;
	if(!eventDeqPeek(ctx->wnd->msg_que,offset_from_last_push,&ptr))
		return NULL;
	return ptr;
}

vboolean V_GLOBAL
uiRemoveEvent(vsize_t offset_from_first_push,ui_event_p ev_return)
{
	CALLER_NAME(uiRemoveEvent)
	ui_event_p ptr;
	gl_context_p ctx;
	IF_NO_GLCONTEXT(ctx)
		return false;
	if(!eventDeqPeekBack(ctx->wnd->msg_que,offset_from_first_push,&ptr))
		return false;
	if(ev_return)
		memCopy(ev_return,ptr,sizeof(ui_event_t));
	ctx->wnd->msg_que = eventDeqRemoveBack(ctx->wnd->msg_que,
		offset_from_first_push);
	return true;
}

vboolean V_GLOBAL
uiRemoveLastEvent(vsize_t offset_from_last_push,ui_event_p ev_return)
{
	CALLER_NAME(uiRemoveLastEvent)
	ui_event_p ptr;
	gl_context_p ctx;
	IF_NO_GLCONTEXT(ctx)
		return false;
	if(!eventDeqPeek(ctx->wnd->msg_que,offset_from_last_push,&ptr))
		return false;
	if(ev_return)
		memCopy(ev_return,ptr,sizeof(ui_event_t));
	ctx->wnd->msg_que =
		eventDeqRemove(ctx->wnd->msg_que,offset_from_last_push);
	return true;
}

vboolean V_GLOBAL
uiNextEvent(ui_event_p ev_return)
{
	CALLER_NAME(uiNextEvent)
	gl_context_p ctx;
	IF_NO_GLCONTEXT(ctx)
		return false;
	archWinPoll(ctx->wnd,true);
	ctx->wnd->msg_que = eventDeqPopBack(ctx->wnd->msg_que,ev_return);
	return true;
}

/* TODO */

#if 0

	vboolean	V_CALL	archWinSetVidMode(arch_window_p aw,int mode_num);
	/* window configuration */
	vboolean	V_CALL	archWinShow(arch_window_p aw,vboolean show);
	void		V_CALL	archWinFocus(arch_window_p aw);
	vboolean	V_CALL	archWinMove(arch_window_p aw,s32_t x,s32_t y);
	vboolean	V_CALL	archWinSize(arch_window_p aw,s32_t width,s32_t height);
	/*
	 * Mouse pointer helper functions
	 */
	vboolean	V_CALL	archWinWarpPointer(arch_window_p aw,s32_t x,s32_t y);
	/* Returns 'true' if cursor is visible at exit. */
	vboolean	V_CALL	archWinShowPointer(arch_window_p aw,vboolean show);
	void		V_CALL	archWinGrabMouse(arch_window_p aw,vboolean grab);
	void		V_CALL	archWinGrabKeyboard(arch_window_p aw,vboolean grab);

#endif

#endif	/* ARCH_WINDOWING_SUPPORTED */
