/******************************************************************************
*	File		-	map_editor.h
*	Author		-	Joey Pollack
*	Date		-	2022/01/31 (y/m/d)
*	Mod Date	-	2022/01/31 (y/m/d)
*	Description	-	The tile map editor tool. Controls subwindows/panels.
******************************************************************************/

#include "map_editor.h"

#include <core/core.h>
#include <graphics/graphics.h>
#include <editor/project/contents/content_manager.h>
#include <assets/types/image.h>
#include <editor/editor.h>
#include <gui/panel.h>
#include <gui/dearimgui/imgui.h>
#include <editor/project/contents/tile_set.h>
#include <editor/project/contents/tile_map.h>

// Panels
#include "panels/map_canvas.h"
#include "panels/tile_set_view.h"

// TEMP
#include <utils/stb/stb_image.h>

namespace lunarium { namespace editor
{
    MapEditor::MapEditor()
        : mpEditor(nullptr), mIsOpen(false), mMapLoaded(false), mImportTileSet(false), mTileSetNextID(0)
    {
        
    }


    OpRes MapEditor::Initialize(Editor* editor)
    {
        if (mpEditor)
        {
            return OpRes::Fail("MapEditor is already initialized");
        }

        mpEditor = editor;
        if (Failed(mPanelManager.Initialize(mpEditor, "Map Editor").LogIfFailed(mpEditor->GetLogCat(), "Map Editor - ")))
        {
            return OpRes::Fail("Could not initialize the panel manager!");
        }

        mPanelManager.AddPanel(new MapCanvas(this)).LogIfFailed(mpEditor->GetLogCat());
        mPanelManager.AddPanel(new TileSetView(this)).LogIfFailed(mpEditor->GetLogCat());

        Open();

        return OpRes::OK();
    }

    void MapEditor::Shutdown()
    {
        mpEditor = nullptr;

        // Free Tilesets
        mPanelManager.Shutdown();
        for (auto i = mTileSets.begin(); i != mTileSets.end(); i++)
        {
            delete i->second->GetImage();
            delete i->second;
        }

        mTileSets.clear();
    }

    void MapEditor::OnTick(double delta)
    {
        HandleMenuEvents();

        mPanelManager.OnTick(delta);
    }

    bool MapEditor::OnRender(lunarium::IGraphics* g)
    {
        if (!mIsOpen)
        {
            Close();
            return false;
        }


        ImGui::SetNextWindowSize(ImVec2(800, 500), ImGuiCond_FirstUseEver);
        if (!ImGui::Begin("Map Editor", &mIsOpen, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_MenuBar))
        {
            mPanelManager.MakeDockSpaces();
            Close();
            ImGui::End();
            return false;
        }
        DoMenu();

        mPanelManager.MakeDockSpaces();

        ImGui::End();

        mPanelManager.RenderPanels();

        if (mFileBrowser.IsOpen())
        {
            mFileBrowser.DoFrame();
        }
        return true;
    }


    void MapEditor::Open()
    {
        if (mIsOpen)
        {
            return;
        }

        mIsOpen = true;
    }

    void MapEditor::Close()
    {        
        mIsOpen = false;
    }

    bool MapEditor::IsOpen() const
    {
        return mIsOpen;
    }


    void MapEditor::NewMap()
    {
        
    }

    OpRes MapEditor::LoadMap(std::string map)
    {
        return OpRes::Fail("MapEditor::LoadMap not implemented");
    }

    void MapEditor::SaveMap()
    {
        
    }

    bool MapEditor::IsMapLoaded() const
    {
        return mMapLoaded;
    }

    const std::map<int, TileSet*>* MapEditor::GetTileSets() const
    {
        return &mTileSets;
    }

    ////////////////////////////////////////////////////////////
    //				HELPERS
    ////////////////////////////////////////////////////////////
    void MapEditor::DoMenu()
    {
        ImGui::BeginMenuBar();

        if (ImGui::BeginMenu("File"))
        {
            if (ImGui::MenuItem("Import Tile Set"))
            {
                mImportTileSet = true;
                mFileBrowser.SetSelectionMode(FileBrowser::SelectionMode::FILES_ONLY);
                mFileBrowser.SetPrompt("Find the tile set image");
                if (!mFileBrowser.OpenInDirectory(""))
                {
                    mImportTileSet = false;
                    Logger::Log(Editor::LogCat, LogLevel::ERROR, "Could not open the File Browser");
                }
            }

            ImGui::Separator();
            if (ImGui::MenuItem("Exit"))
            {
                Close();
            }
            
            ImGui::EndMenu();
        }

         if (ImGui::BeginMenu("Windows"))
            {
                if (ImGui::MenuItem("Reset Window Docking"))
                {
                    mPanelManager.ResetDocking();
                }
                ImGui::Separator();

                // HanelOpenPanel("Asset Browser", gui::PanelType::PT_ASSET_BROWSER);
                // HanelOpenPanel("World Tree", gui::PanelType::PT_WORLD_TREE);
                // HanelOpenPanel("World View", gui::PanelType::PT_WORLD_VIEW);
                // HanelOpenPanel("Properties", gui::PanelType::PT_PROPERTIES_VIEW);

                ImGui::EndMenu();
            }


        ImGui::EndMenuBar();
    }

    void MapEditor::HandleMenuEvents()
    {
         if (mImportTileSet)
        {
            if (mFileBrowser.GetResult() == FileBrowser::Result::OK)
            {
                auto path = mFileBrowser.GetSelectedItem();
                Logger::Log(Editor::LogCat, LogLevel::INFO, "Importing tile set: %s", path->string().c_str());

                uint64_t id = 0;
                ContentManager::GetInstance().ImportFile(*path, mpEditor->GetAssetBrowserLocation() / path->filename(), AssetType::EATYPE_TILE_SET, id).LogIfFailed(Editor::LogCat);

                // For now just directly load the file and make a tileset out of it
                // int w, h, n;
                // stbi_set_flip_vertically_on_load(1);
                // unsigned char* buffer = stbi_load(path->string().c_str(), &w, &h, &n, 0);

                // Image* i = new Image();
                // i->SetData(buffer);
                // i->SetFormat(ImageFormat::RGBA);

                // if (n == 3)
                // {
                //     i->SetFormat(ImageFormat::RGB);
                // }

                // i->SetWidth(w);
                // i->SetHeight(h);

                // Core::Graphics().RegisterImage(*i);

                // TileSet* ts = new TileSet();
                // // ts->SetFileLocation(*path);
                // ts->SetImage(i);

                TileSet* ts = (TileSet*)ContentManager::GetInstance().GetAsset(id);
                ts->SetTileSize({16, 16});      // NOTE: Hardcoding the tile size for testing
                
                mTileSets[mTileSetNextID] = ts;
                mTileSetNextID++;

                // FOR TESTING
                ((TileSetView*)mPanelManager.GetPanel(gui::PanelType::PT_TILE_SET_VIEW))->SetTileSet(ts);

                mImportTileSet = false;
            }
            else if (mFileBrowser.GetResult() == FileBrowser::Result::CANCEL)
            {
                Logger::Log(Editor::LogCat, LogLevel::INFO, "New Project operation cancelled");
                mImportTileSet = false;
            }
        
        }

    }
}}
