/******************************************************************************
*	File		-	assetBrowser.cpp
*	Author		-	Joey Pollack
*	Date		-	2021/11/10 (y/m/d)
*	Mod Date	-	2021/11/10 (y/m/d)
*	Description	-	Browse and manage project assets
******************************************************************************/

#include "asset_browser.h"
#include <dearimgui/imgui.h>
#include <editor/editor.h>
#include <editor/contents/content_manager.h>
#include <editor/contents/editor_asset.h>
#include <utils/logger.h>

namespace lunarium
{
namespace editor
{
    AssetBrowser::AssetBrowser(std::filesystem::path dir, Editor* pEditor)
        : Panel("Asset Browser", gui::PanelDockZone::DDZ_BOTTOM, true),  
            mAssetDirectory(dir), mTreeRoot(nullptr), mSelectedNode(nullptr), mpEditor(pEditor)
    {
        mTreeRoot = ReloadAssets(mAssetDirectory);
        mSelectedNode = mTreeRoot;
    }

    void AssetBrowser::SetAssetDirectory(std::filesystem::path dir)
    {
        mAssetDirectory = dir;
    }
    

    std::filesystem::path AssetBrowser::GetSelectedDirectory()
    {
        return mSelectedDir;
    }

    bool AssetBrowser::DoFrame()
    {
        if (!mIsOpen)
            return false;

        if (!ImGui::Begin(GetName(), &mIsOpen, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar))
        {
            ImGui::End();
            return false;
        }

        // Directory tree
        // TODO: Figure out a better way to size stuff other 
        //          than using this guess-work magic numbers
        float row_height = ImGui::GetFrameHeightWithSpacing() + 2.0f;
        ImVec2 wind_size = ImGui::GetWindowSize();
        wind_size.y -= (row_height + 8.0f);
        wind_size.x -= 15.0f;
        ImGui::SetCursorPosY(row_height);
        if (ImGui::BeginChild("Directory Tree", ImVec2(wind_size.x * 0.15f, wind_size.y), true, ImGuiWindowFlags_NoCollapse))
        {
            DoDirTree(mAssetDirectory);
        }
        ImGui::EndChild();

        ImGui::SetCursorPosY(row_height);
        ImGui::SetCursorPosX(ImGui::GetCursorPosX() + wind_size.x * 0.15f);

        // Contents
        if (ImGui::BeginChild("Contents", ImVec2(wind_size.x * 0.85f, wind_size.y), true, ImGuiWindowFlags_NoCollapse))
        {
            if (std::filesystem::exists(mSelectedDir))
            {
                float yPos = ImGui::GetCursorPosY();
                float xPos = ImGui::GetCursorPosX();
                float left = xPos;


                // Display each file in a row
                // for(auto const& dir_entry: std::filesystem::directory_iterator{mSelectedDir})
                // {
                //     if (!std::filesystem::is_directory(dir_entry))
                //     {
                //         // TODO: Turn into a table with file properties as columns
                //         ImGui::TextWrapped(dir_entry.path().filename().string().c_str());

                //     }
                // }

                std::filesystem::path selected_final = mpEditor->GetProject()->MakeRelativeToAssets(mSelectedDir);
                std::vector<EditorAsset*> assets;
                ContentManager::GetInstance().GetAllAssetsInDirectory(assets, selected_final);

                for (auto iter = assets.begin(); iter != assets.end(); iter++)
                {
                    if (ImGui::Selectable((*iter)->GetFileLocation().stem().string().c_str()))
                    {
                        // TODO: Show properties if this is new selection (meaning wasn't selected last frame)
                        Logger::Info(Editor::LogCat, "Asset selected. Properties shold show in the PropertiesView Panel");
                    }

                    if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
                    {
                        // TODO: Open relevant editor
                        Logger::Info(Editor::LogCat, "Asset double clicked on. Relevant editor should open!");
                    }
                }

                if (ImGui::BeginPopupContextWindow(0, 1, false))
                {
                    if (ImGui::Button("Click Me!"))
                    {
                        Logger::Info(Editor::LogCat, "Context menu button clicked!");
                    }

                    ImGui::EndPopup();
                }
            }
        }
        ImGui::EndChild();

        ImGui::End();
        return true;
    }

    void AssetBrowser::DoDirTree(std::filesystem::path dir)
    {
        if ("" == dir)
            return;

        if (!std::filesystem::is_directory(dir))
            return;

        if (ImGui::TreeNode(dir.filename().string().c_str()))
        {
            mSelectedDir = dir;
            for(auto const& dir_entry: std::filesystem::directory_iterator{dir})
            {
                DoDirTree(dir_entry);
            }
            ImGui::TreePop();
        }
    }

    AssetBrowser::Node* AssetBrowser::ReloadAssets(std::filesystem::path dir)
    {
        if ("" == dir)
            return nullptr;

        Node* pNode = new Node;
        pNode->Myself = dir;
        for(auto const& dir_entry: std::filesystem::directory_iterator{dir})
        {
            if (std::filesystem::is_directory(dir_entry))
            {
                pNode->Children.push_back(ReloadAssets(dir_entry));
            }
            else
            {
                pNode->Files.push_back(dir_entry);
            }
        }

        return pNode;
    }
}
}

// void treeChildren(ImGuiTreeNodeFlags node_flags, bool isOpen, int index)
// {
//     if (isOpen)
//     {
//         for (int p = 0; p < meshList[index].children.size(); p++)
//         {
//             if (meshList[index].children[p].children.empty())
//             {
//                 node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet
//                 ImGui::TreeNodeEx((void *)(intptr_t)p, node_flags, meshList[index].children[p].name.c_str());
//             }
//             else
//             {
//                 bool o = ImGui::TreeNodeEx((void *)(intptr_t)p, node_flags, meshList[index].children[p].name.c_str());
//                 ImGui::TreePop();
//                 treeChildren(node_flags, o, p);
//             }
//         }
//         ImGui::TreePop();
//     }
// }