#include <iostream>
#include <ostream>
#include <DangerousRacers/DrawableEntity.h>

#include "SFML/Graphics/Texture.hpp"

DrawableEntity::DrawableEntity(const float x, const float y, const std::string &texturePath) {
    loadTexture(texturePath);
    this->_setPosition(x, y);
}

void DrawableEntity::loadTexture(const std::string &texturePath) {
    if (texturePath.empty() || !texture.loadFromFile(texturePath)) {
        std::cerr << "Failed to load texture: " << texturePath << std::endl;
    }

    texture.setSmooth(false);
    sprite.setTexture(texture);
}

void DrawableEntity::_setPosition(const float x, const float y) {
    startPosition = position;
    targetPosition = sf::Vector2f(x, y);
    position = targetPosition;
    moveDuration = 0;
    moveElapsed = 0.f;
    moving = false;
    sprite.setPosition(position);
}

sf::Sprite& DrawableEntity::getSprite() {
    return sprite;
}

void DrawableEntity::moveTo(const float x, const float y, const float timeToMove) {
    startPosition = position;
    targetPosition = sf::Vector2f(x, y);
    moveDuration = timeToMove;
    moveElapsed = 0.f;
    moving = timeToMove > 0.f;

    if (!moving) {
        position = targetPosition;
        sprite.setPosition(position);
    };
}

void DrawableEntity::_setTexture(const sf::Texture &_texture) {
    texture = _texture;
    sprite.setTexture(texture, true);
}

sf::Vector2i DrawableEntity::getRelativePosition() const {
    return {static_cast<int>(targetPosition.x) / 64, static_cast<int>(targetPosition.y) / 64};
}

bool DrawableEntity::isMoving() const {
    return moving;
}

void DrawableEntity::render(sf::RenderWindow &window) {
    window.draw(sprite);
}

void DrawableEntity::update(const float deltaTime) {
    if (!moving) return;

    moveElapsed += deltaTime;
    float t = moveElapsed / moveDuration;

    if (t >= 1.f) {
        t = 1.f;
        moving = false;
    }

    position = startPosition + (targetPosition - startPosition) * t;
    sprite.setPosition(position);
}

int DrawableEntity::getHeight() const {
    return static_cast<int>(sprite.getGlobalBounds().height / sprite.getScale().y);
}
