#pragma once

#include "core/script.hpp"
#include "geometry/general.hpp"
#include "geometry/paddle.hpp"

#include "bounce_script.hpp"
#include "constants.hpp"

#include "utils/debug.hpp"


struct paddle_script : frog::script
{
    bounce_script* bounce = nullptr;
    bool ball_magnet = false;

    paddle_script(bool ball_magnet = false)
        : ball_magnet(ball_magnet) {}

    void init(frog::game_object& object, frog::engine&) override
    {
        using namespace frog;

        bounce = object.get_script<bounce_script>();
    }

    void stable_update(frog::game_object& object, frog::engine& engine) override
    {
        using namespace frog;

        double time = engine.global->stable_frame_time();

        float sign = 0;

        if (engine.input->is_down(os::key{ GLFW_KEY_D }))
        {
            sign = -1;
        }
        if (engine.input->is_down(os::key{ GLFW_KEY_A }))
        {
            sign = 1;
        }

        bounce->move(object, sign * Paddle::Speed * geo::ToRad * time);

        magnetize(engine);
    }

    void magnetize(frog::engine& engine)
    {
        using namespace frog;

        if (!ball_magnet)
            return;

        bool release = engine.input->is_released(os::key{ GLFW_KEY_SPACE });

        engine.scenes->current().for_each_object(frog::by_tag("ball"),
            [&](auto& ball)
            {
                auto b_script = ball.get_script<ball_script>();

                geo::vec2 pos = geo::to_cartesian(
                    geo::polar2{
                        bounce->paddle.pos.r - Ball::Radius - geo::Epsilon,
                        bounce->paddle.pos.theta + bounce->paddle.angular_size / 2 });

               ball.model().pos.x() = pos.x();
               ball.model().pos.z() = pos.y();

                if (release)
                {
                    ball_magnet = false;
                    b_script->shoot({ -pos.x(), 0, -pos.y() });
                }
            });
    }
};
