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

#pragma once

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


namespace Deeangband
{

	class Air;
	class Ability;
	class Authority;
	class Building;
	class Camp;
	class CreatureTrait;

	class Creature;
	class Dungeon;
	class Effect;
	class Floor;

	class Field;
	class FixedArtifact;
	class GameMessage;
	class Item;
	class ItemBase;
	class ItemEgo;
	class ItemTrait;
	class Karma;
	class Lore;
	class Quest;
	class Race;
	class Space;
	class Skill;
	class Species;
	class StartingClass;
	class Trap;
	class TrapBase;

	class Coordinates;
	class HaveGameTime;

#include "EngineTypedef.h"

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

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

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

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

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

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


		/*!
		* @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) 
		{
		}

	public:

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

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

		/*!
		 * @brief ゲーム世界の初期生成を行う
		 */
		void GameWorld::Initialize(void);


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

		/*!
		* @brief クリーチャーを生成しGameWorld中の諸要素と連携させる
		* @param creatureTag クリーチャータグ
		* @param fieldID 配置先フィールドID
		* @param x 配置先X座標
		* @param y 配置先Y座標
		* @return 生成に成功した場合trueを返す
		*/
		bool GameWorld::GenerateCreature(std::map<TAG, std::shared_ptr<Species>>::iterator& speciesIt, std::map<ID, std::shared_ptr<Field>>::iterator& fieldIt, MAP_LENGTH x, MAP_LENGTH 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, std::shared_ptr<Ability>> *GameWorld::GetAbilityList(void);

		/*!
		 * @brief GameWorld中に存在するクリーチャーを返す
		 * @return 全クリーチャーのリスト
		 */
		CREATURE_LIST *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_IT GameWorld::GetPlayerCreature(void);

		/*!
		 * @brief 行動順リストを返す
		 * @return 行動順リスト
		 */
		ACTION_LIST *GameWorld::GetActionList(void);

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

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

		std::map<TAG, std::shared_ptr<Floor>> *GameWorld::GetFloorList(void);

		std::map<TAG, std::shared_ptr<Species>> *GameWorld::GetSpeciesList(void);

		/*!
		 * @brief 時間経過処理を行い、次のアクションオブジェクトを返す。
		 * @return 行動順リスト
		 */
		HaveGameTime *GameWorld::GetNextActionObject(void);


	};

}