#include "twn_game_api.h"
#include "state.h"

#include <complex.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>

#define GRAY ((Color){130, 130, 130, 255})
#define BLACK ((Color){0, 0, 0, 255})

#define LEFT_CLICK_ADD 20
#define RIGHT_CLICK_ADD 500


static void handle_input(void)
{
    State *state = ctx.udata;

    if (ctx.mouse_position.y <= 60)
        return;

    if (input_action_pressed("add_a_bit"))
    { // Left click
        for (int i = 0; i < LEFT_CLICK_ADD; i++)
        {
            if (state->bunniesCount < MAX_BUNNIES)
            {
                state->bunnies[state->bunniesCount].position = input_action_position("add_a_bit");
                state->bunnies[state->bunniesCount].speed.x = (float)(rand() % 500 - 250) / 60.0f;
                state->bunnies[state->bunniesCount].speed.y = (float)(rand() % 500 - 250) / 60.0f;
                state->bunnies[state->bunniesCount].color =
                    (Color){(uint8_t)(state->bunniesCount % 190 + 50),
                            (uint8_t)((state->bunniesCount + 120) % 160 + 80),
                            (uint8_t)((state->bunniesCount + 65) % 140 + 100), 255};
                state->bunniesCount++;
            }
        }
    }

    if (input_action_pressed("add_a_lot"))
    { // Right click
        for (int i = 0; i < RIGHT_CLICK_ADD; i++)
        {
            if (state->bunniesCount < MAX_BUNNIES)
            {
                state->bunnies[state->bunniesCount].position = input_action_position("add_a_lot");
                state->bunnies[state->bunniesCount].speed.x = (float)(rand() % 500 - 250) / 60.0f;
                state->bunnies[state->bunniesCount].speed.y = (float)(rand() % 500 - 250) / 60.0f;
                state->bunnies[state->bunniesCount].color =
                   (Color){(uint8_t)(state->bunniesCount % 190 + 50),
                            (uint8_t)((state->bunniesCount + 120) % 160 + 80),
                            (uint8_t)((state->bunniesCount + 65) % 140 + 100), 255};
                state->bunniesCount++;
            }
        }
    }
}

void game_tick(void)
{
    char bunny_count_text[64];

    // State *state = ctx.udata;
    if (ctx.initialization_needed)
    { // First tick, initalizing data
        // Allocating State struct to store data there
        if (!ctx.udata)
            ctx.udata = ccalloc(1, sizeof(State));
    }

    input_action("add_a_bit", CONTROL_LEFT_MOUSE);
    input_action("add_a_lot", CONTROL_RIGHT_MOUSE);

    State *state = ctx.udata;

    for (int i = 0; i < state->bunniesCount; i++)
    {
        state->bunnies[i].position.x += state->bunnies[i].speed.x;
        state->bunnies[i].position.y += state->bunnies[i].speed.y;

        if (((state->bunnies[i].position.x + (float)BUNNY_W / 2) > (float)ctx.resolution.x) ||
            ((state->bunnies[i].position.x + (float)BUNNY_W / 2) < 0))
            state->bunnies[i].speed.x *= -1;
        if (((state->bunnies[i].position.y + (float)BUNNY_H / 2) > (float)ctx.resolution.y) ||
            ((state->bunnies[i].position.y + (float)BUNNY_H / 2 - 60) < 0))
            state->bunnies[i].speed.y *= -1;
    }

    handle_input();

    // Clear window with Gray color (set the background color this way)
    draw_rectangle((Rect){0, 0, (float)ctx.resolution.x, (float)ctx.resolution.y}, GRAY);

    for (int i = 0; i < state->bunniesCount; i++)
    { // Draw each bunny based on their position and color, also scale accordingly
        m_sprite(m_set(texture, "wabbit_alpha.png"),
                 m_set(rect, ((Rect){.x = state->bunnies[i].position.x,
                                     .y = state->bunnies[i].position.y,
                                     .w = BUNNY_W * SPRITE_SCALE,
                                     .h = BUNNY_H * SPRITE_SCALE})),
                 m_opt(color, (state->bunnies[i].color)), m_opt(stretch, true), );
    }

    // Formatting text to display, might want to add FPS here too
    snprintf(bunny_count_text, 64, "Bunnies: %d", state->bunniesCount);
    draw_text(bunny_count_text, (Vec2){0, 0}, 40, BLACK, "/fonts/kenney-pixel.ttf");
}

void game_end(void)
{
    State *state = ctx.udata;

    // Free state when game ends
    free(state);
}