/*!
* @file Field.h
* @brief ゲーム中のダンジョンと付随要素のプロトタイプ
* @date 2013/12/11
* @author Deskull
* 2013 Sikabane Works.
*/

#pragma once

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

#include "Dungeon.h"
#include "GameWorld.h"
#include "GameInstance.h"
#include "Square.h"
#include "Door.h"
#include "TrapBase.h"
#include "Trap.h"
#include "Item.h"

namespace Deeangband
{

	/*!
	* @class Field
	* @brief フロアのクラス
	*/
	class Field : public GameInstance
	{
	private:
		std::vector<std::vector<boost::shared_ptr<Square>>> squares; //!<フロアマスの配列
		std::vector<boost::shared_ptr<Creature>> creatures; //!<クリーチャーインスタンスの配列
		std::vector<boost::shared_ptr<Door>> doors; //!<ドアインスタンスの配列
		std::vector<boost::shared_ptr<Trap>> traps; //!<トラップインスタンスの配列
		std::vector<boost::shared_ptr<Item>> items; //!<アイテムインスタンスの配列
		MAP_LENGTH width;  //!< フロアの横サイズ
		MAP_LENGTH height; //!< フロアの縦サイズ
		bool generated; //!< フロア生成済み
		TAG dungeonTag; //!< 生成元ダンジョンタグ

		friend class boost::serialization::access;

		/*!
		* @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("Squares", squares);
				archive & boost::serialization::make_nvp("Doors", doors);
				archive & boost::serialization::make_nvp("Traps", traps);
				archive & boost::serialization::make_nvp("Items", items);
				archive & boost::serialization::make_nvp("Doors", doors);
				archive & boost::serialization::make_nvp("Width", width);
				archive & boost::serialization::make_nvp("Height", height);
			}
		}

	public:

		/*! 
		* @brief Fieldクラスコンストラクタ(TAG,Dungeonイテレータからの生成)
		* @param dungeonPtr 生成元ダンジョンイテレータ
		* @param depth 生成階層
		* @details 
		* 本コンストラクタは、ダンジョン情報と生成階を元にフロアを生成する、恐らく最も実用の機会の多いコンストラクタになる。<br>
		* <h2>処理の流れ</h2>
		* <ul>
		* <li>フロアサイズの決定</li>
		* <li>外壁地形での全フロア充填</li>
		* </ul>
		* @todo Dungeon情報を基にしたコンストラクタの生成を実装
		*/
		Field::Field(std::map<TAG, boost::shared_ptr<Dungeon>>::iterator dungeonIt, DEPTH depth);


		/*! 
		* @brief Fieldクラスコンストラクタ
		*/
		Field::Field();

		/*! 
		* @brief Fieldクラスデストラクタ
		* @todo フロアを完全消去する際に、同フロアに配置されるクリーチャー、アイテム、ドア、トラップ類を消去し、ユニーク性のあるものなどについて出現状態を調整すること。
		*/
		Field::~Field();

		/*! 
		* @brief ダミーデータによる初期化
		* @return なし
		*/
		void Field::WipeData(void);

		/*!
		* @brief フロアの横サイズを得る
		* @return フロアの横サイズ
		*/
		MAP_LENGTH Field::GetWidth(void);

		/*!
		* @brief フロアの縦サイズを得る
		* @return フロアの縦サイズ
		*/
		MAP_LENGTH Field::GetHeight(void);

		/*!
		* @brief フロアのサイズを設定する
		* @param width フロアの横サイズ
		* @param height フロアの縦サイズ
		* @return 処理に成功した場合trueを返す
		* @todo 変更された場合のフロア配列のリサイズを実装
		*/
		bool Field::SetSize(MAP_LENGTH width, MAP_LENGTH height);

		/*!
		* @brief フロアの該当座標のマスを返す。
		* @return 該当するマスインスタンスの参照ポインタ
		*/
		Square *Field::GetSquare(MAP_LENGTH x, MAP_LENGTH y);

		/*!
		* @brief フロアの該当座標にトラップを生成する
		* @param trapBaseTag 配置するトラップ種別タグ
		* @param position 配置したい座標
		* @return 生成に成功した場合trueを返す。
		* @details
		* GenerateTrap関数はタグで指示されたトラップ種別のトラップをフロアの所定の位置に配置する。<br>
		* @todo Field::GenerateTrapの実装
		*/
		bool Field::GenerateTrap(std::map<TAG, boost::shared_ptr<TrapBase>>::iterator trapBaseIt, Coordinates *position);

	};

}

BOOST_CLASS_VERSION(Deeangband::Field, 10);
