/******************************************************************************
*	File		-	tile_set.h
*	Author		-	Joey Pollack
*	Date		-	2022/02/16 (y/m/d)
*	Mod Date	-	2022/02/16 (y/m/d)
*	Description	-	Manage a tile set for map making
******************************************************************************/

#include "tile_set.h"
#include <editor/editor.h>
#include <editor/editor_helpers.h>
#include <graphics/graphics.h>
#include <assets/types/image.h>
#include <utils/logger.h>
#include <pugixml.hpp>

namespace lunarium { namespace editor 
{
    TileSet::TileSet()
        : EditorAsset(AssetType::EATYPE_TILE_SET), mSetImage(nullptr), mTileSize({ 0, 0})
    {
        
    }

    OpRes TileSet::LoadRawFile()
    {
        mSetImage = FileLoaders::LoadImage(GetFileLocation());
        if (!mSetImage)
        {
            return OpRes::Fail("Could not load image file: %s", GetFileLocation().string().c_str());
        }

        // Set some default values
        mTileSize = { 16, 16 };
        mNumTiles = { mSetImage->GetWidth() / 16, mSetImage->GetHeight() / 16 };

        return OpRes::OK();
    }
    
    OpRes TileSet::LoadFromXML(pugi::xml_node& node)
    {
        // Load Image
        mSetImage = FileLoaders::LoadImage(GetFileLocation());
        if (!mSetImage)
        {
            return OpRes::Fail("Could not load image file: %s", GetFileLocation().string().c_str());
        }

        mTileSize.Width = node.attribute("TileSizeWidth").as_int();
        mTileSize.Height = node.attribute("TileSizeHeight").as_int();
        mNumTiles.Width = node.attribute("NumTilesCol").as_int();
        mNumTiles.Height = node.attribute("NumTilesRow").as_int();

        return OpRes::OK();
    }

    OpRes TileSet::SaveToXML(pugi::xml_node& node)
    {
        node.append_attribute("TileSizeWidth").set_value(mTileSize.Width);
        node.append_attribute("TileSizeHeight").set_value(mTileSize.Height);
        node.append_attribute("NumTilesCol").set_value(mNumTiles.Width);
        node.append_attribute("NumTilesRow").set_value(mNumTiles.Height);

        return OpRes::OK();
    }

    void TileSet::SetImage(Image* image)
    {
        mSetImage = image;
    }

    void TileSet::SetTileSize(Sizei size)
    {
        mTileSize = size;
        mNumTiles.Width = mSetImage->GetWidth() / mTileSize.Width;
        mNumTiles.Height = mSetImage->GetHeight() / mTileSize.Height;
    }

    Image* TileSet::GetImage()
    {
        return mSetImage;
    }

    Sizei TileSet::GetTileSize()
    {
        return mTileSize;
    }

    Rectangle TileSet::GetTileRect(Vec2i index)
    {
        return Rectangle::MakeFromTopLeft(index.X * mTileSize.Width, index.Y * mTileSize.Height, mTileSize.Width, mTileSize.Height);
    }

    void TileSet::Render(lunarium::IGraphics* g)
    {
        g->DrawImage(*mSetImage, glm::vec2(0, 0), Color::White());

        // Draw grid
        for (int i = 0; i < mNumTiles.Width; i++)
        {
            g->DrawLine(glm::vec2(i * mTileSize.Width, 0), glm::vec2(i * mTileSize.Width, mSetImage->GetHeight()), Color::Black(), 1.0f);
        }
        g->DrawLine(glm::vec2(mSetImage->GetWidth(), 0), glm::vec2(mSetImage->GetWidth(), mSetImage->GetHeight()), Color::Black(), 1.0f);

        for (int j = 0; j < mNumTiles.Height; j++)
        {
            g->DrawLine(glm::vec2(0, j * mTileSize.Height), glm::vec2(mSetImage->GetWidth(), j * mTileSize.Height), Color::Black(), 1.0f);
        }
        g->DrawLine(glm::vec2(0, mSetImage->GetHeight()), glm::vec2(mSetImage->GetWidth(), mSetImage->GetHeight()), Color::Black(), 1.0f);
    }
}}