#include "raylib.h"
#include "raymath.h"

int main(int argc, char **argv) {
  const int screen_width = 800;
  const int screen_height = 450;

  InitWindow(screen_width, screen_height, "Parthanon 3D");

  Camera camera = {0}; // camera location places is about the center.
  camera.position = (Vector3){-9.0f, 9.0f, 4.0f};
  camera.target = (Vector3){9.0f, 9.0f, 0.0f};
  camera.up = (Vector3){0.0f, 1.0f, 0.0f};
  camera.fovy = 60.0f;
  camera.projection = CAMERA_PERSPECTIVE;

  Ray ray = {0};

  Model parth = LoadModel("parthanon.obj");
  Texture2D texture = LoadTexture("parthanon.png");
  parth.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;

  Vector3 parthPos = {0.0f, 0.0f, 0.0f};
  BoundingBox parthBB = GetMeshBoundingBox(parth.meshes[0]);

  DisableCursor();
  SetTargetFPS(60);

  while (!WindowShouldClose()) {

    UpdateCamera(&camera, CAMERA_FIRST_PERSON);

    RayCollision collision = {0};
    collision.distance = 10000000.0f; // arbitrary reasonable distance.
    collision.hit = false;

    // ray pointing down so we are always just above the floor.
    ray = (Ray){camera.position, (Vector3){0.0f, -1.0f, 0.0f}};

    RayCollision boxHitInfo = GetRayCollisionBox(ray, parthBB);
    if ((boxHitInfo.hit) && (boxHitInfo.distance < collision.distance)) {
      collision = boxHitInfo;

      RayCollision meshHitInfo = {0};
      for (int m = 0; m < parth.meshCount; m++) {
        meshHitInfo =
            GetRayCollisionMesh(ray, parth.meshes[m], parth.transform);
        if (meshHitInfo.hit) {
          if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) {
            collision = meshHitInfo;
          }
          break;
        }
      }

      if (meshHitInfo.hit) {
        collision = meshHitInfo;
      }
    }

    BeginDrawing();

    ClearBackground(RAYWHITE);

    BeginMode3D(camera);

    DrawModel(parth, parthPos, 1.0f, WHITE);

    if (collision.hit) {
      camera.position.y = collision.point.y + 0.4; // Camera position
      if (camera.position.y < 0.0f) {
        camera.position.y = 0.4f;
      }
    }

    DrawGrid(10, 10.0f);

    EndMode3D();

    DrawFPS(10, 10);

    EndDrawing();
  }

  UnloadModel(parth);
  UnloadTexture(texture);
  CloseWindow();
  return 0;
}
