/******************************************************************************
*	File		-	map_canvas.cpp
*	Author		-	Joey Pollack
*	Date		-	2022/02/14 (y/m/d)
*	Mod Date	-	2022/02/14 (y/m/d)
*	Description	-	the canvas panel for painting map tiles
******************************************************************************/

#include "map_canvas.h"
#include "../map_editor.h"
#include <editor/editor.h>
#include <gui/dearimgui/imgui.h>
#include <core/core.h>
#include <graphics/graphics.h>
#include <assets/types/image.h>

#include <string>
#include <sstream>

namespace lunarium { namespace editor 
{
    MapCanvas::MapCanvas(MapEditor* editor)
        : Panel(gui::PanelType::PT_MAP_CANVAS, "Map Canvas", gui::PanelDockZone::DDZ_CENTER, true),
        mpMapEditor(editor), mpCanvasImage(nullptr), mMap(nullptr), mSelectedTile({-1, -1}), mFrameBuffer(-1), mMapSizeChanged(false)
    {
        
    }

    void MapCanvas::Update(float delta)
    {
        if (!mpCanvasImage)
        {
            if (mMap)
            {
                if (mMapSizeChanged)
                {
                    Core::Graphics().DestroyRenderTexture(mFrameBuffer);
                    mFrameBuffer = -1;
                    mMapSizeChanged = false;
                }

                if (mFrameBuffer == -1)
                {
                    mFrameBuffer = Core::Graphics().CreateRenderTexture(mMap->GetSizeInPixels().Width, mMap->GetSizeInPixels().Height, 4);
                }

                Color prev = Core::Graphics().GetClearColor();
                Core::Graphics().SetClearColor(Color::Transparent());
                Core::GetInstance().BeginRenderToTexture(mFrameBuffer).LogIfFailed(Editor::LogCat);
                mMap->Render(&Core::Graphics());
                mpCanvasImage = Core::GetInstance().EndRenderToTexture();
                Core::Graphics().SetClearColor(prev);
            }
        }
    }

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

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

        ImVec2 pos = ImGui::GetWindowPos();
        ImVec2 size = ImGui::GetWindowSize();

        // Adjust for the tab bar
        pos.y += ImGui::GetFrameHeight();
        size.y -= ImGui::GetFrameHeight();      
        ImGuiIO& io = ImGui::GetIO();
        float x = io.MousePos.x - pos.x;
        float y = io.MousePos.y - pos.y;
        
        

        std::ostringstream oss;
        oss << "Mouse Position on Panel: ";
        if (x < 0.0f || y < 0.0f || x > size.x || y > size.y)
        {
            oss << "OUTSIDE PANEL";
        }
        else
        {
            oss << "(" << x << ", " << y << ")";
        }

        oss << "\nFrameHeight: " << ImGui::GetFrameHeight();
        oss <<"\nFrameHeightWithSpacing: " << ImGui::GetFrameHeightWithSpacing();
        mMouseStatusInfo = oss.str();

        //ImGui::Text(mMouseStatusInfo.c_str());
        if (mpCanvasImage)
        {
            ImGui::Image((ImTextureID)mpCanvasImage->GetGLTextureID64(), ImVec2(mpCanvasImage->GetWidth(), mpCanvasImage->GetHeight()));
        }

        // TODO: If a tile on the map was changed this frame null out the canvas image so it will be redrawn


        ImGui::End();
        return mIsOpen;
    }

    void MapCanvas::SetTileMap(TileMap* pMap)
    {
        mMap = pMap;

        // Force the image to redraw
        mpCanvasImage = nullptr;
    }

    void MapCanvas::SetSelectedTile(TileRef tile)
    {
        mSelectedTile = tile;
    }
    
    TileRef MapCanvas::GetSelectedTile() const
    {
        return mSelectedTile;
    }

    void MapCanvas::MapSizeChanged()
    {
        mMapSizeChanged = true;
        mpCanvasImage = nullptr;
    }
     
}}