#include "renderer_polygon_2d.hpp"

namespace endofthejedi {
    void RendererPolygon2d::setup()
    {
        // (dark grey) bg
        float r = 0.1;
        float g = 0.1;
        float b = 0.1;
        glClearColor(r, g, b, 1.0);
    }

    void RendererPolygon2d::drawCircle(float x, float y, float radius,
                                                  float r, float g, float b,
                                                  int numSides) {
        glBegin(GL_TRIANGLE_FAN);
        glColor3f(r, g, b);
        glVertex2f(x, y); // center of circle
        for (int i = 0; i <= numSides; i++) {
            glVertex2f(x + (radius * cos(i * 2 * M_PI / numSides)),
                       y + (radius * sin(i * 2 * M_PI / numSides)));
        }
        glEnd();
    }

    void RendererPolygon2d::drawShip(const glm::vec2 &pos,
                                                float radius) {
        // std::cout<<"draw ship @ " << pos.x << ", " << pos.y << std::endl;
        glm::vec3 color = glm::vec3(0.2, 1.0, 0.3);

        drawCircle(pos.x, pos.y, radius, color.x, color.y, color.z, 12);
    }

    void RendererPolygon2d::drawPlanet(const glm::vec2 &pos,
                                                  float radius) {
        glm::vec3 color = glm::vec3(0.7, 0.1, 0.2);

        // std::cout<<"draw planet @ " << pos.x << ", " << pos.y << std::endl;
        drawCircle(pos.x, pos.y, radius, color.x, color.y, color.z, 32);
    }

    void RendererPolygon2d::drawMissile(const glm::vec2 &pos) {
        glm::vec3 color = glm::vec3(1.0, 1.0, 0.3);
        drawCircle(pos.x, pos.y, 0.01, color.x, color.y, color.z, 6);
    }

    void RendererPolygon2d::drawTrace(const game::Trace *trace) {
        for (const game::Trace::TracePoint &p : trace->points) {
            glm::vec3 color = glm::vec3(0.1, 0.3, 1.0) / (1.0f + 500.0f * p.speed);
            drawCircle(p.position.x, p.position.y, 0.005, color.x, color.y, color.z,
                       3);
        }
    }

    void RendererPolygon2d::drawExplosion(
        const game::Explosion *explosion) {
        // TODO: transparent
        // TODO: with glow in the middle
        float r = explosion->maxRadius * (explosion->age / explosion->maxAge);

        // TODO: transparency?
        glm::vec3 color = glm::vec3(1.0, 0.9, 0.1);
        drawCircle(explosion->position.x, explosion->position.y, r, color.x,
                   color.y, color.z, 64);
    }

    void RendererPolygon2d::render(const game::State *state) {
        for (const game::Planet *planet : state->planets) {
            drawPlanet(planet->position, planet->radius);
        }

        for (const game::Trace *trace : state->traces) {
            drawTrace(trace);
        }

        for (const game::Explosion *explosion : state->explosions) {
            drawExplosion(explosion);
        }

        for (const game::Ship *ship : state->ships) {
            drawShip(ship->position, ship->radius);
        }

        for (const game::Player *player : state->players) {
            for (const game::Missile *missile : player->missiles) {
                drawMissile(missile->position);
            }
        }
    }
}
