#include "infoScreen.h"
#include "game.h"

// Fuck this capitalist society. Long live Karl Marx!

const EntityUserInfo infoScreenEntityInfo[INFO_SCREEN_ENTITY_COUNT] = {
    (EntityUserInfo){
        .type = ENTITY_ANTIFA,
        .assetId = ANTIFA_SHIP_ASSET,
        .cameraDistance = 15.0,
        .msg = "The player ship. Its a anti fascist ship and is completely bad ass."
    },
    (EntityUserInfo){
        .type = ENTITY_SOLDATO,
        .assetId = SOLDATO_ASSET,
        .cameraDistance = 15.0,
        .msg = "A wippy little ship. It follows the other ships like ants."
    },
    (EntityUserInfo){
        .type = ENTITY_CAPORALE,
        .assetId = CAPORATE_ASSET,
        .cameraDistance = 15.0,
        .msg = "A pretty normal space ship. Often acts as a leader for the soldato."
    },
    (EntityUserInfo){
        .type = ENTITY_SERGENTE,
        .assetId = SERGENTE_ASSET,
        .cameraDistance = 15.0,
        .msg = "A funny little dude that packs a lot of power"
    },
    (EntityUserInfo){
        .type = ENTITY_MARESCIALLO,
        .assetId = MARESCIALLO_ASSET,
        .cameraDistance = 15.0,
        .msg = "A sneaky little ship based on a stealth jet."
    },
    (EntityUserInfo)
    {
        .type = ENTITY_GENERALE,
        .assetId = GENERALE_ASSET,
        .cameraDistance = 15.0,
        .msg = "A ufo that goes zig zag and shoots its epic deadly laser.",
    },
    (EntityUserInfo){
        .type = ENTITY_MUSSOLINI,
        .assetId = MUSSOLINI_ASSET,
        .cameraDistance = 100.0,
        .msg = "A deadly mother fucker named after the Italian fascist dictator"
    }
};

void initInfoScreen(Game * game) {
    InfoScreen * infoScreen = &game->infoScreen;

    infoScreen->goBackButton = (Rectangle){0.0, 25.0, 100.0, 50.0};

    infoScreen->camera = (Camera3D){
        .position = (Vector3){0.0, 0.0, infoScreenEntityInfo[0].cameraDistance},
        .target = Vector3Zero(),
        .up = (Vector3){0.0, 1.0, 0.0},
        .fovy = 90.0,
        .projection = CAMERA_PERSPECTIVE
    };

    infoScreen->currentEntity = 0;

    infoScreen->rotation = QuaternionIdentity();
    infoScreen->resetMouse = true;
    infoScreen->distance = infoScreenEntityInfo[0].cameraDistance;
}

void updateInfoScreenCamera(Game * game, InfoScreen * infoScreen) {
    double t = GetFrameTime();
    Camera3D * camera = &infoScreen->camera;

    if (infoScreen->resetMouse) {
        infoScreen->resetMouse = false;
        SetMousePosition(0, 0);
        infoScreen->lastMouse = Vector2Zero();
    }

    // Get mouse.
    Vector2 mousePosition = GetMousePosition();
    Vector2 mouseSpeed = Vector2Subtract(mousePosition, infoScreen->lastMouse);
    mouseSpeed = Vector2Scale(mouseSpeed, 1.0 / t);
    mouseSpeed = Vector2Scale(mouseSpeed, game->settings.previewMouseSensitivity);
    infoScreen->lastMouse = mousePosition;

    // Get mouse axis angle.
    AxisAngle angle = AxisAngleIdentity();
    angle.axis = (Vector3){mouseSpeed.y, mouseSpeed.x, 0.0};
    angle.angle = Vector3Length(angle.axis);

    if (IsMouseButtonDown(MOUSE_MIDDLE_BUTTON)) {
        angle.axis.z = mouseSpeed.x;
        angle.axis.y = 0.0;
    }

    // Apply rotation.
    Quaternion rotationSpeed = QuaternionFromAxisAngle(angle.axis, angle.angle * t);
    infoScreen->rotation = QuaternionMultiply(infoScreen->rotation, rotationSpeed);
    infoScreen->rotation = QuaternionNormalize(infoScreen->rotation);

    camera->position = (Vector3){0.0, 0.0, infoScreenEntityInfo[infoScreen->currentEntity].cameraDistance};
}

void updateInfoScreen(Game * game) {
    InfoScreen * infoScreen = &game->infoScreen;
    ClearBackground(BLACK);

    // Reset.
    if (IsKeyPressed(KEY_R)) {
        infoScreen->resetMouse = true;
        infoScreen->rotation = QuaternionIdentity();
    }

    // Handling hidding cursor and shit.
    if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) {
        DisableCursor();
    } else if (IsMouseButtonReleased(MOUSE_RIGHT_BUTTON)) {
        infoScreen->resetMouse = true;
        EnableCursor();
    }

    // Switching modes.
    if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) {
        updateInfoScreenCamera(game, infoScreen);
    } else {
         // Back button.
        if (GuiButton(infoScreen->goBackButton, "Back"))
            game->screenId = SCREEN_MAIN_MENU;
    }

    EntityUserInfo info = infoScreenEntityInfo[infoScreen->currentEntity];

    // Draw shit.
    BeginMode3D(infoScreen->camera);

    game->assets.models[info.assetId].transform = QuaternionToMatrix(infoScreen->rotation);
    DrawModelWires(game->assets.models[info.assetId], Vector3Zero(), 1.0, GREEN);

    //DrawGrid(32, 5.0);

    EndMode3D();
}

void resizeInfoScreen(Game * game, InfoScreen * infoScreen) {
}