#include "../hid_lesstif/render.h"

static mbtk_timer_id_t idle_tid;
static int do_idle_proc = 0;
static struct {
	unsigned pending:1;
	rnd_coord_t x, y;
} ch_move_to;

#define MBTKX_IDLE_PROC_PERIOD 0.066

/* save rnd_render and restore at the end: we may get an async expose draw
   while it is set to an exporter */
#define SAVE_HID() \
do { \
	hid_save = rnd_render; \
	rnd_render = &mbtkx_hid; \
} while(0)

#define RESTORE_HID() \
 rnd_render = hid_save

static mbtk_timer_res_t mbtx_idle_proc_cb(long repleft, void *user_data)
{
	rnd_mbtk_t *mctx = user_data;

	if (do_idle_proc) {
		rnd_hid_t *hid_save;

		if (ch_move_to.pending) {
			mctx->in_move_event++;
			xrnd_crosshair_move_to(ch_move_to.x, ch_move_to.y);
			mctx->in_move_event--;
			ch_move_to.pending = 0;
		}


		rnd_trace("do idle proc!\n");
		SAVE_HID();
		if (xrnd.need_redraw) {
			xrnd_redraw_main(&mbtkx_hid);
			TODO("port this:");
/*			xrnd_preview_invalidate(NULL);*/
	
			xrnd_show_crosshair(1);
		}

		RESTORE_HID();
		do_idle_proc = 0;
	}

	return MBTK_TIMER_CONTINUE;
}

void mbtkx_need_idle_proc(void)
{
		rnd_trace("schedule idle proc!\n");
	do_idle_proc = 1;
}


static void mbtkx_set_hidlib(rnd_hid_t *hid, rnd_design_t *hidlib)
{
	xrnd.dsg = hidlib;
	rnd_mbtk_set_hidlib(hid, hidlib); /* chain call */
}

static void mbtkx_invalidate_lr(rnd_hid_t *hid, rnd_coord_t l, rnd_coord_t r, rnd_coord_t t, rnd_coord_t b)
{
	if (!xrnd.window)
		return;

	xrnd.need_redraw = 1;
	mbtkx_need_idle_proc();
}

void mbtkx_invalidate_all(rnd_hid_t *hid)
{
	if (xrnd.dsg != NULL)
		mbtkx_invalidate_lr(hid, xrnd.dsg->dwg.X1, xrnd.dsg->dwg.X2, xrnd.dsg->dwg.Y1, xrnd.dsg->dwg.Y2);
}

static void mbtkx_set_main_scroll(int horiz, int pos, int view, int min, int max, unsigned int slider_size)
{
	rnd_trace("set main scroll %c!\n", horiz ? 'h' : 'v');
}

static int mbtkx_main_drawing_area_first_draw_cb(mbtk_canvas_native_t *c, void *native_ctx, long x_offs, long y_offs, long w, long h)
{
	rnd_mbtk_t *mctx = c->w.user_data;
	mbtk_xlib_native_t *nat = native_ctx;

	xrnd_init(nat->display, nat->screen, &mbtkx_hid, mbtkx_set_main_scroll, mbtkx_need_idle_proc);
	xrnd_work_area_first_expose(nat->window, w, h, 0);
	mbtkx_invalidate_all(&mbtkx_hid);

	mbtk_timer_new(&mctx->disp, MBTK_TIMER_REPEAT_FOREVER, MBTKX_IDLE_PROC_PERIOD, mbtx_idle_proc_cb, mctx);

	return 0;
}

static int mbtkx_main_drawing_area_draw_cb(mbtk_canvas_native_t *c, void *native_ctx, long x_offs, long y_offs, long w, long h)
{
/*	rnd_mbtk_t *mctx = c->w.user_data;*/

	xrnd_work_area_expose(x_offs, y_offs, w, h);
	return 0;
}

void mbtkx_crosshair_set_cb(rnd_mbtk_t *mctx, rnd_coord_t x, rnd_coord_t y, rnd_set_crosshair_t action)
{
	xrnd_set_crosshair(x, y,  action, !mctx->in_move_event, &mctx->in_move_event);
}

void mbtkx_crosshair_move_to_cb(rnd_mbtk_t *mctx, rnd_coord_t x, rnd_coord_t y)
{
	/* draw this only during the next scheduled idle proc */
	ch_move_to.pending = 1;
	ch_move_to.x = x;
	ch_move_to.y = y;
	mbtkx_invalidate_all(&mbtkx_hid);
}

static void screen_coords_to_design_cb(int scx, int scy, rnd_coord_t *xout, rnd_coord_t *yout)
{
	*xout = xrnd_px(scx);
	*yout = xrnd_py(scy);
}


static void mbtkx_glue_render_init(void)
{
	mbtkx_hid.set_design = mbtkx_set_hidlib;

	mbtkx_hid.invalidate_lr = mbtkx_invalidate_lr;
	mbtkx_hid.invalidate_all = mbtkx_invalidate_all;

	mbtkx_hid.notify_crosshair_change = xrnd_notify_crosshair_change;
	mbtkx_hid.notify_mark_change = xrnd_notify_mark_change;
	mbtkx_hid.make_gc = xrnd_make_gc;
	mbtkx_hid.destroy_gc = xrnd_destroy_gc;
	mbtkx_hid.set_drawing_mode = xrnd_set_drawing_mode;
	mbtkx_hid.render_burst = xrnd_render_burst;
	mbtkx_hid.set_color = xrnd_set_color;
	mbtkx_hid.set_line_cap = xrnd_set_line_cap;
	mbtkx_hid.set_line_width = xrnd_set_line_width;
	mbtkx_hid.set_draw_xor = xrnd_set_draw_xor;
	mbtkx_hid.draw_line = xrnd_draw_line;
	mbtkx_hid.draw_arc = xrnd_draw_arc;
	mbtkx_hid.draw_rect = xrnd_draw_rect;
	mbtkx_hid.fill_circle = xrnd_fill_circle;
	mbtkx_hid.fill_polygon = xrnd_fill_polygon;
	mbtkx_hid.fill_polygon_offs = xrnd_fill_polygon_offs;
	mbtkx_hid.fill_rect = xrnd_fill_rect;

	mbtkx_hid.zoom_win = xrnd_zoom_win;
	mbtkx_hid.zoom = xrnd_zoom;
	mbtkx_hid.pan = xrnd_pan;
	mbtkx_hid.pan_mode = xrnd_pan_mode;
	mbtkx_hid.view_get = xrnd_view_get;

	mbtkx_hid.draw_pixmap = xrnd_draw_pixmap;
	mbtkx_hid.uninit_pixmap = xrnd_uninit_pixmap;

	/* set up glue from lib_mbtk_common to HID-specific code */
	mbtkx_global.main_drawing_area_first_draw_cb = mbtkx_main_drawing_area_first_draw_cb;
	mbtkx_global.main_drawing_area_draw_cb = mbtkx_main_drawing_area_draw_cb;
	mbtkx_global.crosshair_set = mbtkx_crosshair_set_cb;
	mbtkx_global.crosshair_move_to = mbtkx_crosshair_move_to_cb;
	mbtkx_global.screen_coords_to_design = screen_coords_to_design_cb;
}
