/******************************************************************************
*	File		-	iPanel.cpp
*	Author		-	Joey Pollack
*	Date		-	2021/11/01 (y/m/d)
*	Mod Date	-	2021/11/01 (y/m/d)
*	Description	-	Base class for all editor panels
******************************************************************************/

#include "panel.h"

#include "dearimgui/imgui.h"

namespace lunarium
{
    Panel::Panel(std::string name, PanelDockZone dock_zone, bool isOpen, int window_flags)
        : mIsOpen(isOpen), mPanelName(name), mDockZone(dock_zone), mWindowFlags(window_flags),
        mX(-1), mY(-1), mWidth(-1), mHeight(-1), mNumPushedStyles(0)
    {

    }

    Panel::~Panel()
    {
        
    }

    const char* Panel::GetName() const
    {
        return mPanelName.c_str();
    }

    PanelDockZone Panel::GetDockZone() const
    {
        return mDockZone;
    }

    
    void Panel::SetWindowFlags(int flags)
    {
        mWindowFlags = flags;
    }

    void Panel::SetOpen(bool isOpen)
    {   
        mIsOpen = isOpen;
    }

    bool Panel::IsOpen()
    {
        return mIsOpen;
    }
    
    void Panel::GetPosition(int& x, int& y) const
    {
        x = mX;
        y = mY;
    }

    void Panel::GetSize(int& w, int& h) const
    {
        w = mWidth;
        h = mHeight;
    }

    
    void Panel::SetNumPushedStyles(int num)
    {
        mNumPushedStyles = num;
    }
    
    void Panel::Update(float dt)
    {
        
    }

    void Panel::PreBegin()
    {

    }
    
    bool Panel::OnUIRender()
    {
        if (!mIsOpen)
            return false;

        PreBegin();

        if (!ImGui::Begin(GetName(), &mIsOpen, (ImGuiWindowFlags) mWindowFlags))
        {
            ImGui::PopStyleVar(mNumPushedStyles);
            ImGui::End();
            return false;
        }

        ImGui::PopStyleVar(mNumPushedStyles);
        UpdateMetaInfo();

        DoFrame();

        RunPopups();

        ImGui::End();
        return true;
    }

    
    OpRes Panel::AddPopup(int id, std::string name, std::function<bool(Panel*)> func) 
    {
        auto iter = mPopups.find(id);
        if (iter != mPopups.end())
        {
            return OpRes::Fail("A popup with id: %d alread exists. Existing name: %s, New Name: %s", 
                            iter->first, iter->second->Name.c_str(), name.c_str());
        }

        mPopups[id] = new Popup { func, false, name };
        return OpRes::OK();
    }

    OpRes Panel::OpenPopup(int id)
    {
        auto iter = mPopups.find(id);
        if (iter == mPopups.end())
        {
            return OpRes::Fail("Attempt to open A popup with id: %d but it does not exist.", id);
        }

        iter->second->IsOpen = true;
        return OpRes::OK();
    }

    void Panel::RunPopups()
    {
        for (auto iter = mPopups.begin(); iter != mPopups.end(); iter++)
        {
            Popup* ppu = iter->second;
            if (ppu->IsOpen)
            {
                if (ImGui::BeginPopupContextItem(ppu->Name.c_str()))
                {
                    ppu->IsOpen = ppu->PopupFunc(this);
                    ImGui::EndPopup();
                }
                ImGui::OpenPopup(ppu->Name.c_str());
            }
        }
    }

    void Panel::UpdateMetaInfo()
    {
        ImVec2 p = ImGui::GetWindowPos();
        ImVec2 s = ImGui::GetWindowSize();

        mX = p.x;
        mY = p.y;
        mWidth = s.x;
        mHeight = s.y;
    }

}