#include "BadWM.h"
#include <stdlib.h>
#include <X11/Xatom.h>
#include <stdio.h>

void handle_key_event(XKeyEvent *e) {
	Client *c = find_client(e->window);
	KeySym key = XKeycodeToKeysym(dpy,e->keycode,0);

	if( c == NULL ) c = current;
	
	if (c) {
		switch (key) {
		case KEY_TOPLEFT:
			{ c->x = c->border; c->y = c->border; } if (0)
		case KEY_TOPRIGHT:
			{ c->x = DisplayWidth(dpy, c->screen->screen)-c->width-c->border; c->y = c->border; } if (0)
		case KEY_BOTTOMLEFT:
			{ c->x = c->border; c->y = DisplayHeight(dpy, c->screen->screen)-c->height-c->border; } if (0)
		case KEY_BOTTOMRIGHT:
			{ c->x = DisplayWidth(dpy, c->screen->screen)-c->width-c->border; c->y = DisplayHeight(dpy, c->screen->screen)-c->height-c->border; }
			move(c, 1);
			break;
		case KEY_KILL:
			send_wm_delete(c); break;
		case KEY_LOWER:
			XLowerWindow(dpy, c->parent);
			break;
		case KEY_MAX:
			maximise(c);
			resize(c, 1);
			break;
		case KEY_MAXVERT:
			maximise_vert(c);
			resize(c, 1);
			break;
		case KEY_MAXHORIZ:
			maximise_horiz(c);
			resize(c, 1);
			break;
		case KEY_FIX:
			c->vdesk = c->vdesk == STICKY ? vdesk : STICKY;
			client_update_current(c, current);
			break;
		}
	}
	switch(key) {
		case KEY_NEW:
			spawn(opt_term); break;
		case KEY_NEXT:
			next();
			break;
		case XK_1: case XK_2: case XK_3: case XK_4: case XK_5:
		case XK_6: case XK_7: case XK_8: case XK_9: case XK_0:
			switch_vdesk(KEY_TO_VDESK(key));
			break;
	}
}

void handle_button_event(XButtonEvent *e) {
	Client *c = find_client(e->window);

	if (c && e->window != c->screen->root) {
		switch (e->button) {
			case Button1:
				move(c, 0); break;
			case Button3:
				resize(c, 0); break;
		}
	}
}

void handle_configure_request(XConfigureRequestEvent *e) {
	Client *c = find_client(e->window);
	XWindowChanges wc;

	wc.sibling = e->above;
	wc.stack_mode = e->detail;
	if (c) {
		ungravitate(c);
		if (e->value_mask & CWWidth) c->width = e->width;
		if (e->value_mask & CWHeight) c->height = e->height;
		if (e->value_mask & CWX) c->x = e->x;
		if (e->value_mask & CWY) c->y = e->y;
		if (c->x == 0 && c->width >= DisplayWidth(dpy, c->screen->screen)) {
			c->x -= c->border;
		}
		if (c->y == 0 && c->height >= DisplayHeight(dpy, c->screen->screen)) {
			c->y -= c->border;
		}
		gravitate(c);

		wc.x = c->x - c->border;
		wc.y = c->y - c->border;
		wc.width = c->width + (c->border*2);
		wc.height = c->height + (c->border*2);
		wc.border_width = 0;
		XConfigureWindow(dpy, c->parent, e->value_mask, &wc);
	}

	wc.x = c ? c->border : e->x;
	wc.y = c ? c->border : e->y;
	wc.width = e->width;
	wc.height = e->height;
	XConfigureWindow(dpy, e->window, e->value_mask, &wc);
}

void handle_map_request(XMapRequestEvent *e) {
	Client *c = find_client(e->window);

	if (c) {
		if (c->vdesk != vdesk)
			switch_vdesk(c->vdesk);
		unhide(c, RAISE,0);
	} else {
		XWindowAttributes attr;
		XGetWindowAttributes(dpy, e->window, &attr);
		make_new_client(e->window, find_screen(attr.root));
	}
}

void handle_unmap_event(XUnmapEvent *e) {
	Client *c = find_client(e->window);

	if (c) {
		if (c->ignore_unmap) c->ignore_unmap--;
		else remove_client(c);
	}
}

void handle_property_change(XPropertyEvent *e) {
	Client *c = find_client(e->window);
	long dummy;

	if (c) {
		if (e->atom == XA_WM_NORMAL_HINTS)
				XGetWMNormalHints(dpy, c->window, c->size, &dummy);
	}
}

void handle_enter_event(XCrossingEvent *e) {
	Client *c;

	current_screen = find_screen(e->root);
	if ((c = find_client(e->window))) {
           focus_client(c);
           client_to_front(c);
	}
}
