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

#ifdef	ARCH_WINDOWING_SUPPORTED

IMPLEMENT_DEQUE_API(event,V_CALL,ui_event_t)

/*
 * ui_default_wnd_proc()
 * Returns 'false' if message must _not_ be stored in queue.
 */
vboolean V_CALL
ui_default_wnd_proc(arch_window_p aw,ui_event_p ev)
{
	int x, y, cx, cy, dx, dy;
	switch(ev->type)
	{
		case ui_pointer_motion_event:
			if(aw->zap_next_mousemove)
			{
				aw->zap_next_mousemove = false;
				return false;
			}
			x = ev->client_x;
			y = ev->client_y;
#ifdef	DISCARD_DUPLICATE_MOUSEMOVE
			if(aw->last_mx == x && aw->last_my == y)
				return false;
#endif	/* DISCARD_DUPLICATE_MOUSEMOVE */
			dx = x - aw->last_mx;
			dy = y - aw->last_my;
			if(aw->auto_warp_enabled)
            {
            	cx = aw->width >> 1;
            	cy = aw->height >> 1;
				aw->last_mx = cx;
				aw->last_my = cy;
				aw->last_vmx += dx;
				aw->last_vmy += dy;
				ev->client_x = aw->last_vmx;
				ev->client_y = aw->last_vmy;
				aw->zap_next_mousemove = true;
				archWinWarpPointer(aw, cx, cy);
				ev->client_dx = dx;
				ev->client_dy = dy;
            }
			else
			{
				ev->client_dx = x - aw->last_mx;
				ev->client_dy = y - aw->last_my;
				aw->last_vmx = aw->last_mx = x;
				aw->last_vmy = aw->last_my = y;
			}
			return true;
		default:
			break;
	}
	if(aw->auto_warp_enabled)
    {
		ev->client_x = aw->last_vmx;
		ev->client_y = aw->last_vmy;
	}
	ev->client_dx = 0;
	ev->client_dy = 0;
	return true;
}

void V_CALL
ui_win_loose_control(arch_window_p aw,vboolean hiding)
{
	if(hiding)
	{
		/* check if we need to uninstall grabs / restore vidmode */
		if(aw->ms_grab_count > 0)
		{
			aw->saved_ms_grab_count = aw->ms_grab_count;
			aw->ms_grab_count = 1;
			archWinGrabMouse(aw, false);
		}
		if(aw->kb_grab_count > 0)
		{
			aw->saved_kb_grab_count = aw->kb_grab_count;
			aw->kb_grab_count = 1;
			archWinGrabKeyboard(aw, false);
		}
		if(aw->current_vidmode != -1)
		{
			aw->saved_vidmode = aw->current_vidmode;
			archWinSetVidMode(aw, -1);
		}
		/*
		 * On exit:
		 *  ms_grab_count == kb_grab_count == 0;
		 *  current_vidmode == 0;
		 */
	}
	else
	{
		/* check if we need to reinstall grabs / set vidmode */
		if(aw->saved_ms_grab_count > 0)
		{
			aw->ms_grab_count = 0;
			archWinGrabMouse(aw, true);
			aw->ms_grab_count = aw->saved_ms_grab_count;
			aw->saved_ms_grab_count = 0;
		}
		if(aw->saved_kb_grab_count > 0)
		{
			aw->kb_grab_count = 0;
			archWinGrabKeyboard(aw, true);
			aw->kb_grab_count = aw->saved_kb_grab_count;
			aw->saved_kb_grab_count = 0;
		}
		if(aw->saved_vidmode != -1)
		{
			archWinSetVidMode(aw, aw->saved_vidmode);
			aw->saved_vidmode = -1;
		}
		/*
		 * On exit:
		 *  saved_ms_grab_count == saved_kb_grab_count == 0;
		 *  saved_vidmode == -1;
		 */
	}
}

void V_CALL
ui_make_default_key_event(ui_key_event_p ev)
{
	ev->press = false;
	ev->scan = sc_unknown;
	ev->acode = 0;
	ev->ucode = 0;
}

void V_CALL
ui_set_configure_from_aw(arch_window_p aw,ui_configure_event_p ev)
{
	ev->focused = aw->focused;
	ev->visible = aw->visible;
	if(aw->visible)
	{
		ev->x = aw->x;
		ev->y = aw->y;
		ev->width = aw->width;
		ev->height = aw->height;
	}
	else
	{
		ev->x = ev->y = 0;
		ev->width = ev->height = 0;
	}
	ev->exposed_left = ev->exposed_top = 0;
	ev->exposed_right = ev->exposed_bottom = 0;
	ev->wm_event = ui_wm_unknown;
}

vec_t	V_CALL
ui_make_message_time(unsigned *start,unsigned current)
{
	unsigned delta1, delta2;
	if(!*start)
		*start = current;
	if(*start <= current)
	{
		delta1 = current - *start;
		delta2 = 0;
	}
	else
	{
		/* overflow ! */
		unsigned last;
#ifdef	_ARCH_64_
		last = 0xFFFFFFFFFFFFFFFF;
#else
		last = 0xFFFFFFFF;
#endif
		delta1 = last - *start;
		delta2 = current;
		/* FIXME: this is wrong */
		*start = current;
	}
	return (vec_t)0.001 * ((vec_t)delta1 + (vec_t)delta2);
}

#endif	/* ARCH_WINDOWING_SUPPORTED */

