#include "World.h"
#include "Snake.h"
#include "Fruit.h"

TWorld::TWorld()
{
    Snake = new TSnake();
    if (!Snake)
    {
        SDL_Log("Couldn't create TSnake object");
    }

    m_FruitsCount = 10;
    Fruits.reserve(m_FruitsCount);
    for (int i = 0; i < m_FruitsCount; ++i)
    {
        TFruit* Fruit = new TFruit();
        if (Fruit)
        {
            Fruits.push_back(Fruit);
        }
    }

    TilesPerRow = GameObject.WindowWidth / TileSize;
    TilesPerHeight = GameObject.WindowHeight / TileSize;
    MaxPosX = TilesPerRow - 1;
    MaxPosY = TilesPerHeight - 1;

    WorldMap.reserve(TilesPerRow * TilesPerHeight);
    for (int i = 0; i < TilesPerRow * TilesPerHeight; ++i)
    {
        WorldMap.emplace_back(static_cast<int>(SDL_randf() * 3.999));
    }
}

TWorld::~TWorld()
{
    for (int i = 0; i < Fruits.size(); ++i)
    {
        if (TFruit* Fruit = Fruits[i])
        {
            delete Fruit;
            Fruit = nullptr;
        }
    }
    if (Snake)
    {
        delete Snake;
        Snake = nullptr;
    }
}

void TWorld::Update(float DeltaTime)
{
    Snake->Update(DeltaTime);
}

void TWorld::Render(SDL_Renderer* Renderer)
{
    for (int x = 0; x < TilesPerRow; ++x)
    {
        for (int y = 0; y < TilesPerHeight; ++y)
        {
            SDL_FRect GroundSourceRect = GroundRects[WorldMap[x*y]];
            SDL_FRect GroundDestinationRect{
                static_cast<float>(x * TileSize),
                static_cast<float>(y * TileSize),
                static_cast<float>(TileSize),
                static_cast<float>(TileSize)
            };
            SDL_RenderTexture(Renderer, GameObject.TileMap, &GroundSourceRect, &GroundDestinationRect);
        }
    }

    for (int i = 0; i < Fruits.size(); ++i)
    {
        Fruits[i]->Render(Renderer);
    }
    Snake->Render(Renderer);
}

TFruit* TWorld::GetFruitAtPosition(int X, int Y)
{
    for (int i = 0; i < Fruits.size(); ++i)
    {
        if (Fruits[i]->IsOccupiedByFruit(X, Y))
        {
            return Fruits[i];
        }
    }
    return nullptr;
}

bool TWorld::IsFieldAvaialable(int X, int Y)
{
    if (Snake->IsOccupiedBySegment(X, Y)) return false;
    if (GetFruitAtPosition(X, Y)) return false;
    return true;
}

void TWorld::Reset()
{
    for (int i = 0; i < Fruits.size(); ++i)
    {
        Fruits[i]->SetRandomPosition();
    }
}
