/*!
* @file GameWorld.cpp
* @brief ゲーム世界を定義する
* @date 2013/12/22
* @author Deskull
* 2013 Sikabane Works.
*/

#include "stdafx.h"
#include "GameWorld.h"
#include "Deeangband.h"

#include "Coordinates.h"
#include "HaveGameTime.h"

#include "Air.h"
#include "Ability.h"
#include "Authority.h"
#include "Building.h"
#include "Camp.h"
#include "CreatureTrait.h"

#include "Creature.h"
#include "Dungeon.h"
#include "Effect.h"
#include "Floor.h"

#include "HaveGameTime.h"

#include "FixedArtifact.h"
#include "GameMessage.h"
#include "ItemBase.h"
#include "ItemEgo.h"
#include "ItemTrait.h"
#include "Karma.h"
#include "Lore.h"
#include "Quest.h"
#include "Race.h"
#include "Space.h"
#include "Skill.h"
#include "Species.h"
#include "StartingClass.h"
#include "TrapBase.h"

#include "Item.h"
#include "Field.h"
#include "Trap.h"

namespace Deeangband
{

	GameWorld::GameWorld(void)
	{
		XMLLoad();

		this->itemID = 0;
		this->trapID = 0;
		this->creatureID = 0;
		this->fieldID = 0;
		this->gameTime = 0;

	}

	void GameWorld::Initialize(void)
	{
		int i;
		std::map<ID, boost::shared_ptr<Field>>::iterator fieldIt;
		std::map<TAG, boost::shared_ptr<Species>>::iterator speciesIt;
		fieldList.emplace(0, boost::make_shared<Field>(dungeonList.find("VANILLA_WOMB"), 1));
		fieldIt = fieldList.find(0);

		speciesIt = speciesList.find("VANILLA_STIGMATIC");
		GameWorld::GenerateCreature(speciesIt, fieldIt, 10, 10);

		speciesIt = speciesList.find("VANILLA_RAVING_LUNATIC");
		GameWorld::GenerateCreature(speciesIt, fieldIt, 5, 5);

		for(i = 0; i < MAX_KARMAS; i++)
		{
			karmaList.emplace("VANILLA_", boost::make_shared<Karma>());
		}
		playerIt = creatureList.begin()++;
	}


	GameWorld::~GameWorld(void)
	{
	}

	bool GameWorld::GenerateCreature(std::map<TAG, boost::shared_ptr<Species>>::iterator& speciesIt)
	{
		creatureList.emplace(this->creatureID, boost::make_shared<Creature>(speciesIt));
		do
		{
			this->creatureID++;
		} while(creatureList.find(this->creatureID) != creatureList.end());
		return true;
	}

	bool GameWorld::GenerateCreature(std::map<TAG, boost::shared_ptr<Species>>::iterator& speciesIt, std::map<ID, boost::shared_ptr<Field>>::iterator& fieldIt, MAP_LENGTH x, MAP_LENGTH y)
	{
		std::map<ID, boost::shared_ptr<Creature>>::iterator creatureIt;
		HaveGameTime *test;
		creatureList.emplace(this->creatureID, boost::make_shared<Creature>(speciesIt, fieldIt, x, y));
		creatureIt = creatureList.find(this->creatureID);
		creatureIt->second->PlusWait(100, TRUE);
		creatureIt->second->UpdateFieldLore();
		actionList2.push_back(creatureIt->second.get());
		test = creatureIt->second.get();
		//actionList3.push_back(test);
		do
		{
			this->creatureID++;
		} while(creatureList.find(this->creatureID) != creatureList.end());
		return true;
	}

	bool GameWorld::xmlSaveAir(void)
	{
		std::ofstream ofs("lib-Vanilla\\Air.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Airs", this->airList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveAbility(void)
	{
		std::ofstream ofs("lib-Vanilla\\Ability.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Abilities", this->abilityList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveAuthority(void)
	{
		std::ofstream ofs("lib-Vanilla\\Authority.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Authorities", this->authorityList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveBuilding(void)
	{
		std::ofstream ofs("lib-Vanilla\\Building.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Buildings", this->buildingList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveCamp(void)
	{
		std::ofstream ofs("lib-Vanilla\\Camp.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Camps", this->campList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveCreatureTrait(void)
	{
		std::ofstream ofs("lib-Vanilla\\CreatureTrait.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("CreatureTraits", this->creatureTraitList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveDungeon(void)
	{
		std::ofstream ofs("lib-Vanilla\\Dungeon.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Dungeons", this->dungeonList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveEffect(void)
	{
		std::ofstream ofs("lib-Vanilla\\Effect.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Effects", this->effectList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveFloor(void)
	{
		std::ofstream ofs("lib-Vanilla\\Floor.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Floors", this->floorList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveFixedArtifact(void)
	{
		std::ofstream ofs("lib-Vanilla\\FixedArtifact.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("FixedArtifacts", this->fixedArtifactList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveItemBase(void)
	{
		std::ofstream ofs("lib-Vanilla\\ItemBase.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("ItemBases", this->itemBaseList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveItemEgo(void)
	{
		std::ofstream ofs("lib-Vanilla\\ItemEgo.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("ItemEgos", this->itemEgoList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveItemTrait(void)
	{
		std::ofstream ofs("lib-Vanilla\\ItemTrait.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("ItemTraits", this->itemTraitList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveKarma(void)
	{
		std::ofstream ofs("lib-Vanilla\\Karma.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Karmas", this->karmaList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveQuest(void)
	{
		std::ofstream ofs("lib-Vanilla\\Quest.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Quests", this->questList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveRace(void)
	{
		std::ofstream ofs("lib-Vanilla\\Race.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Races", this->raceList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveSpace(void)
	{
		std::ofstream ofs("lib-Vanilla\\Space.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Spaces", this->spaceList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveSkill(void)
	{
		std::ofstream ofs("lib-Vanilla\\Skill.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Skills", this->skillList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveSpecie(void)
	{
		std::ofstream ofs("lib-Vanilla\\Specie.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("Species", this->speciesList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveStartingClass(void)
	{
		std::ofstream ofs("lib-Vanilla\\StartingClass.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("StartingClasses", this->startingClassList);
		ofs.close();
		return true;
	}

	bool GameWorld::xmlSaveTrapBase(void)
	{
		std::ofstream ofs("lib-Vanilla\\TrapBase.xml");
		assert(ofs);
		boost::archive::xml_oarchive oa(ofs);
		oa << boost::serialization::make_nvp("TrapBases", this->trapBaseList);
		ofs.close();
		return true;
	}

	bool GameWorld::XMLSave(void)
	{
		this->xmlSaveAir();
		this->xmlSaveAbility();
		this->xmlSaveAuthority();
		this->xmlSaveBuilding();
		this->xmlSaveCamp();
		this->xmlSaveCreatureTrait();
		this->xmlSaveDungeon();
		this->xmlSaveEffect();
		this->xmlSaveFloor();
		this->xmlSaveFixedArtifact();
		this->xmlSaveItemBase();
		this->xmlSaveItemEgo();
		this->xmlSaveItemTrait();
		this->xmlSaveKarma();
		this->xmlSaveQuest();
		this->xmlSaveRace();
		this->xmlSaveSpace();
		this->xmlSaveSkill();
		this->xmlSaveSpecie();
		this->xmlSaveStartingClass();
		this->xmlSaveTrapBase();
		return true;
	}

	bool GameWorld::xmlLoadAir()
	{
		std::ifstream ifs("lib-Vanilla\\Air.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(airList);
		return true;
	}

	bool GameWorld::xmlLoadAbility()
	{
		std::ifstream ifs("lib-Vanilla\\Ability.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(abilityList);
		return true;
	}

	bool GameWorld::xmlLoadAuthority()
	{
		std::ifstream ifs("lib-Vanilla\\Authority.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(authorityList);
		return true;
	}

	bool GameWorld::xmlLoadBuilding()
	{
		std::ifstream ifs("lib-Vanilla\\Building.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(buildingList);
		return true;
	}

	bool GameWorld::xmlLoadCamp()
	{
		std::ifstream ifs("lib-Vanilla\\Camp.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(campList);
		return true;
	}

	bool GameWorld::xmlLoadCreatureTrait()
	{
		std::ifstream ifs("lib-Vanilla\\CreatureTrait.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(creatureTraitList);
		return true;
	}

	bool GameWorld::xmlLoadDungeon()
	{
		std::ifstream ifs("lib-Vanilla\\Dungeon.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(dungeonList);
		return true;
	}

	bool GameWorld::xmlLoadEffect()
	{
		std::ifstream ifs("lib-Vanilla\\Effect.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(effectList);
		return true;
	}

	bool GameWorld::xmlLoadFloor()
	{
		std::ifstream ifs("lib-Vanilla\\Floor.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(floorList);
		return true;
	}

	bool GameWorld::xmlLoadFixedArtifact()
	{
		std::ifstream ifs("lib-Vanilla\\FixedArtifact.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(fixedArtifactList);
		return true;
	}

	bool GameWorld::xmlLoadItemBase()
	{
		std::ifstream ifs("lib-Vanilla\\ItemBase.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(itemBaseList);
		return true;
	}

	bool GameWorld::xmlLoadItemEgo()
	{
		std::ifstream ifs("lib-Vanilla\\ItemEgo.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(itemEgoList);
		return true;
	}

	bool GameWorld::xmlLoadItemTrait()
	{
		std::ifstream ifs("lib-Vanilla\\ItemTrait.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(itemTraitList);
		return true;
	}

	bool GameWorld::xmlLoadKarma()
	{
		std::ifstream ifs("lib-Vanilla\\Karma.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(karmaList);
		return true;
	}

	bool GameWorld::xmlLoadQuest()
	{
		std::ifstream ifs("lib-Vanilla\\Quest.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(questList);
		return true;
	}

	bool GameWorld::xmlLoadRace()
	{
		std::ifstream ifs("lib-Vanilla\\Race.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(raceList);
		return true;
	}

	bool GameWorld::xmlLoadSpace()
	{
		std::ifstream ifs("lib-Vanilla\\Space.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(spaceList);
		return true;
	}

	bool GameWorld::xmlLoadSkill()
	{
		std::ifstream ifs("lib-Vanilla\\Skill.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(skillList);
		return true;
	}

	bool GameWorld::xmlLoadSpecie()
	{
		std::ifstream ifs("lib-Vanilla\\Specie.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(speciesList);
		return true;
	}

	bool GameWorld::xmlLoadStartingClass()
	{
		std::ifstream ifs("lib-Vanilla\\StartingClass.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(startingClassList);
		return true;
	}

	bool GameWorld::xmlLoadTrapBase()
	{
		std::ifstream ifs("lib-Vanilla\\TrapBase.xml");
		assert(ifs);
		boost::archive::xml_iarchive ia(ifs);
		ia >> BOOST_SERIALIZATION_NVP(trapBaseList);
		return true;
	}

	void GameWorld::XMLLoad(void)
	{
		this->xmlLoadAir();
		this->xmlLoadAbility();
		this->xmlLoadAuthority();
		this->xmlLoadBuilding();
		this->xmlLoadCamp();
		this->xmlLoadCreatureTrait();
		this->xmlLoadDungeon();
		this->xmlLoadEffect();
		this->xmlLoadFloor();
		this->xmlLoadFixedArtifact();
		this->xmlLoadItemBase();
		this->xmlLoadItemEgo();
		this->xmlLoadItemTrait();
		this->xmlLoadKarma();
		this->xmlLoadQuest();
		this->xmlLoadRace();
		this->xmlLoadSpace();
		this->xmlLoadSkill();
		this->xmlLoadSpecie();
		this->xmlLoadStartingClass();
		this->xmlLoadTrapBase();
	}

	Authority *GameWorld::GetAuthority(TAG tag)
	{
		return &(*authorityList[tag]);
	}

	CreatureTrait *GameWorld::GetCreatureTrait(TAG tag)
	{
		return &(*creatureTraitList[tag]);
	}

	Effect *GameWorld::GetEffect(TAG tag)
	{
		return &(*effectList[tag]);
	}

	FixedArtifact *GameWorld::GetFixedArtifact(TAG tag)
	{
		return &(*fixedArtifactList[tag]);
	}

	Floor *GameWorld::GetFloor(TAG tag)
	{
		return &(*floorList[tag]);
	}

	ItemBase *GameWorld::GetItemBase(TAG tag)
	{
		return &(*itemBaseList[tag]);
	}

	ItemEgo *GameWorld::GetItemEgo(TAG tag)
	{
		return &(*itemEgoList[tag]);
	}

	ItemTrait *GameWorld::GetItemTrait(TAG tag)
	{
		return &(*itemTraitList[tag]);
	}

	Karma *GameWorld::GetKarma(TAG tag)
	{
		return &(*karmaList[tag]);
	}

	Skill *GameWorld::GetSkill(TAG tag)
	{
		return &(*skillList[tag]);
	}

	Species *GameWorld::GetSpecies(TAG tag)
	{
		return &(*speciesList[tag]);
	}

	TrapBase *GameWorld::GetTrapBase(TAG tag)
	{
		return &(*trapBaseList[tag]);
	}

	Building *GameWorld::GetBuilding(TAG tag)
	{
		return &(*buildingList[tag]);
	}

	Camp *GameWorld::GetCamp(TAG tag)
	{
		return &(*campList[tag]);
	}

	Dungeon *GameWorld::GetDungeon(TAG tag)
	{
		return &(*dungeonList[tag]);
	}

	Item *GameWorld::GetItem(ID id)
	{
		return &(*itemList[id]);
	}

	Field *GameWorld::GetField(ID id)
	{
		return &(*fieldList[id]);
	}

	Creature *GameWorld::GetCreature(ID id)
	{
		return &(*creatureList[id]);
	}

	std::map<TAG, boost::shared_ptr<Ability>> *GameWorld::GetAbilityList(void)
	{
		return &(this->abilityList);
	}

	Quest *GameWorld::GetQuest(TAG tag)
	{
		return &(*questList[tag]);
	}

	GAME_TIME GameWorld::GetGameTime(void)
	{
		return this->gameTime;
	}

	void GameWorld::WipeCreature(ID id)
	{
		creatureList.erase(id);
	}

	CREATURE_IT GameWorld::GetPlayerCreature(void)
	{
		return this->playerIt;
	}

	Creature *GameWorld::GetCreatureFromPosition(ID fieldID, Coordinates *positionPtr)
	{
		CREATURE_IT creatureIt;
		creatureIt = this->creatureList.begin();
		while(creatureIt != this->creatureList.end())
		{
			if(creatureIt->second->GetPosition() == *positionPtr && fieldID == creatureIt->second->GetFieldID()) return (creatureIt->second.get());
			creatureIt++;
		}
		return NULL;
		
	}

	Floor *GameWorld::GetFloorFromPosition(ID fieldID, Coordinates *positionPtr)
	{
		Square *square = fieldList[fieldID].get()->GetSquare(positionPtr->GetX(), positionPtr->GetY());
		if(!square) return NULL;		
		TAG tag = square->GetFloorTag();
		return &(*floorList[tag]);
	}

	std::map<TAG, boost::shared_ptr<Floor>> *GameWorld::GetFloorList(void)
	{
		return &floorList;
	}

	std::map<TAG, boost::shared_ptr<Species>> *GameWorld::GetSpeciesList(void)
	{
		return &speciesList;
	}

	CREATURE_LIST *GameWorld::GetCreatureList(void)
	{
		return &creatureList;
	}

	ACTION_LIST* GameWorld::GetActionList(void)
	{
		return &(this->actionList);
	}

	HaveGameTime *GameWorld::GetNextActionObject(void)
	{
		//this->gameTime++;
		return this->playerIt->second.get();
	}


}