// 15 june 2016
#include "test.h"

static uiAreaHandler borderAH;
static int borderAHInit = 0;
static double lastx = -1, lasty = -1;

struct trect {
	double left;
	double top;
	double right;
	double bottom;
	int in;
};

#define tsetrect(re, l, t, r, b) re.left = l; re.top = t; re.right = r; re.bottom = b; re.in = lastx >= re.left && lastx < re.right && lasty >= re.top && lasty < re.bottom

struct tareas {
	struct trect move;
	struct trect alsomove;
	struct trect leftresize;
	struct trect topresize;
	struct trect rightresize;
	struct trect bottomresize; 
	struct trect topleftresize;
	struct trect toprightresize;
	struct trect bottomleftresize;
	struct trect bottomrightresize;
	struct trect close;
};

static void filltareas(double awid, double aht, struct tareas *ta)
{
	tsetrect(ta->move, 20, 20, awid - 20, 20 + 30);
	tsetrect(ta->alsomove, 30, 200, 100, 270);
	tsetrect(ta->leftresize, 5, 20, 15, aht - 20);
	tsetrect(ta->topresize, 20, 5, awid - 20, 15);
	tsetrect(ta->rightresize, awid - 15, 20, awid - 5, aht - 20);
	tsetrect(ta->bottomresize, 20, aht - 15, awid - 20, aht - 5);
	tsetrect(ta->topleftresize, 5, 5, 15, 15);
	tsetrect(ta->toprightresize, awid - 15, 5, awid - 5, 15);
	tsetrect(ta->bottomleftresize, 5, aht - 15, 15, aht - 5);
	tsetrect(ta->bottomrightresize, awid - 15, aht - 15, awid - 5, aht - 5);
	tsetrect(ta->close, 130, 200, 200, 270);
}

static void drawtrect(uiDrawContext *c, struct trect tr, double r, double g, double bl)
{
	uiDrawPath *p;
	uiDrawBrush b;

	memset(&b, 0, sizeof (uiDrawBrush));
	b.Type = uiDrawBrushTypeSolid;
	b.R = r;
	b.G = g;
	b.B = bl;
	b.A = 1.0;
	if (tr.in) {
		b.R += b.R * 0.75;
		b.G += b.G * 0.75;
		b.B += b.B * 0.75;
	}
	p = uiDrawNewPath(uiDrawFillModeWinding);
	uiDrawPathAddRectangle(p,
		tr.left,
		tr.top,
		tr.right - tr.left,
		tr.bottom - tr.top);
	uiDrawPathEnd(p);
	uiDrawFill(c, p, &b);
	uiDrawFreePath(p);
}

static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
{
	struct tareas ta;

	filltareas(p->AreaWidth, p->AreaHeight, &ta);
	drawtrect(p->Context, ta.move, 0, 0.5, 0);
	drawtrect(p->Context, ta.alsomove, 0, 0.5, 0);
	drawtrect(p->Context, ta.leftresize, 0, 0, 0.5);
	drawtrect(p->Context, ta.topresize, 0, 0, 0.5);
	drawtrect(p->Context, ta.rightresize, 0, 0, 0.5);
	drawtrect(p->Context, ta.bottomresize, 0, 0, 0.5);
	drawtrect(p->Context, ta.topleftresize, 0, 0.5, 0.5);
	drawtrect(p->Context, ta.toprightresize, 0, 0.5, 0.5);
	drawtrect(p->Context, ta.bottomleftresize, 0, 0.5, 0.5);
	drawtrect(p->Context, ta.bottomrightresize, 0, 0.5, 0.5);
	drawtrect(p->Context, ta.close, 0.5, 0, 0);

	// TODO add current position prints here
}

static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e)
{
	struct tareas ta;

	lastx = e->X;
	lasty = e->Y;
	filltareas(e->AreaWidth, e->AreaHeight, &ta);
	// redraw our highlighted rect
	uiAreaQueueRedrawAll(area);
	if (e->Down != 1)
		return;
	if (ta.move.in || ta.alsomove.in) {
		uiAreaBeginUserWindowMove(area);
		return;
	}
#define resize(cond, edge) if (cond) { uiAreaBeginUserWindowResize(area, edge); return; }
	resize(ta.leftresize.in, uiWindowResizeEdgeLeft)
	resize(ta.topresize.in, uiWindowResizeEdgeTop)
	resize(ta.rightresize.in, uiWindowResizeEdgeRight)
	resize(ta.bottomresize.in, uiWindowResizeEdgeBottom)
	resize(ta.topleftresize.in, uiWindowResizeEdgeTopLeft)
	resize(ta.toprightresize.in, uiWindowResizeEdgeTopRight)
	resize(ta.bottomleftresize.in, uiWindowResizeEdgeBottomLeft)
	resize(ta.bottomrightresize.in, uiWindowResizeEdgeBottomRight)
	if (ta.close.in) {
		// TODO
		return;
	}
}

static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left)
{
}

static void handlerDragBroken(uiAreaHandler *ah, uiArea *a)
{
}

static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e)
{
	return 0;
}

static void borderWindowOpen(uiButton *b, void *data)
{
	uiWindow *w;
	uiArea *a;

	if (!borderAHInit) {
		borderAH.Draw = handlerDraw;
		borderAH.MouseEvent = handlerMouseEvent;
		borderAH.MouseCrossed = handlerMouseCrossed;
		borderAH.DragBroken = handlerDragBroken;
		borderAH.KeyEvent = handlerKeyEvent;
		borderAHInit = 1;
	}

	w = uiNewWindow("Border Resize Test", 300, 500, 0);
	uiWindowSetBorderless(w, 1);

	a = uiNewArea(&borderAH);
//	uiWindowSetChild(w, uiControl(a));
{uiBox *b;
b=uiNewHorizontalBox();
uiBoxAppend(b,uiControl(a),1);
uiWindowSetChild(w,uiControl(b));}
//TODO why is this hack needed? GTK+ issue

	uiControlShow(uiControl(w));
}

static uiSpinbox *width, *height;
static uiSpinbox *posX, *posY;
static uiCheckbox *fullscreen;

static void sizeWidth(uiSpinbox *s, void *data)
{
	uiWindow *w = uiWindow(data);
	int xp, yp;

	uiWindowContentSize(w, &xp, &yp);
	xp = uiSpinboxValue(width);
	uiWindowSetContentSize(w, xp, yp);
}

static void sizeHeight(uiSpinbox *s, void *data)
{
	uiWindow *w = uiWindow(data);
	int xp, yp;

	uiWindowContentSize(w, &xp, &yp);
	yp = uiSpinboxValue(height);
	uiWindowSetContentSize(w, xp, yp);
}

static void posXChanged(uiSpinbox *s, void *data)
{
	uiWindow *w = uiWindow(data);
	int x, y;

	uiWindowPosition(w, &x, &y);
	x = uiSpinboxValue(posX);
	uiWindowSetPosition(w, x, y);
}

static void posYChanged(uiSpinbox *s, void *data)
{
	uiWindow *w = uiWindow(data);
	int x, y;

	uiWindowPosition(w, &x, &y);
	y = uiSpinboxValue(posY);
	uiWindowSetPosition(w, x, y);
}

void onMoved(uiWindow *w, void *data)
{
	int x, y;

	puts("PositionChanged");
	uiWindowPosition(w, &x, &y);
	uiSpinboxSetValue(posX, x);
	uiSpinboxSetValue(posY, y);
}

static void updatesize(uiWindow *w)
{
	int xp, yp;

	uiWindowContentSize(w, &xp, &yp);
	uiSpinboxSetValue(width, xp);
	uiSpinboxSetValue(height, yp);
	// TODO on OS X this is updated AFTER sending the size change, not before
	uiCheckboxSetChecked(fullscreen, uiWindowFullscreen(w));
}

void onSize(uiWindow *w, void *data)
{
	puts("ContentSizeChanged");
	updatesize(w);
}

void setFullscreen(uiCheckbox *cb, void *data)
{
	uiWindow *w = uiWindow(data);

	uiWindowSetFullscreen(w, uiCheckboxChecked(fullscreen));
	updatesize(w);
}

static void borderless(uiCheckbox *c, void *data)
{
	uiWindow *w = uiWindow(data);

	uiWindowSetBorderless(w, uiCheckboxChecked(c));
}

uiBox *makePage15(uiWindow *w)
{
	uiBox *page15;
	uiBox *hbox;
	uiButton *button;
	uiCheckbox *checkbox;

	page15 = newVerticalBox();

	hbox = newHorizontalBox();
	uiBoxAppend(page15, uiControl(hbox), 0);

	uiBoxAppend(hbox, uiControl(uiNewLabel("Size")), 0);
	width = uiNewSpinbox(0, INT_MAX);
	uiBoxAppend(hbox, uiControl(width), 1);
	height = uiNewSpinbox(0, INT_MAX);
	uiBoxAppend(hbox, uiControl(height), 1);

	uiSpinboxOnChanged(width, sizeWidth, w);
	uiSpinboxOnChanged(height, sizeHeight, w);

	hbox = newHorizontalBox();
	uiBoxAppend(page15, uiControl(hbox), 0);

	uiBoxAppend(hbox, uiControl(uiNewLabel("Position")), 0);
	posX = uiNewSpinbox(INT_MIN, INT_MAX);
	uiBoxAppend(hbox, uiControl(posX), 1);
	posY = uiNewSpinbox(INT_MIN, INT_MAX);

	uiSpinboxOnChanged(posX, posXChanged, w);
	uiSpinboxOnChanged(posY, posYChanged, w);
	uiWindowOnPositionChanged(w, onMoved, NULL);
	onMoved(w, NULL);

	uiBoxAppend(hbox, uiControl(posY), 1);
	fullscreen = uiNewCheckbox("Fullscreen");
	uiBoxAppend(page15, uiControl(fullscreen), 0);

	uiCheckboxOnToggled(fullscreen, setFullscreen, w);
	uiWindowOnContentSizeChanged(w, onSize, NULL);
	updatesize(w);

	checkbox = uiNewCheckbox("Borderless");
	uiCheckboxOnToggled(checkbox, borderless, w);
	uiBoxAppend(page15, uiControl(checkbox), 0);

	button = uiNewButton("Borderless Resizes");
	uiButtonOnClicked(button, borderWindowOpen, NULL);
	uiBoxAppend(page15, uiControl(button), 0);

	hbox = newHorizontalBox();
	uiBoxAppend(page15, uiControl(hbox), 1);

	uiBoxAppend(hbox, uiControl(uiNewVerticalSeparator()), 0);

	return page15;
}
