#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <cmath>

#include "bonus.hpp"
#include "arkanoid.hpp"

const double pi = 3.14159265358979323846;

Bonus::Bonus(sf::Vector2f position): m_position(position)
{
    m_time = 0;
}

// Двигаем бонус
void Bonus::update(float dt)
{
    m_time += dt;
    m_position.y += speed * dt;
}

// Рисуем бонус
void Bonus::draw(sf::RenderWindow& window) const
{
    // Рисуем белый круг
    static sf::CircleShape shape(radius);
    shape.setOrigin(radius, radius);
    shape.setFillColor(sf::Color{100, 200, 100});
    shape.setPosition(m_position);
    window.draw(shape);

    float angle = 0;
    // Рисуем 3 шарика на этом круге
    static Ball ball {5, {0, 0}, {0, 0}};
    float ballRotationRadius = 7;
    ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
    ball.draw(window);
    angle += 2.0 * pi / 3.0;
    ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
    ball.draw(window);
    angle += 2.0 * pi / 3.0;
    ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
    ball.draw(window);
}


/*
    Функция Bonus::activate

    Применяем эффект бонуса (в данном случае - утроение шариков)
    numBalls - Количество шариков до утроения
    Шарики хранятся в связном списке m_balls
    Так как мы работаем со связным списком, то придётся использовать итератор it

    Проходим итератором по изначальным элементам списка и добавляем новые шарики в список
    В данном случае простой цикл через итераторы не сработает, так как массив game.m_balls увеличивается в процессе выполнения цикла.

    Внутри цикла выбираем случайный вектор скорости и добавляем шарик в список game.m_balls
    Делаем то же самое для ещё одного шарика
    В конце цикла переходим ко следующему шарику в списке, т.е. увеличивем итератор it

*/
void Bonus::activate(Arkanoid& game)
{
    int numBalls = game.m_balls.size();
    std::list<Ball>::iterator it = game.m_balls.begin();

    for (int i = 0; i < numBalls; i++)
    {
        float angle = rand() % 1000 * (2 * pi / 1000);
        float vx = Ball::initialVelocity * sin(angle);
        float vy = Ball::initialVelocity * cos(angle);
        game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}});

        angle = rand() % 1000 * (2 * pi / 1000);
        vx = Ball::initialVelocity * sin(angle);
        vy = Ball::initialVelocity * cos(angle);
        game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}});

        it++;
    }
}

bool Bonus::isColiding(const Paddle& paddle) const
{
    bool result = paddle.getBorder().intersects({m_position.x - radius, m_position.y - radius, 2 * radius, 2 * radius});
    return result;
}