#include "Salamander.h"
#include "GameManager.h"

#include "ButtonDownEvent.h"
#include "ButtonUpEvent.h"
#include "Camera.h"
#include "CameraEvent.h"
#include "Character.h"
#include "Effect.h"
#include "Line.h"
#include "Obstacle.h"
#include "Polygon.h"
#include "Platform.h"
#include "SDLHack.h"
#include "World.h"

defineUniqueId(GameManager);
GameManager::GameManager()
{
	
}

GameManager::~GameManager()
{

}

bool GameManager::startup()
{
	// Title
	SDLHack sdlHack; sdlHack.setCaption("The Sky Is Falling");

	// Random stuff should be random
	srand((int)time(NULL));

	// Physics!
	world_ = new World();
	world_->gravity_ = Vec2(0.0, 0.0);

	// Character
	Character* character = new Character();
	character->setTranslation(Vec2(-180, -160));
	world_->addBody(character);

	// Start on something reasonably solid
	Platform* platform = new Platform("building1_start1_1024.txt");
	platform->setTranslation(Vec2(0, 0));
	platform->setMass(0.0);
	platform->resetPhysics();
	platform->setRotation(0.0);
	world_->addBody(platform);

	// The rest of the platforms
	std::string filename;
	std::ifstream file ("..\\data\\platforms.txt");
	while(file.good())
	{
		std::getline(file, filename);
		platformnames_.push_back(filename);
	}
	file.close();

	// TEMP
	unsigned int i = 2;
	for(; i < 20; i++)
	{
		Platform* platform = new Platform(platformnames_[rand() % platformnames_.size()]);
		platform->setTranslation(Vec2(i * 500, 0.0));
		if(i < 3) platform->setMass(0.0);
		world_->addBody(platform);
	}

	// Finish on something reasonably solid
	platform = new Platform("building1_end1_1024.txt");
	platform->setTranslation(Vec2(i * 500 + 500, 0));
	platform->setMass(0.0);
	platform->resetPhysics();
	platform->setRotation(0.0);
	world_->addBody(platform);

	// Load Obstacles
	std::ifstream obstacles("..\\data\\obstacles.txt");
	while(obstacles.good())
	{
		std::getline(obstacles, filename);

		Obstacle* obstacle = new Obstacle(filename);
		obstacle->setTranslation(Vec2(rand() % 1000, 0.0));
		world_->addBody(obstacle);
	}
	obstacles.close();

	// Foreground
	generateRain();
	generateForeground();

	// Camera
	camera_ = new Camera(*character);

	// don't need this?
	events().receive<GameManager, ButtonEvent>(this, &GameManager::onButtonEvent);

	// to spawn new platforms etc
	events().receive<GameManager, CameraEvent>(this, &GameManager::onCameraEvent);

	return true;
}

// should be in a foreground manager
void GameManager::generateForeground()
{
	// load graphics
	std::string filename;
	std::ifstream foreground("..\\data\\foreground.txt");
	while(foreground.good())
	{
		std::getline(foreground, filename);
		Effect* effect = new Effect(Effect::FOREGROUND);
		effect->setScale(Vec2(128.0, 128.0) * 3.0);
		effect->setTexture(asset().load<Texture>("..\\data\\" + filename));
		scene().addChild(*effect);
	}
	foreground.close();
}

// should be in a foreground manager
void GameManager::generateRain()
{
	// load graphics
	for(unsigned int i = 0; i < 40; i++)
	{
		Effect* effect = new Effect(Effect::RAIN);
		effect->setScale(Vec2(256.0, 256.0) * (rand() % 100 + 10) * 0.01);		
		effect->setTexture(asset().load<Texture>("..\\data\\rain.png"));
		scene().addChild(*effect);
	}
}

bool GameManager::shutdown()
{
	// our own stuff
	if(world_)
	{
		delete world_;
		world_ = NULL;
	}
    
	return true;
}

void GameManager::frame()
{
	world_->timeStep(application().delta());
	camera_->update();
}

void GameManager::onButtonEvent(const ButtonEvent& event)
{
	//nothing?
}

void GameManager::onCameraEvent(const CameraEvent& event)
{
	// spawn new platforms!


	// check the borders

}