#include "Level.h"
#include "BulletManager.h"
#include "ShaderManager.h"

Level::Level(string filename)
{
	BulletManager::getInstance()->clearDynamicsWorld();
	ifstream levelFile(filename.c_str());
	if (levelFile.is_open())
	{
		string line;
		int nLineNum = 0;
		getline(levelFile, line);
		stringstream linestream(line);
		int mapHeight;
		linestream >> mapHeight;
		for (int nLineNum = 0; nLineNum < mapHeight; nLineNum++)
		{
			getline(levelFile, line);
			vector<int> mapVector;
			vector<Actor *> actorVector;
			for (int i=0; i<line.length(); i++)
			{
				char cNumber = line[i];
				int nNumber = atoi(&cNumber);
				mapVector.push_back(nNumber);
				switch (nNumber)
				{
					case 0:
					{
						Actor *boxActor = new Actor("Cube");
						boxActor->setTranslate(BOX_SIZE*i, BOX_SIZE/2.0, BOX_SIZE*nLineNum);
						boxActor->setScale(BOX_SIZE/2.0, BOX_SIZE/2.0, BOX_SIZE/2.0);
						actorVector.push_back(boxActor);
						PhysicsShape *physics = new PhysicsShape(BOX);
						physics->setTranslate(BOX_SIZE*i, BOX_SIZE/2.0, BOX_SIZE*nLineNum);
						physics->setScale(BOX_SIZE/2.0, BOX_SIZE/2.0, BOX_SIZE/2.0);
						BulletManager::getInstance()->addPhysicsShape(physics);
						break;
					}
					case 1:
						actorVector.push_back(0);
						break;
				}
			}
			levelMap.push_back(mapVector);
			levelActors.push_back(actorVector);
		}
		
		getline(levelFile, line);
		stringstream posStream(line);
		posStream >> nStartPosX >> nStartPosZ;

		getline(levelFile, line);
		stringstream endPosStream(line);
		endPosStream >> nEndPosX >> nEndPosZ;

		levelFile.close();
	}

	int nHeight = levelActors.size();
	int nWidth = levelActors[0].size();
	PhysicsShape *floor = new PhysicsShape(BOX);
	floor->setTranslate(0,-1.0f,0);
	floor->setScale(nWidth * BOX_SIZE * 1.0f,1.0,nHeight * BOX_SIZE * 1.0f);
	BulletManager::getInstance()->addPhysicsShape(floor);
}

void Level::initCamera(Camera *camera)
{
	camera->setPosition((nStartPosX-1)*BOX_SIZE, 1.8, (nStartPosZ-1)*BOX_SIZE);
}

void Level::drawLevel(string shader)
{
	GLSLProgram *glslProgram = ShaderManager::getInstance()->getShader("GBuffer");

	for (int i=0; i<levelActors.size(); i++)
	{
		vector<Actor *> actorVector = levelActors[i];
		for (int j=0; j<actorVector.size(); j++)
		{
			if (actorVector[j] != 0)
			{
				actorVector[j]->drawActor(shader);
			}
		}
	}

	glslProgram->sendUniform("color", 1.0f, 1.0f, 1.0f);

	int nHeight = levelActors.size();
	int nWidth = levelActors[0].size();
	Actor floorActor("Cube");
	floorActor.setTranslate(0,-1.0f,0);
	floorActor.setScale(nWidth * BOX_SIZE * 1.0f,1.0,nHeight * BOX_SIZE * 1.0f);
	floorActor.drawActor(shader);
	floorActor.setTranslate(0,BOX_SIZE+1.0f,0);
	floorActor.drawActor(shader);

	Actor endActor("Sphere");
	endActor.setTranslate(BOX_SIZE*(nEndPosX-1), BOX_SIZE/2.0, BOX_SIZE*(nEndPosZ-1));
	endActor.setScale(BOX_SIZE/3.0, BOX_SIZE/3.0, BOX_SIZE/3.0);
	endActor.drawActor(shader);
}

Vector3 Level::getEndPos()
{
	return Vector3(BOX_SIZE*(nEndPosX-1), BOX_SIZE/2.0, BOX_SIZE*(nEndPosZ-1));
}