void GameState_BasePlayable::LoadLevel (std::string levelPath) {
	Nav->SetNavMap(0);
	ClearMap();
	objectives[0] = 0;
	objectives[1] = 0;

	GOOGLE_PROTOBUF_VERIFY_VERSION;

	std::fstream levelFile(levelPath.c_str(), std::ios::in | std::ios::binary);
	if (!levelFile.is_open()) {
//std::cout << "!levelFile.is_open()" << std::endl;
		OnLevelLoaded(false);
		return;
	}

	Level level;

	if (!level.ParseFromIstream(&levelFile)) {
//std::cout << "!level.ParseFromIstream(&levelFile)" << std::endl;
		google::protobuf::ShutdownProtobufLibrary();
		OnLevelLoaded(false);
		return;
	}

	// LOAD DATA ===
	this->levelName = level.levelname();

	SetLevelSize(sf::Vector2f(level.levelsize().x(), level.levelsize().y()));

	for (int itG = 0; itG != level.guards_size(); itG++) {
		Level_Guard* plGuard =  level.mutable_guards(itG);

		Guard* newGuard = new Guard(this, LAYER_GUARD);
		AddWorldSpace(newGuard);
		newGuard->SetPosition(sf::Vector2f(plGuard->mutable_pos()->x(), plGuard->mutable_pos()->y()));

		for (int itWP = 0; itWP != plGuard->waypoints_size(); itWP++) {
			newGuard->WPushBack(new sf::Vector2i(plGuard->mutable_waypoints(itWP)->x(),
												plGuard->mutable_waypoints(itWP)->y()));
		}
	}

	// all the simple WorldObj stuff
	for (int itS = 0; itS != level.stuff_size(); itS++) {
		Level_WorldObj* plStuff = level.mutable_stuff(itS);
		WorldDrawable* newGO = 0;
		switch (plStuff->type()) {
			case Level_WorldObjType_ROCKWALL:
				newGO = new WallRectangle(TEXTURE_ROCKWALL, Collision::STATIC, LAYER_ROCKWALL, ID_ROCKWALL);
			break;
			case Level_WorldObjType_ROCK01:
				newGO = new WallRectangle(TEXTURE_ROCK01, Collision::STATIC, LAYER_ROCK01, ID_ROCK01);
			break;
			case Level_WorldObjType_ROCK02:
				newGO = new WallRectangle(TEXTURE_ROCK02, Collision::STATIC, LAYER_ROCK02, ID_ROCK02);
			break;
			case Level_WorldObjType_BUSH:
				newGO = new WallCircle(TEXTURE_BUSH, Collision::STATIC, LAYER_BUSH, ID_BUSH);
			break;
			case Level_WorldObjType_PINE:
				newGO = new WallCircle(TEXTURE_PINE, Collision::STATIC, LAYER_PINE, ID_PINE);
			break;
			case Level_WorldObjType_ROOF:
				newGO = new WallRectangle(TEXTURE_ROOF, Collision::STATIC, LAYER_ROOF, ID_ROOF);
			break;
			case Level_WorldObjType_ROAD:
				newGO = new WorldSprite(TEXTURE_ROAD, LAYER_ROAD, ID_ROAD);
			break;
			case Level_WorldObjType_PLAYER:
				newGO = new Player(this, LAYER_PLAYER);
				player = dynamic_cast<Player*>(newGO);
			break;
			case Level_WorldObjType_PRINCESS:
				newGO = new Princess(this, LAYER_PRINCESS);
				princess = dynamic_cast<Princess*>(newGO);
			break;
			case Level_WorldObjType_COIN:
				newGO = new Coin(LAYER_COIN);
			break;
			case Level_WorldObjType_CHEST:
				newGO = new Chest(LAYER_CHEST);
				chest = dynamic_cast<Chest*>(newGO);
			break;
			case Level_WorldObjType_GOAL:
				newGO = new Goal(LAYER_GOAL);
//				goal = dynamic_cast<Goal*>(newGO);
			break;
		}
		AddWorldSpace(newGO);
		newGO->SetPosition(sf::Vector2f(plStuff->mutable_pos()->x(), plStuff->mutable_pos()->y()));
	}

	if (level.has_mission1st()) {
		Level_WorldObj* plStuff = level.mutable_mission1st();
		sf::Vector2f posMission(plStuff->mutable_pos()->x(), plStuff->mutable_pos()->y());

		switch (level.mutable_mission1st()->type()) {
			case Level_WorldObjType_CHEST:
				objectives[0] = chest;
			break;
			case Level_WorldObjType_PRINCESS:
				objectives[0] = princess;
			break;
			case Level_WorldObjType_GOAL: {
				const EntityMap& entities = GameObjects->GetEntityMap(ID_GOAL);
				GameObject* GO = entities.begin()->second;
				for (EntityMap::const_iterator itE = ++entities.begin(); itE != entities.end(); ++itE) {
					if ( Utils->Dst(posMission, itE->second->GetPosition()) < Utils->Dst(GO->GetPosition(), itE->second->GetPosition()) ) {
						GO = itE->second;
					}
				}

				objectives[0] = dynamic_cast<BaseObjective*>(GO);
			} break;
			default: break;
		}
	}
	if (level.has_mission2nd()) {
		Level_WorldObj* plStuff = level.mutable_mission2nd();
		sf::Vector2f posMission(plStuff->mutable_pos()->x(), plStuff->mutable_pos()->y());

		switch (level.mutable_mission2nd()->type()) {
			case Level_WorldObjType_CHEST:
				objectives[1] = chest;
			break;
			case Level_WorldObjType_PRINCESS:
				objectives[1] = princess;
			break;
			case Level_WorldObjType_GOAL: {
				const EntityMap& entities = GameObjects->GetEntityMap(ID_GOAL);
				GameObject* GO = entities.begin()->second;
				for (EntityMap::const_iterator itE = ++entities.begin(); itE != entities.end(); ++itE) {
					if ( Utils->Dst(posMission, itE->second->GetPosition()) < Utils->Dst(GO->GetPosition(), itE->second->GetPosition()) ) {
						GO = itE->second;
					}
				}

				objectives[1] = dynamic_cast<BaseObjective*>(GO);
			} break;
			default: break;
		}
	}

//	development_level = level.usercreated();

	int navmapnodes_size = level.navmapnodes_size();
	if (navmapnodes_size > 0) {
		NavMap* navMap = new NavMap();

		for (int i = 0; i != navmapnodes_size; ++i) {
			const Level_NavMapNode& ilN = level.navmapnodes(i);

			sf::Vector2i iNPos(ilN.position().x(), ilN.position().y());

			std::deque<sf::Vector2i> iNAdjacents;

			int adjacentpositions_size = ilN.adjacentpositions_size();
			if (adjacentpositions_size > 0) {
				for (int j = 0; j != adjacentpositions_size; ++j) {
					iNAdjacents.push_back(
						sf::Vector2i(ilN.adjacentpositions(j).x(), ilN.adjacentpositions(j).y()));
				}
			}

			navMap->insert( std::pair< sf::Vector2i, std::deque<sf::Vector2i> >(iNPos, iNAdjacents) );
		}

		Nav->SetNavMap(navMap);
	}
	// === LOAD DATA

	google::protobuf::ShutdownProtobufLibrary();

	SortAscendingWorld();

	OnLevelLoaded(true);
}