#include "DangerousRacers/Obstacles/ObstacleManager.h"
#include <iostream>

ObstacleManager::ObstacleManager(float& sceneSpeed) : sceneSpeed(sceneSpeed) {

}

void ObstacleManager::reset() {
    obstacles.clear();
}

void ObstacleManager::render(sf::RenderWindow &window) {
    for (const auto& obstacle : obstacles) {
        obstacle->render(window);
    }
}

void ObstacleManager::update(const float deltaTime) {
    for (auto obstacleIterator = obstacles.begin(); obstacleIterator != obstacles.end();) {
        (*obstacleIterator)->update(deltaTime);

        if ((*obstacleIterator)->outOfBounds()) {
            obstacleIterator = obstacles.erase(obstacleIterator);
        } else {
            ++obstacleIterator;
        }
    }

    if (!allowRandomSpawn) return;
    spawnTimer -= deltaTime;

    if (spawnTimer > 0.f) return;

    spawnObstacle(32 + rand() % (405-64), -32.f, static_cast<Obstacle::ObstacleType>((rand() % 2) + (rand() % 2 >= 1 ? 2 : 0)));
    spawnTimer = rand() % 2 + 1;
}

void ObstacleManager::spawnObstacle(const float x, const float y, const Obstacle::ObstacleType type) {

    std::string texturePath;

    switch (type) {
        case Obstacle::WALL:
            texturePath = "assets/Obstacles/Wall.png";
            break;
        case Obstacle::CONE:
            texturePath = "assets/Obstacles/traffic_cone.png";
            break;
        case Obstacle::FUEL:
            texturePath = "assets/Obstacles/fuel.png";
            break;
        case Obstacle::REPAIR:
            texturePath = "assets/Obstacles/repair.png";
            break;
        default:
            break;
    }

    obstacles.push_back(std::make_unique<Obstacle>(x, y, sceneSpeed, texturePath, type));
}

ObstacleManager::CollisionType ObstacleManager::obstacleCollides(const sf::FloatRect &collisionObject) {
    for (auto obstacleIterator = obstacles.begin(); obstacleIterator != obstacles.end();) {
        if ((*obstacleIterator)->getYBottom() < collisionObject.top) return NONE; // If obstacle is above collision object, skip all.
        if ((*obstacleIterator)->getSprite().getGlobalBounds().intersects(collisionObject)) {
            switch ((*obstacleIterator)->type) {
                case Obstacle::ObstacleType::FUEL:
                    obstacles.erase(obstacleIterator);
                    return PICKUP_FUEL;
                case Obstacle::ObstacleType::REPAIR:
                    obstacles.erase(obstacleIterator);
                    return PICKUP_HEALTH;
                default:
                    return DAMAGE;
            }
        }

        ++obstacleIterator;
    }

    return NONE;
}