/*!
* @file GameWorld.h
* @brief ゲーム世界のプロトタイプ宣言
* @date 2013/02/01
* @author Deskull
* 2013-2014 Sikabane Works.
*/

#pragma once

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

#include "Air.h"
#include "Ability.h"
#include "Authority.h"
#include "Building.h"
#include "Camp.h"
#include "Creature.h"
#include "CreatureTrait.h"
#include "Dungeon.h"
#include "Effect.h"
#include "Floor.h"
#include "FixedArtifact.h"
#include "GameMessage.h"
#include "ItemBase.h"
#include "ItemEgo.h"
#include "ItemTrait.h"
#include "Karma.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 "Creature.h"
#include "Field.h"
#include "Trap.h"

BOOST_CLASS_VERSION(GameWorld, 1);

namespace Deeangband
{

	/*!
	* @class GameWorld
	* @brief ゲーム世界のクラス
	*/
	class GameWorld
	{
	private:

		//静的データリスト
		std::map<TAG, boost::shared_ptr<Air>> airList;                      /*!<全大気地形リスト*/
		std::map<TAG, boost::shared_ptr<Ability>> abilityList;              /*!<全発動技能リスト*/
		std::map<TAG, boost::shared_ptr<Authority>> authorityList;          /*!<全権能リスト*/
		std::map<TAG, boost::shared_ptr<Building>> buildingList;            /*!<全施設リスト*/
		std::map<TAG, boost::shared_ptr<Camp>> campList;                    /*!<全陣営リスト*/
		std::map<TAG, boost::shared_ptr<CreatureTrait>> creatureTraitList;  /*!<全クリーチャー特性リスト*/
		std::map<TAG, boost::shared_ptr<Dungeon>> dungeonList;              /*!<全ダンジョンリスト*/
		std::map<TAG, boost::shared_ptr<Effect>> effectList;                /*!<全効果属性リスト*/
		std::map<TAG, boost::shared_ptr<Floor>> floorList;                  /*!<全床地形リスト*/
		std::map<TAG, boost::shared_ptr<FixedArtifact>> fixedArtifactList;  /*!<全固定アーティファクトリスト*/
		std::map<TAG, boost::shared_ptr<ItemBase>> itemBaseList;            /*!<全アイテムベースリスト*/
		std::map<TAG, boost::shared_ptr<ItemEgo>> itemEgoList;              /*!<全アイテムエゴリスト*/
		std::map<TAG, boost::shared_ptr<ItemTrait>> itemTraitList;          /*!<全アイテム特性リスト*/
		std::map<TAG, boost::shared_ptr<Karma>> karmaList;                  /*!<全カルマリスト*/
		std::map<TAG, boost::shared_ptr<Quest>> questList;                  /*!<全クエスト特性リスト*/
		std::map<TAG, boost::shared_ptr<Space>> spaceList;                      /*!<全空間地形リスト*/
		std::map<TAG, boost::shared_ptr<Skill>> skillList;                  /*!<全スキルリスト*/
		std::map<TAG, boost::shared_ptr<Species>> speciesList;              /*!<全クリーチャー種別リスト*/
		std::map<TAG, boost::shared_ptr<StartingClass>> startingClassList;  /*!<全出自リスト*/
		std::map<TAG, boost::shared_ptr<Race>> raceList;                    /*!<全種族リスト*/
		std::map<TAG, boost::shared_ptr<TrapBase>> trapBaseList;            /*!<全トラップベース種別リスト*/

		//動的データリスト
		std::map<ID, boost::shared_ptr<Item>> itemList;                    /*!<全アイテムリスト*/
		std::map<ID, boost::shared_ptr<Creature>> creatureList;            /*!<全クリーチャーリスト*/
		std::map<ID, boost::shared_ptr<Field>> fieldList;                  /*!<全フロアリスト*/
		std::map<ID, boost::shared_ptr<Trap>> trapList;                    /*!<全トラップリスト*/

		ID itemID;     //!<空きアイテムID
		ID creatureID; //!<空きクリーチャーID
		ID fieldID;    //!<空きフィールドID
		ID trapID;     //!<空きトラップID

		std::vector<boost::shared_ptr<HaveGameTime>> actionList; /*!<行動順リスト*/

		Creature *playerPtr; //!< プレイヤークリーチャー参照ポインタ
		GAME_TIME gameTime; //!<ゲーム時間

		friend class boost::serialization::access;

		/*!
		* @brief 大気地形情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveAir(void);

		/*!
		* @brief 発動技能のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveAbility(void);

		/*!
		* @brief 権能情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveAuthority(void);

		/*!
		* @brief 施設情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveBuilding(void);

		/*!
		* @brief 陣営情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveCamp(void);

		/*!
		* @brief クリーチャー特性のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveCreatureTrait(void);

		/*!
		* @brief ダンジョン情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveDungeon(void);

		/*!
		* @brief 効果属性情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveEffect(void);

		/*!
		* @brief 地形情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveFloor(void);

		/*!
		* @brief 固定アーティファクト情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveFixedArtifact(void);

		/*!
		* @brief ベースアイテム情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveItemBase(void);

		/*!
		* @brief アイテムエゴ情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveItemEgo(void);

		/*!
		* @brief アイテム特性情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveItemTrait(void);

		/*!
		* @brief カルマ情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveKarma(void);

		/*!
		* @brief クエスト情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveQuest(void);

		/*!
		* @brief クエスト情報のセーブ
		* @return 書き込みに成功すればTRUEを返す
		* @todo 書き込み処理のエラー判定
		*/
		bool GameWorld::xmlSaveRace(void);

		/*!
		* @brief スキル情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveSkill(void);

		/*!
		* @brief 空間地形情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveSpace(void);

		/*!
		* @brief クリーチャー種別情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveSpecie(void);

		/*!
		* @brief 出自情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveStartingClass(void);

		/*!
		* @brief ベーストラップ情報のセーブ
		* @return 保存に成功すればTRUEを返す
		* @todo 保存処理のエラー判定
		*/
		bool GameWorld::xmlSaveTrapBase(void);

		bool GameWorld::xmlLoadAir(void);
		bool GameWorld::xmlLoadAbility(void);
		bool GameWorld::xmlLoadAuthority(void);
		bool GameWorld::xmlLoadBuilding(void);
		bool GameWorld::xmlLoadCamp(void);
		bool GameWorld::xmlLoadCreatureTrait(void);
		bool GameWorld::xmlLoadDungeon(void);
		bool GameWorld::xmlLoadEffect(void);
		bool GameWorld::xmlLoadFloor(void);
		bool GameWorld::xmlLoadFixedArtifact(void);
		bool GameWorld::xmlLoadItemBase(void);
		bool GameWorld::xmlLoadItemEgo(void);
		bool GameWorld::xmlLoadItemTrait(void);
		bool GameWorld::xmlLoadKarma(void);
		bool GameWorld::xmlLoadQuest(void);
		bool GameWorld::xmlLoadRace(void);
		bool GameWorld::xmlLoadSpace(void);
		bool GameWorld::xmlLoadSkill(void);
		bool GameWorld::xmlLoadSpecie(void);
		bool GameWorld::xmlLoadStartingClass(void);
		bool GameWorld::xmlLoadTrapBase(void);

		/*!
		* @brief クラスのシリアライズを設定する
		* @param archive アーカイブ化するクラスのアドレス
		* @param version ファイルバージョン
		* @return XMLSerializeテンプレート
		*/
		template<class Archive> void serialize(Archive &archive, const unsigned int version) 
		{
			if(version >= 0)
			{
				archive & boost::serialization::make_nvp("Authorities", authorityList);
				archive & boost::serialization::make_nvp("Buildings", buildingList);
				archive & boost::serialization::make_nvp("Camps", campList);
				archive & boost::serialization::make_nvp("Dungeons", dungeonList);
				archive & boost::serialization::make_nvp("Effects", effectList);
				archive & boost::serialization::make_nvp("Floors", floorList);
				archive & boost::serialization::make_nvp("FixedArtifacts", fixedArtifactList);
				archive & boost::serialization::make_nvp("ItemBases", itemBaseList);
				archive & boost::serialization::make_nvp("ItemEgos", itemEgoList);
				archive & boost::serialization::make_nvp("ItemTraits", itemTraitList);
				archive & boost::serialization::make_nvp("Karmas", karmaList);
				archive & boost::serialization::make_nvp("Quests", questList);
				archive & boost::serialization::make_nvp("Skills", skillList);
				archive & boost::serialization::make_nvp("Species", speciesList);
				archive & boost::serialization::make_nvp("TrapBases", trapBaseList);

				archive & boost::serialization::make_nvp("Authorities", authorityList);
				archive & boost::serialization::make_nvp("Creatures", creatureList);
				archive & boost::serialization::make_nvp("Items", itemList);
				archive & boost::serialization::make_nvp("Fields", fieldList);
				archive & boost::serialization::make_nvp("Traps", trapList);
			}
		}

	public:

		/*!
		* @brief GameWorldクラスのコンストラクタ
		* @param gSurface ゲームのインターフェイスとなる GameSurface 参照
		*/
		GameWorld::GameWorld(void);

		/*!
		* @brief GameWorldクラスのデストラクタ
		*/
		GameWorld::~GameWorld(void);

		/*!
		* @brief クリーチャーを生成しGameWorld中の諸要素と連携させる
		* @param creatureTag クリーチャータグ
		* @return 生成に成功した場合trueを返す
		*/
		bool GameWorld::GenerateCreature(TAG creatureTag);

		/*!
		* @brief クリーチャーを生成しGameWorld中の諸要素と連携させる
		* @param creatureTag クリーチャータグ
		* @param fieldID 配置先フィールドID
		* @param x 配置先X座標
		* @param y 配置先Y座標
		* @return 生成に成功した場合trueを返す
		*/
		bool GameWorld::GenerateCreature(TAG creatureTag, ID fieldID, int x, int y);

		/*!
		* @brief GameWorld中に存在する権能を返す
		* @param tag 権能のタグ
		* @return 権能の参照ポインタ、存在しなければNULLを返す。
		*/
		Authority *GameWorld::GetAuthority(TAG tag);

		/*!
		* @brief GameWorld中に存在するクリーチャー特性を返す
		* @param tag クリーチャー特性のタグ
		* @return クリーチャー特性の参照ポインタ、存在しなければNULLを返す。
		*/
		CreatureTrait *GameWorld::GetCreatureTrait(TAG tag);

		/*!
		* @brief GameWorld中に存在する効果属性を返す
		* @param tag 効果属性のタグ
		* @return 効果属性の参照ポインタ、存在しなければNULLを返す。
		*/
		Effect *GameWorld::GetEffect(TAG tag);

		/*!
		* @brief GameWorld中に存在する固定アーティファクトを返す
		* @param tag 効果属性のタグ
		* @return 固定アーティファクトの参照ポインタ、存在しなければNULLを返す。
		*/
		FixedArtifact *GameWorld::GetFixedArtifact(TAG tag);

		/*!
		* @brief GameWorld中に存在する地形を返す
		* @param tag 地形のタグ
		* @return 地形の参照ポインタ、存在しなければNULLを返す。
		*/
		Floor *GameWorld::GetFloor(TAG tag);

		/*!
		* @brief GameWorld中に存在するベースアイテムを返す
		* @param tag ベースアイテムのタグ
		* @return ベースアイテムの参照ポインタ、存在しなければNULLを返す。
		*/
		ItemBase *GameWorld::GetItemBase(TAG tag);

		/*!
		* @brief GameWorld中に存在するアイテムエゴを返す
		* @param tag アイテムエゴのタグ
		* @return アイテムエゴの参照ポインタ、存在しなければNULLを返す。
		*/
		ItemEgo *GameWorld::GetItemEgo(TAG tag);

		/*!
		* @brief GameWorld中に存在するアイテム特性を返す
		* @param tag アイテム特性のタグ
		* @return アイテム特性の参照ポインタ、存在しなければNULLを返す。
		*/
		ItemTrait *GameWorld::GetItemTrait(TAG tag);

		/*!
		 * @brief GameWorld中に存在するカルマを返す
		 * @param tag カルマのタグ
		 * @return カルマの参照ポインタ、存在しなければNULLを返す。
		 */
		Karma *GameWorld::GetKarma(TAG tag);

		/*!
		 * @brief GameWorld中に存在するスキルを返す
		 * @param tag スキルのタグ
		 * @return スキルの参照ポインタ、存在しなければNULLを返す。
		 */
		Skill *GameWorld::GetSkill(TAG tag);

		/*!
		 * @brief GameWorld中に存在するスキルを返す
		 * @param tag スキルのタグ
		 * @return スキルの参照ポインタ、存在しなければNULLを返す。
		 */
		Species *GameWorld::GetSpecies(TAG tag);

		/*!
		 * @brief GameWorld中に存在するトラップ種別を返す
		 * @param tag トラップ種別のタグ
		 * @return トラップ種別の参照ポインタ、存在しなければNULLを返す。
		 */
		TrapBase *GameWorld::GetTrapBase(TAG tag);

		/*!
		 * @brief GameWorld中に存在する施設を返す
		 * @param tag 施設のタグ
		 * @return 施設の参照ポインタ、存在しなければNULLを返す。
		 */
		Building *GameWorld::GetBuilding(TAG tag);

		/*!
		 * @brief GameWorld中に存在する陣営を返す
		 * @param tag 陣営のタグ
		 * @return 陣営の参照ポインタ、存在しなければNULLを返す。
		 */
		Camp *GameWorld::GetCamp(TAG tag);

		/*!
		 * @brief GameWorld中に存在するダンジョンを返す
		 * @param tag ダンジョンのタグ
		 * @return ダンジョンの参照ポインタ、存在しなければNULLを返す。
		 */
		Dungeon *GameWorld::GetDungeon(TAG tag);

		/*!
		 * @brief GameWorld中に存在するアイテムを返す
		 * @param id アイテムのID
		 * @return アイテムの参照ポインタ、存在しなければNULLを返す。
		 */
		Item *GameWorld::GetItem(ID id);

		/*!
		 * @brief GameWorld中に存在するフロアを返す
		 * @param id フロアのID
		 * @return フロアの参照ポインタ、存在しなければNULLを返す。
		 */
		Field *GameWorld::GetField(ID id);

		/*!
		 * @brief GameWorld中に存在するクリーチャーを返す
		 * @param id クリーチャーのID
		 * @return クリーチャーの参照ポインタ、存在しなければNULLを返す。
		 */
		Creature *GameWorld::GetCreature(ID id);

		/*!
		 * @brief GameWorld中に存在する発動技能を返す
		 * @return 全発動技能のリスト
		 */
		std::map<TAG, boost::shared_ptr<Ability>> *GameWorld::GetAbilityList(void);

		/*!
		 * @brief GameWorld中に存在するクリーチャーを返す
		 * @return 全クリーチャーのリスト
		 */
		std::map<ID, boost::shared_ptr<Creature>> *GameWorld::GetCreatureList(void);

		/*!
		 * @brief GameWorld中に存在するクエストを返す
		 * @param tag クエストのタグ
		 * @return クエストの参照ポインタ、存在しなければNULLを返す。
		 */
		Quest *GameWorld::GetQuest(TAG tag);

		/*!
		 * @brief ゲーム時間を返す
		 * @return ゲーム時間
		 */
		GAME_TIME GameWorld::GetGameTime(void);

		/*!
		 * @brief XMLシリアライズによるゲームデータ保存処理
		 * @return なし
		 */
		bool GameWorld::XMLSave(void);

		/*!
		 * @brief XMLデシリアライズによるゲームデータ読込処理
		 * @return なし
		 */
		void GameWorld::XMLLoad(void);

		/*!
		 * @brief 対応したIDのクリーチャーをリストから除外する
		 * @return なし
		 */
		void GameWorld::WipeCreature(ID id);

		/*!
		 * @brief プレイヤークリーチャーを返す
		 * @return プレイヤークリーチャーの参照ポインタ
		 */
		Creature *GameWorld::GetPlayerCreature(void);

		/*!
		 * @brief 行動順リストを返す
		 * @return 行動順リスト
		 */
		std::vector<boost::shared_ptr<HaveGameTime>>* GameWorld::GetActionList(void);

		/*!
		 * @brief 指定フィールド及び座標に存在するクリーチャーがいるかを判別しクリーチャーを返す。
		 * @param fieldID フィールドID
		 * @param positionPtr 座標ポインタ
		 * @param 存在するクリーチャーのポインタ、存在しない場合NULL。
		 */
		Creature *GameWorld::GetCreatureFromPosition(ID fieldID, Coordinates *positionPtr);

	};

}