/******************************************************************************
*	File		-	properties_view.h
*	Author		-	Joey Pollack
*	Date		-	2022/01/26 (y/m/d)
*	Mod Date	-	2022/01/26 (y/m/d)
*	Description	-	Displayes the properties and components(?) of the selected
*                   object.
******************************************************************************/

#include "properties_view.h"
#include <dearimgui/imgui.h>
#include <gui/imgui_ext.h>
#include <editor/editor.h>
#include <world/entity.h>
#include <world/components.h>
#include <editor/component_guis.h>

#define PRESENT_COMP_CHOICE(str_name, type_name, pv) \
if (ImGui::Selectable(str_name)){\
    if (pv->mpSelectedEntity->HasComponent<type_name>()) {\
        pv->OpenPopup(Popup::ADD_COMP_FAIL).LogIfFailed(Editor::LogCat);\
        return false;\
    }\
    pv->mpSelectedEntity->AddComponent<type_name>();\
    return false;\
}

namespace lunarium { namespace editor 
{
    PropertiesView::PropertiesView()
        : Panel("Properties", PanelDockZone::DDZ_RIGHT, true, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar), 
            mpSelectedAsset(nullptr), mpSelectedEntity(nullptr), mIsLocked(false)
    {
        AddPopup(Popup::ADD_COMP, "Add Component", [](Panel* p) 
        {
            PropertiesView* pv = (PropertiesView*)p;

            // List components that can be added
            PRESENT_COMP_CHOICE("Tag Component", TagComponent, pv)
            PRESENT_COMP_CHOICE("Transform Component", TransformComponent, pv)

            return true;
        }).LogIfFailed(Editor::LogCat);

        AddPopup(Popup::ADD_COMP_FAIL, "Add Comp Fail", [] (Panel* p)
        {
            ImGui::Text("Can not add that component - Entity already has it");
            if (ImGui::Button("OK") || (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsWindowHovered()))
            {
                return false;
            }

            return true;
        }).LogIfFailed(Editor::LogCat);
    }

    /////////////////////////////////////////////////////////////////////
    //				RENDER METHOD
    /////////////////////////////////////////////////////////////////////

    void PropertiesView::DoFrame()
    {
        ShowToolBar();

        if (mpSelectedEntity)
        {
            ShowEntity();
        }

        if (mpSelectedAsset)
        {
            ShowAsset();
        }

    }

    /////////////////////////////////////////////////////////////////////
    //				INTERFACE METHODS
    /////////////////////////////////////////////////////////////////////

    void PropertiesView::SetSelection(Entity* pEntity)
    {
        if (mIsLocked)
        {
            return;
        }

        mpSelectedAsset = nullptr;
        mpSelectedEntity = pEntity;
    }

    void PropertiesView::SetSelection(EditorAsset* pAsset)
    {
        if (mIsLocked)
        {
            return;
        }
        
        mpSelectedEntity = nullptr;
        mpSelectedAsset = pAsset;
    }

    /////////////////////////////////////////////////////////////////////
    //			HELPER METHODS      HELPER METHODS
    /////////////////////////////////////////////////////////////////////
    void PropertiesView::ShowToolBar()
    {
        ImGui::BeginChild("##PropsToolBar", ImVec2(0, ImGui::GetFrameHeightWithSpacing()));

        ImGui::Checkbox("Locked", &mIsLocked);

        ImGui::EndChild();
        ImGui::Separator();
    }
    
    void PropertiesView::ShowEntity()
    {
        ImGuiExt::TextCentered("Components");
        float spacing_y = 12.0f;
        ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, spacing_y));
        ImGui::Separator();

        // TODO: iterate through components
        if (mpSelectedEntity->HasComponent<TagComponent>())
        {
            CompGui::RenderTagComp(mpSelectedEntity->GetComponent<TagComponent>());

            ImGui::Separator();
        }
        
        if (mpSelectedEntity->HasComponent<TransformComponent>())
        {
            ImGui::PopStyleVar();
            CompGui::RenderTransformComp(mpSelectedEntity->GetComponent<TransformComponent>());
            ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, spacing_y));
            ImGui::Separator();
        }

        // After all components rendered
        if (ImGuiExt::ButtonCentered("Add Component"))
        {
            OpenPopup(Popup::ADD_COMP).LogIfFailed(Editor::LogCat);
        }

        ImGui::PopStyleVar();
    }

    void PropertiesView::ShowAsset()
    {

    }

}}