#include "include/window_draw.h"
#include "include/window_manager.h"
#include "include/unicode.h"
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <assert.h>

#define NAME_PX

void unframe(Window w) {
    linked_window * linkframe = find_client(w);
    if (linkframe == NULL) { // either frame called, or a window with no frame, eq dropdown
        return;
    }
    Window frame = linkframe->frame;
    XUnmapWindow(X_display, frame);
    XReparentWindow(X_display, w, root_window, 0,0);
    XDestroyWindow(X_display, frame);
    remove_client(w);
}

void draw_window_core(Window w);

void reframe_decorate(Window w) {
    XWindowAttributes attrs;
    XGetWindowAttributes(X_display, w, &attrs);
    Window frame = XCreateSimpleWindow(X_display, root_window, attrs.x, attrs.y, attrs.width+18, attrs.height+4, 2, 0x444444, 0x333333);
    XSelectInput(X_display, frame, SubstructureNotifyMask | SubstructureRedirectMask);

    XGrabButton(X_display, AnyButton, AnyModifier, frame, 0, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeSync, GrabModeAsync, None, None);\

    XReparentWindow(X_display, w, frame, 0, 2);
    XMapWindow(X_display, frame);
    GRAB_SHORTCUTS(X_display, frame);
    add_client(w, frame);
    draw_window_core(w);
}


static inline int char_len(int utf_char) {
    for (int i = 3; i >=0; i--) {
        if (*((char*)&utf_char+i) != 0) return i+1;
    }
    return 4;
}

char close_icon[] = {0x00, 0x00, 0xfe, 0x07, 0xfa, 0x05, 0xf6, 0x06, 0x6e, 0x07, 0x9e, 0x07,
   0x9e, 0x07, 0x6e, 0x07, 0xf6, 0x06, 0xfa, 0x05, 0xfe, 0x07, 0x00, 0x00};

char resize_icon[] = {
    0xff, 0x07, 0xff, 0x0b, 0xff, 0x05, 0xff, 0x0a, 0x7f, 0x05, 0xbf, 0x0a,
   0x5f, 0x05, 0xaf, 0x0a, 0x57, 0x05, 0xab, 0x0a, 0x55, 0x05, 0xaa, 0x0a
};

char minimize_icon[] = {
    0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xfd, 0x0b, 0xfb, 0x0d, 0xf7, 0x0e,
   0x6d, 0x0b, 0x9b, 0x0d, 0xf7, 0x0e, 0x6f, 0x0f, 0x9f, 0x0f, 0xff, 0x0f
};

Pixmap close, resize, minimize;

void draw_frame_decorations(Window frame, int width, int height, GC context) {
    XCopyArea(X_display, resize, frame, context, 0, 0, _ICON_SIZE, _ICON_SIZE, width-_RESIZE_X, height-_RESIZE_Y);
    XCopyArea(X_display, close, frame, context, 0, 0, _ICON_SIZE, _ICON_SIZE, width-_CLOSE_X, height-_CLOSE_Y);
    XCopyArea(X_display, minimize, frame, context, 0, 0, _ICON_SIZE, _ICON_SIZE, width-_MINIMIZE_X, height-_MINIMIZE_Y);
}

void draw_window_core(Window w) {
    linked_window * client = get_window_definite(w);
    if (client == NULL) return;
    XWindowAttributes attrs;
    XGetWindowAttributes(X_display, client->client, &attrs);

    XClearWindow(X_display, client->frame);

    GC context = DefaultGC(X_display, DefaultScreen(X_display));
    XSetBackground(X_display, context, 0x333333);
    XSetForeground(X_display, context, 0x888888);

    char * buf;
    #define NAMEERR (const char*)"Welp ICCC doesnt mean anything"

    XTextProperty name;
    if (XGetWMName(X_display, client->client, &name) == 0) {
        buf = malloc((1+strlen(NAMEERR))*sizeof(char));
        strcpy(buf, NAMEERR);
    } else {
        char ** property_string;
        int count;

        buf = malloc (sizeof(char)*name.nitems);
        memset(buf, 0, name.nitems);
        strncpy(buf, (char*)name.value, name.nitems);
        free(name.value);
    }

    XFontSet fontset;

    struct utf8_string title = parse_string(buf);
    for (int i = 0; i<title.count; i++) {
        Xutf8DrawString(X_display, client->frame, wm_default_fontset, context, attrs.width+5, 15+(18*i), title.chars[i].chars, title.chars[i].count);
    }
    free(title.chars);
    GRAB_SHORTCUTS(X_display, client->frame);
    draw_frame_decorations(client->frame, attrs.width+18, attrs.height+4, context);

    XMapWindow(X_display, client->frame);
    XMapWindow(X_display, client->client);
    free(buf);
}

void draw_window(XExposeEvent* event) {
    linked_window * curr = windows;
    while (curr->next != NULL) {
        curr = curr->next;
        draw_window_core(curr->client);
    }
}