#include "settings_menu.hpp"

#include <glm/gtc/type_ptr.hpp>
#include <imgui.h>

#include "../util/imgui/style.hpp"
#include "../util/imgui/widget.hpp"
#include "../util/display.hpp"
#include "../util/math.hpp"
#include "../util/measurement.hpp"

using namespace game::util;
using namespace game::util::imgui;
using namespace game::resource::xml;

namespace game::state
{
  void SettingsMenu::update(Resources& resources, Mode mode, const Strings* strings)
  {
    auto* settings = resources.settings.root();
    if (!settings)
    {
      resources.settings.settings_default();
      settings = resources.settings.root();
    }
    auto measurementSystem = settings->measurementSystem == "Imperial" ? measurement::IMPERIAL : measurement::METRIC;
    auto& volume = settings->volume;
    auto& isAudioMuted = settings->isAudioMuted;
    auto& color = settings->color;
    auto string_get = [&](Strings::Type type, const char* fallback) -> const char*
    {
      return strings ? strings->get(type).c_str() : fallback;
    };

    isJustColorSet = false;

    ImGui::SeparatorText(string_get(Strings::SettingsMeasurementSystem, "Measurement System"));
    WIDGET_FX(ImGui::RadioButton(string_get(Strings::SettingsMetric, "Metric"),
                                 (int*)&measurementSystem, measurement::METRIC));
    ImGui::SetItemTooltip("%s", string_get(Strings::SettingsMetricTooltip, "Use kilograms (kg)."));
    ImGui::SameLine();
    WIDGET_FX(ImGui::RadioButton(string_get(Strings::SettingsImperial, "Imperial"),
                                 (int*)&measurementSystem, measurement::IMPERIAL));
    ImGui::SetItemTooltip("%s", string_get(Strings::SettingsImperialTooltip, "Use pounds (lbs)."));
    settings->measurementSystem = measurementSystem == measurement::IMPERIAL ? "Imperial" : "Metric";

    ImGui::SeparatorText(string_get(Strings::SettingsWindow, "Window"));
    const char* windowModes[] = {
        string_get(Strings::SettingsWindowed, "Windowed"),
        string_get(Strings::SettingsFullscreen, "Fullscreen"),
    };
    auto windowMode = display::fullscreen_get() ? 1 : 0;
    if (WIDGET_FX(ImGui::Combo(string_get(Strings::SettingsWindowMode, "Mode"), &windowMode, windowModes, 2)))
      display::fullscreen_set(windowMode == 1);
    ImGui::SetItemTooltip("%s", string_get(Strings::SettingsWindowModeTooltip,
                                           "Switch between windowed and fullscreen display.\n(Shortcut: F)"));

    ImGui::SeparatorText(string_get(Strings::SettingsSound, "Sound"));
    ImGui::BeginDisabled(isAudioMuted);
    if (WIDGET_FX(
            ImGui::SliderInt(string_get(Strings::SettingsVolume, "Volume"), &volume, 0, 100, "%d%%")))
      resources.volume_set(math::to_unit((float)volume));
    ImGui::SetItemTooltip("%s", string_get(Strings::SettingsVolumeTooltip, "Adjust master volume."));
    ImGui::EndDisabled();
    ImGui::SameLine();
    if (WIDGET_FX(ImGui::Checkbox(string_get(Strings::SettingsMute, "Mute"), &isAudioMuted)))
      resources.audio_mute_set(isAudioMuted);
    ImGui::SetItemTooltip("%s", string_get(Strings::SettingsMuteTooltip, "Mute all audio.\n(Shortcut: M)"));

    ImGui::SeparatorText(string_get(Strings::SettingsAppearance, "Appearance"));

    if (WIDGET_FX(ImGui::Checkbox(string_get(Strings::SettingsUseCharacterColor,
                                             "Use Character Color"),
                                  &settings->isUseCharacterColor)))
      isJustColorSet = true;
    ImGui::SetItemTooltip("%s", string_get(Strings::SettingsUseCharacterColorTooltip,
                                           "When playing, the UI will use the character's preset UI color."));
    ImGui::SameLine();
    ImGui::BeginDisabled(settings->isUseCharacterColor);
    if (WIDGET_FX(
            ImGui::ColorEdit3(string_get(Strings::SettingsColor, "Color"), value_ptr(color),
                              ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoTooltip)))
    {
      style::color_set(color);
      isJustColorSet = true;
    }
    ImGui::SetItemTooltip("%s", string_get(Strings::SettingsColorTooltip, "Change the UI color."));
    ImGui::EndDisabled();

    ImGui::Separator();
    if (WIDGET_FX(ImGui::Button(string_get(Strings::SettingsResetButton, "Reset to Default"),
                                ImVec2(-FLT_MIN, 0))))
    {
      resources.settings.settings_default();
      settings = resources.settings.root();
      style::color_set(settings->color);
    }

    if (mode == PLAY)
    {
      ImGui::Separator();

      if (WIDGET_FX(
              ImGui::Button(string_get(Strings::SettingsSaveButton, "Save"), ImVec2(-FLT_MIN, 0))))
        isSave = true;
      ImGui::SetItemTooltip(
          "%s", string_get(Strings::SettingsSaveTooltip,
                           "Save the game.\n(Note: the game autosaves frequently.)"));

      if (WIDGET_FX(ImGui::Button(
              string_get(Strings::SettingsReturnToCharactersButton, "Return to Characters"),
              ImVec2(-FLT_MIN, 0))))
        isGoToSelect = true;
      ImGui::SetItemTooltip("%s", string_get(Strings::SettingsReturnToCharactersTooltip,
                                             "Go back to the character selection screen.\nProgress will be saved."));
    }
  }
}
