#include "Sprite.hpp"
#include "ResourceManager.hpp"

SpriteComponent::SpriteComponent(TransformComponent *_transform)
{
    transform = _transform;
    printf("POS : X, %f Y, %f\n", transform->getPos().x, transform->getPos().y);
}

SpriteComponent::~SpriteComponent()
{
    // TODO: Make sure spritesheet and mTexture are destroyed
    // but is this the right place?
    SDL_FreeSurface(mSpriteSheet);
    mSpriteSheet = nullptr;
    SDL_DestroyTexture(mTexture);
}

void SpriteComponent::Update(SDL_Event e, int frame, std::vector<std::string> broadcastList)
{
    ParseAndUpdateBroadcast(broadcastList);
    // The part of the image that we want to render
    mCurrentFrame = frame % frameCount;

    // Here I am selecting which frame I want to draw
    // from our sprite sheet. Think of this as just
    // using a mouse to draw a rectangle around the
    // sprite that we want to draw.
    mSrc.x = mCurrentFrame * width;
    mSrc.y = 0;
    mSrc.w = width;
    mSrc.h = height;

    // Where we want the rectangle to be rendered at.
    // This is an actual 'quad' that will draw our
    // source image on top of.
    mDest.x = transform->getPos().x;
    mDest.y = transform->getPos().y;

    // printf("X: %f, Y: %f\n", transform->getPos().x, transform->getPos().y);

    mDest.w = dimensions.x;
    mDest.h = dimensions.y;
}

void SpriteComponent::Render(SDL_Renderer *ren)
{
    SDL_RenderCopy(ren, mTexture, &mSrc, &mDest);
}

void SpriteComponent::ShowComponentEditor(bool *showEditor)
{
    ImGuiWindowFlags window_flags = 0;
    window_flags |= ImGuiWindowFlags_MenuBar;
    window_flags |= ImGuiWindowFlags_NoCollapse;

    if (ImGui::Begin("Editing Sprite Component", showEditor, window_flags))
    {
        int displayWidth = dimensions.x;
        int displayHeight = dimensions.y;
        static char filePath[255] = "";
        ImGui::InputText("New Image File", filePath, IM_ARRAYSIZE(filePath));
        if (ImGui::Button("Update Image File"))
        {
            dimensions = Vec2D(displayWidth, displayHeight);
            LoadImage(filePath, last_used, width, height, frameCount, dimensions);
        }
        ImGui::InputInt("Tile Width", &width);
        ImGui::InputInt("Tile Height", &height);
        ImGui::InputInt("Display Width", &displayWidth);
        ImGui::InputInt("Display Height", &displayHeight);
        ImGui::InputInt("Frame Count", &frameCount);
        ImGui::End();
    }
}

void SpriteComponent::LoadImage(std::string filePath, SDL_Renderer *ren, int w, int h, int frames, Vec2D targetDisplay)
{
    last_used = ren;
    width = w;
    height = h;
    frameCount = frames;

    dimensions = targetDisplay;

    mSpriteSheet = ResourceManager::GetInstance().LoadResource(filePath);
    mTexture = SDL_CreateTextureFromSurface(ren, mSpriteSheet);
    // mSpriteSheet = SDL_LoadBMP(filePath.c_str());
    // if (nullptr == mSpriteSheet)
    // {
    //     SDL_Log("Failed to allocate surface");
    // }
    // else
    // {
    //     SDL_Log("Allocated a bunch of memory to create identical game character");
    //     // Create a texture from our surface
    //     // Textures run faster and take advantage
    //     // of hardware acceleration
    //     mTexture = SDL_CreateTextureFromSurface(ren, mSpriteSheet);
    // }
}

Vec2D SpriteComponent::getDimensions()
{
    return dimensions;
}
