// MassBuilderSaveTool
// Copyright (C) 2021 Guillaume Jacquemin
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "SaveTool.h"

#include <Corrade/Utility/Directory.h>

#include "../FontAwesome/IconsFontAwesome5.h"
#include "../FontAwesome/IconsFontAwesome5Brands.h"

void SaveTool::drawMainMenu() {
    if(ImGui::BeginMainMenuBar()) {
        if(ImGui::BeginMenu("Save Tool##SaveToolMenu")) {
            if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", Utility::Directory::exists(_gameDataDir))) {
                if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, Utility::Directory::exists(_configDir))) {
                    openUri(Utility::Directory::toNativeSeparators(_configDir));
                }

                if(ImGui::MenuItem(ICON_FA_SAVE " Saves", nullptr, false, Utility::Directory::exists(_saveDir))) {
                    openUri(Utility::Directory::toNativeSeparators(_saveDir));
                }

                if(ImGui::MenuItem(ICON_FA_IMAGE " Screenshots", nullptr, false, Utility::Directory::exists(_screenshotsDir))) {
                    openUri(Utility::Directory::toNativeSeparators(_screenshotsDir));
                }

                ImGui::EndMenu();
            }

            if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open manager directory")) {
                if(ImGui::MenuItem(ICON_FA_FILE_ARCHIVE " Profile backups", nullptr, false, Utility::Directory::exists(_backupsDir))) {
                    openUri(Utility::Directory::toNativeSeparators(_backupsDir));
                }

                if(ImGui::MenuItem(ICON_FA_EXCHANGE_ALT " Staging area", nullptr, false, Utility::Directory::exists(_stagingDir))) {
                    openUri(Utility::Directory::toNativeSeparators(_stagingDir));
                }

                ImGui::EndMenu();
            }

            ImGui::Separator();

            if(ImGui::BeginMenu(ICON_FA_COG " Settings")) {
                ImGui::AlignTextToFramePadding();
                ImGui::TextUnformatted("Frame limiter:");
                ImGui::SameLine();

                static UnsignedByte selection = static_cast<UnsignedByte>(_framelimit);
                static const char* framelimit_labels[3] = {
                    "V-sync",
                    "Half V-sync",
                    "FPS cap, no V-sync"
                };

                ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth());
                if(ImGui::BeginCombo("##FrameLimit", framelimit_labels[selection])) {
                    if(ImGui::Selectable(framelimit_labels[0], _framelimit == Framelimit::Vsync)) {
                        selection = 0;
                        _framelimit = Framelimit::Vsync;
                        setSwapInterval(1);
                    }
                    if(ImGui::Selectable(framelimit_labels[1], _framelimit == Framelimit::HalfVsync)) {
                        selection = 1;
                        _framelimit = Framelimit::HalfVsync;
                        setSwapInterval(2);
                    }
                    if(ImGui::Selectable(framelimit_labels[2], _framelimit == Framelimit::FpsCap)) {
                        selection = 2;
                        _framelimit = Framelimit::FpsCap;
                        setSwapInterval(0);
                        setMinimalLoopPeriod(1000 / _fpsCap);
                    }

                    ImGui::EndCombo();
                }

                if(_framelimit == Framelimit::FpsCap) {
                    static constexpr UnsignedInt min_fps = 15;
                    static constexpr UnsignedInt max_fps = 150;

                    ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth());
                    if(ImGui::SliderScalar("##FpsSlider", ImGuiDataType_U32, &_fpsCap, &min_fps, &max_fps, "%u FPS", ImGuiSliderFlags_AlwaysClamp)) {
                        setMinimalLoopPeriod(1000 / _fpsCap);
                    }
                }

                ImGui::Checkbox("Cheat mode", &_cheatMode);
                ImGui::SameLine();
                ImGui::AlignTextToFramePadding();
                drawHelpMarker("This gives access to save edition features that can be considered cheats.",
                               Float(windowSize().x()) * 0.4f);

                ImGui::Checkbox("Unsafe mode", &_unsafeMode);
                ImGui::SameLine();
                ImGui::AlignTextToFramePadding();
                drawHelpMarker("This allows changing the state of save files in the game's save folder even when the game is running.",
                               Float(windowSize().x()) * 0.4f);

                ImGui::Checkbox("Check for updates on startup", &_checkUpdatesOnStartup);
                ImGui::SameLine();
                if(ImGui::Button(ICON_FA_SYNC_ALT " Check now")) {
                    _queue.addToast(Toast::Type::Default, "Checking for updates...");
                    _updateThread = std::thread{[this]{ checkForUpdates(); }};
                }

                if(_updateAvailable) {
                    ImGui::AlignTextToFramePadding();
                    ImGui::Text("Version %s is available.", _latestVersion.c_str());
                    if(ImGui::Button(ICON_FA_FILE_SIGNATURE " Release notes")) {
                        openUri(_releaseLink);
                    }
                    ImGui::SameLine();
                    if(ImGui::Button(ICON_FA_DOWNLOAD " Download now")) {
                        openUri(_downloadLink);
                    }
                }

                ImGui::Checkbox("Skip disclaimer", &_skipDisclaimer);

                ImGui::EndMenu();
            }

            ImGui::Separator();

            if(ImGui::MenuItem(ICON_FA_SIGN_OUT_ALT " Quit##QuitMenuItem")) {
                exit(EXIT_SUCCESS);
            }

            ImGui::EndMenu();
        }

        if(ImGui::BeginMenu("Game##GameMenu")) {
            if(ImGui::MenuItem(ICON_FA_PLAY " Run demo##RunDemoMenuItem")) {
                openUri("steam://run/1048390");
            }
            drawTooltip("Will not work if you have the full game.");

            if(ImGui::MenuItem(ICON_FA_PLAY " Run full game##RunFullGameMenuItem")) {
                openUri("steam://run/956680");
            }

            ImGui::Separator();

            if(ImGui::BeginMenu(ICON_FA_DISCORD " Discord communities")) {
                if(ImGui::MenuItem("Official server")) {
                    openUri("https://discord.gg/quS7E46");
                }

                if(ImGui::MenuItem("Community server")) {
                    openUri("https://discord.gg/YSSRTRB");
                }

                ImGui::EndMenu();
            }

            ImGui::EndMenu();
        }

#ifdef SAVETOOL_DEBUG_BUILD
        if(ImGui::BeginMenu("Debug tools")) {
            ImGui::MenuItem("ImGui demo window", nullptr, &_demoWindow);
            ImGui::MenuItem("ImGui style editor", nullptr, &_styleEditor);
            ImGui::MenuItem("ImGui metrics window", nullptr, &_metricsWindow);

            ImGui::EndMenu();
        }
#endif

        if(ImGui::BeginMenu("Help")) {
            if(ImGui::BeginMenu(ICON_FA_BOOK " ImGui user guide")) {
                ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text.");
                ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields.");
                ImGui::BulletText("While inputing text:\n");
                ImGui::Indent();
                ImGui::BulletText("CTRL+Left/Right to word jump.");
                ImGui::BulletText("CTRL+A or double-click to select all.");
                ImGui::BulletText("CTRL+X/C/V to use clipboard cut/copy/paste.");
                ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo.");
                ImGui::BulletText("ESCAPE to revert.");
                ImGui::BulletText("You can apply arithmetic operators +,*,/ on numerical values.\nUse +- to subtract.");
                ImGui::Unindent();
                ImGui::EndMenu();
            }
            ImGui::MenuItem(ICON_FA_INFO_CIRCLE " About", nullptr, &_aboutPopup);

            ImGui::EndMenu();
        }

        if(_gameCheckTimerId != 0) {
            if(ImGui::BeginTable("##MainMenuLayout", 2)) {
                ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
                ImGui::TableSetupColumn("##GameState", ImGuiTableColumnFlags_WidthFixed);

                ImGui::TableNextRow();
                ImGui::TableSetColumnIndex(1);
                drawGameState();

                ImGui::EndTable();
            }
        }

        ImGui::EndMainMenuBar();
    }
}