#include "GameScreen.h"
#include "../entities/components/Position.h"
#include "../entities/components/Direction.h"
#include "../entities/components/Renderable.h"
#include "../entities/MovementSystem.h"
#include "../entities/RenderSystem.h"

#include <SDL.h>

#include <iostream>

GameScreen::GameScreen(Renderer *renderer, Assets *assets)
{
	std::cout << "GameScreen got created!" << std::endl;
	this->renderer = renderer;
	this->assets = assets;

	//Vertex2D can be defined like this, because it an aggregate class.
	// see https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special
	std::vector<Vertex2D> vertices({Vertex2D{glm::vec2(-0.5f, -0.5f), glm::vec2(0.0f, 1.0f)},
									Vertex2D{glm::vec2(0.5f, -0.5f), glm::vec2(1.0f, 1.0f)},
									Vertex2D{glm::vec2(0.5f, 0.5f), glm::vec2(1.0f, 0.0f)},
									Vertex2D{glm::vec2(-0.5f, 0.5f), glm::vec2(0.0f, 0.0f)}});

	std::vector<unsigned int> indices({0, 1, 3,
									   1, 2, 3});

	obj = new Mesh(vertices, indices, assets->getTexture("police_officer"));

	inputHandler = new InputHandler();
	camera = new OrtographicCamera();

	//Create Entities
	entityx::Entity charakter = ex.entities.create();
	charakter.assign<Position>();
	charakter.assign<Direction>(1.f,0.f); //apply speed right
	charakter.assign<Renderable>(obj, "defaultShader");

	ex.systems.add<MovementSystem>();
	ex.systems.add<RenderSystem>(renderer,camera,assets);
	ex.systems.configure();
	
}

GameScreen::~GameScreen()
{
	delete camera;
	delete obj;
	delete inputHandler;
}

void GameScreen::hide()
{
}

void GameScreen::pause()
{
}

void GameScreen::render(unsigned int delta)
{
	double dt = ((double) delta) * 0.001; //(10^-3) milli
	ex.systems.update<RenderSystem>(dt);
	/*//Drawing
	Shader defaultShader = assets->getShader("defaultShader");
	defaultShader.SetMatrix4("MVP", camera->getCombinedMatrix(), true);
	//Draw Mesh
	renderer->draw(*obj, defaultShader);*/
}

void GameScreen::update(unsigned int delta)
{
	SDL_Event event;
	while (SDL_PollEvent(&event) != 0)
	{
		Command *command = inputHandler->handleInput(&event);
		if (command)
		{
			command->execute(*camera);
		}
	}
	double dt = ((double) delta) * 0.001; //(10^-3) milli
	ex.systems.update<MovementSystem>(dt);
}

void GameScreen::resize()
{
}

void GameScreen::resume()
{
}

void GameScreen::show()
{
}
