#include <camera.h>
#include <camera_private.h>
#include <gfx.h>
#include <mouse.h>
#include <util.h>
#include <stdbool.h>

static void cursor_update(struct cursor *const c, const struct mouse *const m)
{
    if (c->screen.last_w != screen_w
        || c->screen.last_h != screen_h)
        cursor_init(c);

    c->x = m->x;
    c->y = m->y;

    if (mouse_pressed(m, MOUSE_BUTTON_LEFT)
        || mouse_pressed(m, MOUSE_BUTTON_RIGHT))
        c->state = CURSOR_STATE_PRESSED;
    else if (m->hovering)
        c->state = CURSOR_STATE_HOVERING;
    else
        c->state = CURSOR_STATE_IDLE;
}

static void update_speed(struct camera *const cam, const struct mouse *const m)
{
    enum
    {
        MAX_SPEED = 10,
        STEP = 1,
        T_STEP = 10,
        THRESHOLD_X = CAMERA_CURSOR_WIDTH,
        THRESHOLD_Y = CAMERA_CURSOR_HEIGHT
    };

    const struct cursor *const c = &cam->cursor;

    if (c->x >= screen_w - THRESHOLD_X)
    {
        if (++cam->xt >= T_STEP)
        {
            cam->xt = 0;

            if (cam->x_speed - STEP > -MAX_SPEED)
                cam->x_speed -= STEP;
        }
    }
    else if (c->x < THRESHOLD_X)
    {
        if (++cam->xt >= T_STEP)
        {
            cam->xt = 0;

            if (cam->x_speed + STEP < MAX_SPEED)
                cam->x_speed += STEP;
        }
    }
    else
        cam->x_speed = 0;

    if (c->y >= screen_h - THRESHOLD_Y)
    {
        if (++cam->yt >= T_STEP)
        {
            cam->yt = 0;

            if (cam->y_speed - STEP > -MAX_SPEED)
                cam->y_speed -= STEP;
        }
    }
    else if (c->y < THRESHOLD_Y)
    {
        if (++cam->yt >= T_STEP)
        {
            cam->yt = 0;

            if (cam->y_speed + STEP < MAX_SPEED)
                cam->y_speed += STEP;
        }
    }
    else
        cam->y_speed = 0;
}

void camera_update_mouse(struct camera *const cam, const struct mouse *const m)
{
    cursor_update(&cam->cursor, m);
    update_speed(cam, m);
    camera_update_pos(cam);
}
