/******************************************************************************
*	File		-	editor.cpp
*	Author		-	Joey Pollack
*	Date		-	2021/11/01 (y/m/d)
*	Mod Date	-	2021/11/01 (y/m/d)
*	Description	-	Entry point for the editor run mode.
******************************************************************************/

#include "editor.h"

#include "panels/mainPanel.h"
#include <core/core.h>
#include <utils/logger.h>
#include <gui/fileBrowser.h>
#include <internal_data/dataManager.h>

// Panels
#include "panels/about.h"
#include "panels/assetBrowser.h"

namespace lunarium
{
    Editor::Editor()
        : mLogCat(-1), mpMainPanel(nullptr), mpFileBrowser(nullptr), mpPath(nullptr), mDoNewProject(false), mDoOpenProject(false),
        mDoSaveProject(false), mDoSaveAs(false)
    {
    }

    OpRes Editor::Initialize()
    {
        mLogCat = Logger::RegisterCategory("EDITOR");
        mpMainPanel = &MainPanel::GetInstance();
        mpMainPanel->SetEditor(this);

        // Initialize internal data
        DataManager::Initialize();

        CreatePanels();

        return OpRes::OK();
    }
    
    void Editor::Shutdown()
    {
        DestoryPanels();
        DataManager::Shutdown();
        MainPanel::FreeInstance();

    }
    
    void Editor::OnTick(double delta)
    {
        HandleMenuEvents();
    }
    
    void Editor::OnRender(IGraphics* g)
    {
        mpMainPanel->DoFrame();

        for (auto iter = mPanels.begin(); iter != mPanels.end(); iter++)
        {
            if (iter->second->IsOpen())
            {
                iter->second->DoFrame();
            }
        }

        
        if (mpFileBrowser)
        {
            if (!mpFileBrowser->DoFrame())
            {
                mpPath = mpFileBrowser->GetSelectedItem();
            }
        }
    }

    uint32_t Editor::GetLogCat() const
    {
        return mLogCat;
    }

    ////////////////////////////////////////////////////////////
    //				HELPER METHODS
    ////////////////////////////////////////////////////////////
    void Editor::CreatePanels()
    {
        mPanels[PanelType::PT_ABOUT] = new AboutPanel;
        mPanels[PanelType::PT_ASSET_BROWSER] = new AssetBrowser("");
    }

    void Editor::DestoryPanels()
    {
        delete mPanels[PanelType::PT_ABOUT];
        delete mPanels[PanelType::PT_ASSET_BROWSER];
    }

    void Editor::HandleMenuEvents()
    {
        ///////////////////////////
        // FILE
        if (mDoNewProject)
        {
            if (!mpFileBrowser)
            {
                mpFileBrowser = new FileBrowser;
                // mpFileBrowser->WarnOnExistingFileSelection(true);
                mpFileBrowser->SetSelectionMode(FileBrowser::SelectionMode::FILES_ONLY);
                mpFileBrowser->SetPrompt("Pick a location and name for the project");
                if (!mpFileBrowser->OpenInDirectory(""))
                {
                    delete mpFileBrowser;
                    mpFileBrowser = nullptr;
                    mDoNewProject = false;
                    Logger::Log(mLogCat, LogLevel::ERROR, "Could not open the File Browser");
                }
            }
            else
            {
                if (!mpFileBrowser->IsOpen())
                {
                    if (mpFileBrowser->GetResult() == FileBrowser::Result::OK)
                    {
                        Logger::Log(mLogCat, LogLevel::INFO, "Generating new project at %s", mpPath->string().c_str());

                        // Generate new project at mpPath
                        OpRes result = mProject.GenerateProject(mpPath->filename().string(), mpPath->parent_path());
                        if (Failed(result))
                        {
                            Logger::Log(mLogCat, LogLevel::ERROR, "Could not create a new project: %s", result.Description);
                        }
                        ((AssetBrowser*)mPanels[PanelType::PT_ASSET_BROWSER])->SetAssetDirectory(*mpPath / std::filesystem::path("contents/assets"));
                    }
                    else
                    {
                        Logger::Log(mLogCat, LogLevel::INFO, "New Project operation cancelled");
                    }

                    mpPath = nullptr;
                    delete mpFileBrowser;
                    mpFileBrowser = nullptr;
                    mDoNewProject = false;
                }
            }            
        }

        if (mDoOpenProject)
        {
            if (!mpFileBrowser)
            {
                mpFileBrowser = new FileBrowser;
                // mpFileBrowser->WarnOnExistingFileSelection(true);
                mpFileBrowser->SetSelectionMode(FileBrowser::SelectionMode::FILES_ONLY);
                mpFileBrowser->SetPrompt("Locate the project to open");
                if (!mpFileBrowser->OpenInDirectory(""))
                {
                    delete mpFileBrowser;
                    mpFileBrowser = nullptr;
                    mDoOpenProject = false;
                    Logger::Log(mLogCat, LogLevel::ERROR, "Could not open the File Browser");
                }
            }
            else
            {
                if (!mpFileBrowser->IsOpen())
                {
                    if (mpFileBrowser->GetResult() == FileBrowser::Result::OK)
                    {
                        Logger::Log(mLogCat, LogLevel::INFO, "Generating new project at %s", mpPath->string().c_str());

                        // Generate new project at mpPath
                        OpRes result = mProject.LoadProject(*mpPath);
                        if (Failed(result))
                        {
                            Logger::Log(mLogCat, LogLevel::ERROR, "Could not open project: %s -- reason: %s", mpPath->string().c_str(), result.Description);
                        }
                        ((AssetBrowser*)mPanels[PanelType::PT_ASSET_BROWSER])->SetAssetDirectory(mpPath->parent_path() / std::filesystem::path("contents/assets"));
                    }
                    else
                    {
                        Logger::Log(mLogCat, LogLevel::INFO, "New Project operation cancelled");
                    }

                    mpPath = nullptr;
                    delete mpFileBrowser;
                    mpFileBrowser = nullptr;
                    mDoOpenProject = false;
                }
            }
        }

        if (mDoSaveProject)
        {

            mDoSaveProject = false;
        }

        if (mDoSaveAs)
        {

            mDoSaveAs = false;
        }
        ///////////////////////////
        
    }

    

    ////////////////////////////////////////////////////////////
    //				MENU BAR EVENTS
    ////////////////////////////////////////////////////////////
    void Editor::NewProject()
    {
        mDoNewProject = true;
    }

    void Editor::OpenProject()
    {
        mDoOpenProject = true;
    }

    void Editor::SaveProject()
    {
        mDoSaveProject = true;
    }

    void Editor::SaveAs()
    {
        mDoSaveAs = true;
    }

    void Editor::Exit()
    {
        Core::GetInstance().SignalShutdown();
    }

    void Editor::ShowAboutPanel()
    {
        mPanels[PanelType::PT_ABOUT]->SetOpen(true);
    }
}