#include "raylib.h"
#include <emscripten/emscripten.h>
#include <iostream>
#include <cmath>

// Global state
Model pengerModel;

Camera3D camera = { 0 };

Vector2 mouseDelta = { 0 };

float cameraSpeed = 0.8f;
float cameraPosition = 10.0f;
float cameraRadius = 0.0f;
Vector2 cameraAngle;

void CalculateFrame() {
    mouseDelta = GetMouseDelta();
    
    // Zoom on scroll
    float wheelMove = GetMouseWheelMove();
    cameraRadius -= wheelMove * 1.5f;
    if (cameraRadius < 2.0f)  cameraRadius = 2.0f;
    if (cameraRadius > 50.0f) cameraRadius = 50.0f;

    cameraAngle.x += mouseDelta.x;
    cameraAngle.y += mouseDelta.y;

    if (cameraAngle.y > 89.0f) cameraAngle.y = 90.0f;
    if (cameraAngle.y < -89.0f) cameraAngle.y = -90.0f;

    float mouseDeltaRadianX = (cameraAngle.x * (PI / 180.0f)) * cameraSpeed;
    float mouseDeltaRadianY = (cameraAngle.y * (PI / 180.0f)) * cameraSpeed;

    Vector3 newCameraPosition;
    newCameraPosition.x = cameraRadius * cosf(mouseDeltaRadianX) * cosf(mouseDeltaRadianY);
    newCameraPosition.z = cameraRadius * sinf(mouseDeltaRadianX) * cosf(mouseDeltaRadianY);
    newCameraPosition.y = cameraRadius *                           sinf(mouseDeltaRadianY);

    camera.position = newCameraPosition;
}

void DrawFrame() {
    BeginDrawing();
    ClearBackground(DARKGRAY);
        BeginMode3D(camera);
            DrawModel(pengerModel, (Vector3){ 0.0f, 0.0f, 0.0f }, 1.0f, WHITE);
            DrawGrid(10, 1.0f);
        EndMode3D();

        DrawFPS(10, GetScreenHeight() - GetScreenHeight() + 10);
    EndDrawing();
}

void UpdateDrawFrame() {
    CalculateFrame();
    DrawFrame();
}

int main() {
    // Enable High DPI for crisp rendering on Retina displays
    SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
    
    // Internal resolution
    InitWindow(2560, 1440, "Raylib WASM");
    SetTargetFPS(60);

    camera.position = (Vector3){ cameraPosition, cameraPosition, cameraPosition };
    camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
    camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
    camera.fovy = 45.0f;
    camera.projection = CAMERA_PERSPECTIVE;
    cameraRadius = cameraPosition * sqrt(3);

    pengerModel = LoadModel("assets/penger.obj");

    emscripten_set_main_loop(UpdateDrawFrame, 0, 1);

    // Note: This part is rarely reached in WASM
    UnloadModel(pengerModel);
    CloseWindow();

    return 0;
}