#include <string>
#include <imgui/imgui_impl_glfw.h>
#include <imgui/imgui_impl_opengl3.h>
#include "user_interface.h"

bool init_user_interface(User_Interface *user_interface, Render_Data *render_data) {
  IMGUI_CHECKVERSION();
  ImGui::CreateContext();
  ImGui_ImplGlfw_InitForOpenGL(render_data->glfw_window, true);
  const char* glsl_version = "#version 460 core";
  ImGui_ImplOpenGL3_Init(glsl_version);
  return true;
}

void create_user_interface_frame(User_Interface *user_interface, Render_Data *render_data) {
  ImGui_ImplOpenGL3_NewFrame();
  ImGui_ImplGlfw_NewFrame();
  ImGui::NewFrame();
  ImGuiWindowFlags imgui_window_flags = 0;
  ImGui::SetNextWindowBgAlpha(0.8f);
  ImGui::Begin("Control", nullptr, imgui_window_flags);
  static f32 new_fps = 0.0f;
  if (render_data->frame_time > 0.0) {
    new_fps = 1.0f / render_data->frame_time;
  }
  user_interface->frames_per_second = (user_interface->averaging_alpha * user_interface->frames_per_second) + (1.0f - user_interface->averaging_alpha) * new_fps;

  ImGui::Text("FPS:");
  ImGui::SameLine();
  ImGui::Text("%s", std::to_string(user_interface->frames_per_second).c_str());
  ImGui::Separator();

  ImGui::Text("UI generation time:");
  ImGui::SameLine();
  ImGui::Text("%s", std::to_string(render_data->user_interface_generate_time).c_str());
  ImGui::SameLine();
  ImGui::Text("ms");
  ImGui::Separator();

  ImGui::Text("Triangles:");
  ImGui::SameLine();
  ImGui::Text("%s", std::to_string(render_data->triangle_count).c_str());
  string window_dims = std::to_string(render_data->width) + "x" +
                       std::to_string(render_data->height);
  ImGui::Text("Window dimensions:");
  ImGui::SameLine();
  ImGui::Text("%s", window_dims.c_str());
  string img_window_position = std::to_string(static_cast<s32>(ImGui::GetWindowPos().x))+ "/" + std::to_string(static_cast<s32>(ImGui::GetWindowPos().y));
  ImGui::Text("ImGui Window Position:");
  ImGui::SameLine();
  ImGui::Text("%s", img_window_position.c_str());

  // Checkbox
  static bool checkbox_is_checked = false;
  ImGui::Checkbox("Check me", &checkbox_is_checked);

  if (checkbox_is_checked) {
    ImGui::SameLine();
    ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 255, 0, 255));
    ImGui::Text("Yes");
    ImGui::PopStyleColor();
  }

  // Alt shader toggler
  if (ImGui::Button("Toggle shader")) {
    render_data->use_alt_shader = !render_data->use_alt_shader;
  }

  ImGui::SameLine();
  if (!render_data->use_alt_shader) {
    ImGui::Text("Basic shader");
  } else {
    ImGui::Text("Alt shader");
  }

  // Field of view slider
  ImGui::Text("Field of view");
  ImGui::SameLine();
  ImGui::SliderInt("##FOV", &render_data->field_of_view, 40, 150);

  // Camera information
  ImGui::Text("View Azimuth:");
  ImGui::SameLine();
  ImGui::Text("%s", std::to_string(render_data->view_azimuth).c_str());
  ImGui::Text("View Elevation:");
  ImGui::Text("%s", std::to_string(render_data->view_elevation).c_str());
  ImGui::Separator();
  ImGui::Text("Camera Position:");
  ImGui::SameLine();
  ImGui::Text("%f, %f, %f", render_data->camera_world_position.x, render_data->camera_world_position.y, render_data->camera_world_position.z);

  ImGui::End();
}

void render_user_interface(User_Interface *user_interface) {
  ImGui::Render();
  ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

void cleanup_user_interface(User_Interface *user_interface) {
  ImGui_ImplOpenGL3_Shutdown();
  ImGui_ImplGlfw_Shutdown();
  ImGui::DestroyContext();
}
