#pragma once

#include "opengl.hpp"
#include "renderer.hpp"

#include "renderer_polygon_2d/renderer_polygon_2d.hpp"
#include "renderer_polygon_3d/renderer_polygon_3d.hpp"
#include "renderer_ray_tracer/renderer_ray_tracer.hpp"

#include "game.hpp"

#include "state/trace.hpp"
#include "state/object.hpp"
#include "state/missile.hpp"
#include "state/player.hpp"
#include "state/planet.hpp"
#include "state/ship.hpp"
#include "state/explosion.hpp"

class GameWindow : public endofthejedi::GLWindow {
  private:
    Game* m_game;
    //endofthejedi::RendererPolygon2d m_renderer;
    endofthejedi::RendererPolygon3d m_renderer;
    //endofthejedi::RendererRayTracer m_renderer;

  protected:
    void init() override {
        glClearColor(0.5f, 0.6f, 0.7f, 1.0f);
        resize();


        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_DEPTH_TEST);
        glEnable( GL_BLEND );
        glEnable(GL_ALPHA_TEST);

        m_renderer.setup();
    }

    void render(double time) override {
        if (!m_game->cycle(static_cast<float>(time / 1000000000.0))) {
            std::cout << "stopping the game..." << std::endl;
            stop();
        }

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        m_renderer.render(m_game->state());
    }

    void resize() override
    {
        std::cout<<"resize()" << std::endl;

        glViewport(0, 0, getwidth(), getheight());

        // resize the game
        m_game->resize(getwidth(), getheight());

        // TODO: mark it and let the reinit() happen in the next so it happnens just once. while doing the resize
        m_game->state()->init();

        // resize the renderer
        m_renderer.setWindowSize(getwidth(), getheight());
    }

  public:
    GameWindow(unsigned int width, unsigned int height, Game *ptr)
        : endofthejedi::GLWindow(width, height) {
        m_game = ptr;
    }
};
