#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/keyboard.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_image.h>

#include "../framework/base.h"
#include "../framework/buttons.h"

int width = 800, height = 600;
unsigned char key[ALLEGRO_KEY_MAX];

void ui_resize_model(Model*, Model*, Model*);

// Views
void view_page(Model*);
void view_tools(Model*, Button*, int);
void view_app_bar(Model*);

int main()
{
    // Initialization
    if (!al_init()) printf("Error : Couldn't initialize Allegro!\n");
    if (!al_init_primitives_addon()) printf("Error : Couldn't initialize primitives!\n");
    if (!al_init_image_addon()) printf("Error : Couldn't initialize Image Addon!\n");
    if (!al_init_font_addon()) printf("Error : Font Addon initializer failed!\n");
    if (!al_init_ttf_addon()) printf("Error : TTF Format Addon couldn't be initialized!\n");
    if (!al_install_keyboard()) printf("Error : Keyboard not found!\n");
    //if (!al_install_mouse()) printf("Error : Mouse not found!\n");

    materialize();
    lighten();
    darken();

    // Pre Window creation actions
    al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);
    ALLEGRO_MONITOR_INFO monitor;
    al_get_monitor_info(0, &monitor);

    ALLEGRO_TIMER* timer = al_create_timer(1.0 / 30.0);
    ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue();
    ALLEGRO_DISPLAY* disp = al_create_display(width, height);
    ALLEGRO_FONT* font = al_create_builtin_font();
    ALLEGRO_BITMAP* icon = al_load_bitmap("icon2.png");
    ALLEGRO_MOUSE_STATE mouse_state;

    // Registering event sources with an event
    al_register_event_source(queue, al_get_keyboard_event_source());
    //al_register_event_source(queue, al_get_mouse_event_source());
    al_register_event_source(queue, al_get_display_event_source(disp));
    al_register_event_source(queue, al_get_timer_event_source(timer));

    // Data Models here...
    bool redraw = true, resize = false, fullscreen_window = false;
    ALLEGRO_EVENT event;

    Model page = {PAGE, MATERIAL, 200, 100, 600, 500, 500, 400, 0, 1, VISIBLE};
    Model tools = {TOOLS, MATERIAL, 20, 120, 160, 460, 200, 500, 10, 1, VISIBLE};
    Model app_bar = {APP_BAR, MATERIAL, -1, -1, 800, 50, 800, 50, 0, 2, VISIBLE};
    page.C.primary_color = page.C.bg_color;
    page.C.bg_color = LIGHT.bg_color;

    printf("parent actual size : %d", sizeof(tools));

    int buttons_total = 9;
    Button buttons[buttons_total];
    init_buttons(&tools, buttons, 9, font);
    ALLEGRO_MOUSE_STATE state;


    // This sets the frames per second of the application
    al_start_timer(timer);
    al_set_window_title(disp, "PixelHack");
    al_set_app_name("PixelHack");
    al_set_display_icon(disp, icon);

    // Main event loop
    while (1)
    {
//        printf("Main loop entered!\n");
        al_wait_for_event(queue, &event);

        if(event.type == ALLEGRO_EVENT_TIMER)
            redraw = true;
        // close the display
        else if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE || event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
            break;
        // Resize the display
        else if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE)
        {
            resize = !resize;
            if (al_acknowledge_resize(disp)) {
                width = al_get_display_width(disp);
                height = al_get_display_height(disp);
            } else {
                width = 800;
                height = 600;
            }

            // resizing the Models
            ui_resize_model(&page, &tools, &app_bar);
        }
        // FULLSCREEN WINDOWED MODE
        else if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_F11)
        {
            fullscreen_window = !fullscreen_window;
            al_set_display_flag(disp, ALLEGRO_FULLSCREEN_WINDOW, fullscreen_window);
            if (fullscreen_window) {
                width = monitor.x2;
                height = monitor.y2;
            } else {
                width = 800;
                height = 600;
            }

            // resizing the Models
            ui_resize_model(&page, &tools, &app_bar);
        }
        else if (event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT)
            memset(key, 0, sizeof(key));
        // else if (event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN)
        // Mouse Click events
        else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
        {
            al_get_mouse_state(&state);
            for (int i=0; i<buttons_total; i++) {
                printf("button_down%d\n", i);
                controller_click_down(&buttons[i].M, &state);
            }
        }
        else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)
        {
            al_get_mouse_state(&state);
            printf("Mouse x = %d\n", event.mouse.x);
            for (int i=0; i<buttons_total; i++) {
                printf("button_up%d\n", i);
                controller_click_up(&buttons[i].M, &state);
            }
        }

        // Rendering happens here...
        if (redraw && al_is_event_queue_empty(queue))
        {
            al_clear_to_color(MATERIAL.bg_color);

            // Drawing the page layout of the application
            view_page(&page);
            view_tools(&tools, buttons, buttons_total);
            view_app_bar(&app_bar);


            al_flip_display();
            redraw = false;
        }
    }

    al_destroy_font(font);
    al_destroy_display(disp);
    al_destroy_timer(timer);
    al_destroy_event_queue(queue);
    al_destroy_bitmap(icon);
    al_destroy_font(font);
    return 0;
}


void ui_resize_model(Model* page, Model* tools, Model* app_bar)
{
    page->width = width-200;
    page->height = height-100;
    tools->height = height-140;
    app_bar->width = width;
}

void view_page(Model* page)
{
    // background
    al_draw_filled_rectangle(page->x, page->y, page->x + page->width, page->y + page->height, page->C.bg_color);
    // page body
    al_draw_filled_rectangle(page->x, page->y, page->x + page->offset_x, page->y + page->offset_y, page->C.primary_color);
    // border of page view area
    al_draw_rectangle(page->x, page->y, page->x + page->width, page->y + page->height, page->C.border_color, page->border);
}

void view_tools(Model* tools, Button* btn, int len)
{
    // border of tools area
    al_draw_rectangle(tools->x, tools->y, tools->x + tools->width, tools->y + tools->height, tools->C.border_color, tools->border);
    for (int i=0; i<len; i++)
    {
        view_button(&btn[i]);
    }
}

void view_app_bar(Model* app_bar)
{
    al_draw_filled_rounded_rectangle(app_bar->x, app_bar->y, app_bar->width, app_bar->height, 0, 5, app_bar->C.primary_color);
    al_draw_rectangle(app_bar->x, app_bar->y, app_bar->width, app_bar->height, app_bar->C.border_color, app_bar->border);
}
