//@STATE=嶌惉拞
//@DESCRIPTION ---------------------------------------------------------------
// DispositionControl.h: DispositionControl 僋儔僗偺僀儞僞乕僼僃僀僗
// 攝抲僨乕僞惂屼
//	棜楌丗
// $Log: DispositionControl.h,v $
// Revision 1.1  2001/10/28 21:40:35  fujiwara
// DLL偵暘妱
//
// Revision 1.7  2001/07/09 20:30:08  fujiwara
// 椺奜張棟偺慻傒崬傒
//
// Revision 1.6  2001/07/01 01:03:43  fujiwara
// const 偺尒捈偟
// 攝抲僄僨傿僞偼搑拞宱夁
//
// Revision 1.5  2001/05/17 12:34:10  fujiwara
// 抧忋揋僒儞僾儖嶌惉
//
// Revision 1.4  2001/05/12 12:48:28  fujiwara
// 攝抲僄僨傿僞嶌惉偵敽偆曄峏丒捛壛
//
// Revision 1.3  2001/05/12 00:50:48  fujiwara
// 俠倁俽傪摫擖偟丄儘僌昞帵傪捛壛
//
//@DESCRIPTION_END -----------------------------------------------------------
//@AUTHOR=S.F.
// Copyright (C) 2000 Satoshi Fujiwara. All Rights Reserved.
///////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_DISPOSITIONCONTROL_H__B18EC6D6_B30C_4A24_B747_D0EBBC6F71F2__INCLUDED_)
#define AFX_DISPOSITIONCONTROL_H__B18EC6D6_B30C_4A24_B747_D0EBBC6F71F2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
namespace sf {
	namespace application {
		namespace scene {
			class DispositionEditor;
		};

		namespace disposition {

	// 攝抲僐儅儞僪僆僽僕僃僋僩
	namespace command { 
		// ----------------------------------------------------
		// 僐儅儞僪僨乕僞偺堄枴乮僼傽僀儖偵曐懚偝傟偰偄傞帪乯 
		// position float Y埵抲
		// command  string 僐儅儞僪柤
		// parameter ... 僷儔儊乕僞楍(奺僐儅儞僪偛偲偵挿偝偼堎側傞乯
		// ----------------------------------------------------
		
		const int MAX = 5;// 僐儅儞僪偺嵟戝悢
		enum TYPE {
			RESET = 0,
			SET_SCROLLSPEED = 1,
			SET_RESTARTPOSITION = 2,
			SET_ENEMY = 3,
			SET_ARMY = 4
		};

		// --- 僐儞僥僫廂擺梡僀儞僞乕僼僃乕僗 --- //

		class Interface : 
			public sf::system::input::keyboard::Listener
			,public sf::system::input::mouse::Listener 
		{
			
			// LIFECYCLE //

		public:
			Interface(){;};
			virtual ~Interface(){;};

			// OPERATORS //

			// 僀儞僞乕僼僃乕僗偺峫偊曽偐傜偡傟偽偙傟偼斀懃峴堊両
			// 戙擖墘嶼巕偼virtual偵偱偒側偄偺偱丏丏丏
			Interface &operator=( Interface &rSrc )
			{
				return copy(rSrc);
			};

			
			// OPERATIONS //

			virtual void exec(const float position) = 0;
			// 僗僩儕乕儉偐傜偺儘乕僪
			virtual void load(std::istream &is) = 0;
			// 僗僩儕乕儉偐傜偺僙乕僽
			virtual void save(std::ostream &os) = 0;

			// 攝抲僄僨傿僞忣曬昤夋
			virtual void draw(sf::application::scene::DispositionEditor * const pEditor
								,const float position,const bool bMouse) = 0;
			
			// ACCESS //

			// 僐儅儞僪偺宆傪曉偡
			virtual const TYPE id(void) const = 0;
			// Game僔乕儞傊偺億僀儞僞
			virtual sf::application::scene::Game * const game(void) const = 0;
			virtual void game(sf::application::scene::Game * const pGame) = 0;
			// 僐儅儞僪偺僔儕傾儖斣崋(尰嵼偼枹巊梡)
			virtual void serialNo(const int value) = 0;
			virtual const int serialNo(void) const = 0;
			// 攝抲儅僢僾昞帵梡僗僾儔僀僩傊偺億僀儞僞
			virtual sf::system::console::sprite::Sprite * const sprite (void) const = 0;
			// 攝抲僄僨傿僞梡
			virtual const int max(void) const = 0;
			virtual void load(void) = 0;
			virtual Interface& copy(Interface &rSrc) = 0;

		};// Interface

		// --- 拪徾僋儔僗  亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅

		class Abstract : public Interface {

			// LIFECYCLE //
		
		public:
			Abstract()
			{	mSerialNo = 0;
				mpGame = NULL;
			};

			~Abstract(){;};
		
			// OPERATORS //

			
			// OPERATIONS //

			virtual void draw(sf::application::scene::DispositionEditor * const pEditor
				,const float position
				,const bool bMouse);

			// 儅僂僗丒僉乕儃乕僪儕僗僫
			// 儅僂僗儕僗僫乕
			void leftButtonDown(const int screenX,const int screenY,const DWORD mkey){;};
			void leftButtonUp(const int screenX,const int screenY,const DWORD mkey){;};
			void leftButtonDoubleClick(const int screenX,const int screenY,const DWORD mkey){;};
			void rightButtonDown(const int screenX,const int screenY,const DWORD mkey){;};
			void rightButtonUp(const int screenX,const int screenY,const DWORD mkey){;};
			void rightButtonDoubleClick(const int screenX,const int screenY,const DWORD mkey){;};
			virtual void mouseMove(const int screenX,const int screenY,const DWORD mkey){;};
			void mouseWheel(const int screenX,const int screenY,const DWORD mkey){;};
			void mouseTalkerIsDeleted(void){;};
		
			void keyDown(const DWORD keyCode,const DWORD extKeyCode){};
			void keyUp(const DWORD keyCode,const DWORD extKeyCode){};
			void keyboardTalkerIsDeleted(void){;};

			// 僐儅儞僪偺僐僺乕傪偲傞 //
			Interface &copy(Interface &rSrc)
			{
//				position(rSrc.position());
				game(rSrc.game());
				return (*this);
			};

			// ACCESS //
			
			// 僔儕傾儖斣崋 //
			void serialNo(const int value){ mSerialNo = value;};
			const int serialNo(void) const {return mSerialNo;};
			// 僎乕儉僔乕儞傊偺億僀儞僞 
			sf::application::scene::Game * const game(void) const { return mpGame;};
			void game(sf::application::scene::Game * const pGame){mpGame = pGame;};

			const int max(void) const { return 1;};

			sf::system::console::sprite::Sprite * const sprite(void) const {return NULL;};

			// INQUIRY //
		
			const bool isListeningMouse(void) const {return false;};
			const bool isListeningKeyboard(void) const {return false;};
		
		private:
			sf::application::scene::Game * mpGame;
			int mSerialNo;
		};// Abstract
		
		// 儕僙僢僩僐儅儞僪		亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
		class Reset : public Abstract {

			// LIFECYCLE //

		public:
			Reset(){;};
			virtual ~Reset(){;};

			// OPERATORS //


			// OPERATIONS //

			void exec(const float position){;};
			
			void load(std::istream &is){;};
			void save(std::ostream &os){;};
			void load(void){;};
			// 僆僽帪僕僃僋僩偺惗惉
			static Interface * const create(void) { return new Reset;};

			// ACCESS //

			const TYPE id(void) const {return RESET;};
		};// Reset
		
		// 僗僋儘乕儖僗僺乕僪 偺愝掕 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
		class SetScrollSpeed : public Abstract {

			// LIFECYCLE //

		public:
			SetScrollSpeed(){mSpeed = 0;};
			virtual ~SetScrollSpeed(){unloadResource();};

			// OPERATORS //


			// OPERATIONS //

			void exec(const float position){ game()->scrollSpeed(mSpeed);};

			const TYPE id(void) const {return SET_SCROLLSPEED;};

			void load(std::istream &is){ is >> mSpeed; };
			void save(std::ostream &os){ os << " " << mSpeed;};

			static void loadResource(void);
			static void unloadResource(void);

			void load(void){loadResource();};

			static Interface * const create(void) { return new SetScrollSpeed;};

			// 僐儅儞僪偺僐僺乕傪偲傞 //
			Interface &copy(Interface &rSrc)
			{
				SetScrollSpeed &tmp = dynamic_cast<SetScrollSpeed &>(rSrc);
				speed(tmp.speed());
				game(tmp.game());
				return (*this);
			};
	
			// ACCESS //

			const float	speed(void) const {return mSpeed;};
			void		speed(const float value){mSpeed = value;};

			sf::system::console::sprite::Sprite * const sprite(void) const {return mspSprite.get();};
		private:
		
			float mSpeed;

			static sf::system::console::sprite::PSprite mspSprite;
			static const sf::system::console::sprite::Info msSpriteInfo;
			static int msRefCount; 
		};// SetScrollSpeed
		
		// -- 儕僗僞乕僩埵抲偺愝掕 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
		class SetRestartPosition : public Abstract {
			
			// LIFECYCLE // 

		public:
			SetRestartPosition(){;};
			virtual ~SetRestartPosition(){;};

			// OPERATORS //

			
			// OPERATIONS //

			// 僐儅儞僪偺幚峴 
			void exec(const float position)
			{	game()->restartPosition(position);
			};

			// 僐儅儞僪偺僐僺乕傪偲傞 
			Interface &copy(Interface &rSrc)
			{
				SetRestartPosition &tmp = dynamic_cast<SetRestartPosition &>(rSrc);
				game(tmp.game());
				return (*this);
			};

			

			void load(std::istream &is){;};
			void save(std::ostream &os){;};
			
			void load(void){loadResource();};

			static void loadResource(void);
			static void unloadResource(void);

			static Interface * const create(void) { return new SetRestartPosition;};

			// ACCESS //

			const TYPE id(void) const {return SET_RESTARTPOSITION;};

			sf::system::console::sprite::Sprite * const sprite(void){return mspSprite.get();};
		private:
			static sf::system::console::sprite::PSprite mspSprite;
			static const sf::system::console::sprite::Info msSpriteInfo;
		};// SetRestartPosition
		
		// 揋傪攝抲偡傞 //////////////////////////////////////////////////
		// 僷儔儊乕僞 
		// int ... 擄堈搙
		// int ... 揋俬俢
		// float ... 弌尰埵抲倃
		// float ... 弌尰埵抲倄

		// 嬻拞揋偺攝抲僐儅儞僪 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
		class SetEnemy : public Abstract {

			// LIFECYCLE //

		public:
			SetEnemy();
			virtual ~SetEnemy();

			// OPERATORS //


			// OPERATIONS //

			// 僐儅儞僪偺僐僺乕傪偲傞 
			Interface &copy(Interface &rSrc)
			{
				SetEnemy &tmp = dynamic_cast<SetEnemy &>(rSrc);
				game(tmp.game());
				x(tmp.x());
				y(tmp.y());
				z(tmp.z());
				enemyNo(tmp.enemyNo());
				difficulty(tmp.difficulty());
				return (*this);
			};

			void exec(const float position);
			// 僗僩儕乕儉傛傝僨乕僞儘乕僪
			void load(std::istream &is);
			// 僗僩儕乕儉傊僨乕僞僙乕僽
			void save(std::ostream &os);
			// 儕僜乕僗偺儘乕僪
			void load(void){loadResource();};
			static void loadResource(void);
			// 儕僜乕僗偺傾儞儘乕僪
			static void unloadResource(void);
			// 攝抲僨乕僞傊昤夋 
			void draw(sf::application::scene::DispositionEditor * const pEditor,const float position,const bool bMouse);
			// 僆僽僕僃僋僩偺惗惉 			
			static Interface * const create(void) { return new SetEnemy;};
			// 儅僂僗堏摦帪偺張棟 
			void mouseMove(const int screenX,const int screenY,const DWORD mkey)
			{
				x((float)screenX - game()->background()->startOffsetX());
				y((float)screenY - game()->background()->startOffsetY());
				z(sf::application::enemy::Z_OFFSET_ENEMYS);
			};
			// 僉乕墴壓帪偺張棟 
			void keyDown(const DWORD keyCode,const DWORD extKeyCode);

			// ACCESS //

			// 攝抲僨乕僞埵抲丂X
			const float x() const {return mX;};
			void x(const float value){mX = value;};
			// 攝抲僨乕僞埵抲丂Y
			const float y() const {return mY;};
			void y(const float value){mY = value;};
			// 攝抲僨乕僞埵抲丂Z
			const float z() const {return mZ;};
			void z(const float value){mZ = value;};
			// 揋偺庬椶
			const int enemyNo() const {return mEnemyNo;};
			void enemyNo(const int value){mEnemyNo = value;};
			// 擄堈搙 
			const sf::application::scene::Game::DIFFICULTY difficulty() const {return mDifficulty;};
			void difficulty(const sf::application::scene::Game::DIFFICULTY value){mDifficulty = value;};
			// 揋偺嵟戝
			const int max(void) const;
			// 僐儅儞僪偺庬椶
			const TYPE id(void) const {return SET_ENEMY;};
			
			// INQUIRY //

			const bool isListeningMouse(void) const {return true;};
			const bool isListeningKeyboard(void) const {return true;};

		private:

			int mEnemyNo;
			sf::application::scene::Game::DIFFICULTY mDifficulty;

			float mX;
			float mY;
			float mZ;

			static  const sf::system::console::sprite::Info msSpriteInfos[sf::application::enemy::MAX_TYPE];
			static  sf::system::console::sprite::PSprite mspSprites[sf::application::enemy::MAX_TYPE];

		};// SetEnemy

		// 抧忋揋攝抲僐儅儞僪 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
		class SetArmy : public Abstract
		{
			
			// LIFECYCLE //
		
		public:
			
			SetArmy();
			virtual ~SetArmy();
			
			// OPERATORS //

			
			// OPERATIONS //

			// 僐儅儞僪偺僐僺乕傪偲傞 
			Interface &copy(Interface &rSrc)
			{
				SetArmy &tmp = dynamic_cast<SetArmy &>(rSrc);
				game(tmp.game());
				x(tmp.x());
				y(tmp.y());
				z(tmp.z());
				enemyNo(tmp.enemyNo());
				difficulty(tmp.difficulty());
				return (*this);
			};
			
			// 僐儅儞僪偺幚峴 
			void exec(const float position);
			// 僗僩儕乕儉傛傝僐儅儞僪偺儘乕僪
			void load(std::istream &is);
			// 僗僩儕乕儉傊僐儅儞僪傪僙乕僽
			void save(std::ostream &os);
			// 儕僜乕僗偺儘乕僪
			void load(void){loadResource();};
			static void loadResource(void);
			// 儕僜乕僗偺傾儞儘乕僪 
			static void unloadResource(void);
			// 攝抲儅僢僾偵昤夋
			void draw(sf::application::scene::DispositionEditor * const pEditor,const float position,const bool bMouse);
			// 僆僽僕僃僋僩偺惗惉
			static Interface * const create(void) { return new SetArmy;};
			// 僉乕僐乕僪墴壓帪偺張棟 
			void keyDown(const DWORD keyCode,const DWORD extKeyCode);

			// ACCESS //

			// 弌尰埵抲 X 
			const float x() const {return mX;};
			void x(const float value){mX = value;};
			// 弌尰埵抲 Y 
			const float y() const {return mY;};
			void y(const float value){mY = value;};
			// 弌尰埵抲 Z
			const float z() const {return mZ;};
			void z(const float value){mZ = value;};
			// 揋偺庬椶 			
			const int enemyNo() const {return mEnemyNo;};
			void enemyNo(const int value){mEnemyNo = value;};
			// 擄堈搙 
			const sf::application::scene::Game::DIFFICULTY difficulty() const {return mDifficulty;};
			void difficulty(const sf::application::scene::Game::DIFFICULTY value){mDifficulty = value;};
			// 揋偺庬椶嵟戝 
			const int max(void) const ;
			// 僆僽僕僃僋僩偺僞僀僾傪曉偡 
			const TYPE id(void) const {return SET_ARMY;};
		
			// INQUIRY //
			
			const bool isListeningMouse(void) const {return true;};
			const bool isListeningKeyboard(void) const {return true;};
		
		private:
			// 揋斣崋
			int mEnemyNo;
			// 擄堈搙
			sf::application::scene::Game::DIFFICULTY mDifficulty;
			
			float mX;// 弌尰X嵗昗
			float mY;// 弌尰Y嵗昗
			float mZ;// 弌尰Z嵗昗

			static  const sf::system::console::sprite::Info msSpriteInfos[sf::application::enemy::MAX_ARMYS_TYPE];
			static  sf::system::console::sprite::PSprite mspSprites[sf::application::enemy::MAX_ARMYS_TYPE];

		};// SetArmy	

	}// command

	// 僐儅儞僪惂屼 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
	class ControllerImpl : public Controller
	{
	public:
	
		// LIFECYCLE 
		
		ControllerImpl();
		~ControllerImpl();
		
		// OPERATIONS
		
		// 攝抲僨乕僞傪攋婞偡傞
		void unload(void);
		// 攝抲僨乕僞僼傽僀儖偺儘乕僪
		void load(const char * const pFileName);
		// 攝抲僨乕僞僼傽僀儖偺僙乕僽
		void save(const char * const pFileName = NULL);
		// 攝抲僨乕僞傪幚峴 		
		void exec(const float position);
		// 巜掕偟偨埵抲偵僀僥儗乕僞傪堏摦
		void restart(const float position);

		void insertCommand(const float position,command::Interface * const pInterface)
		{	
			typedef std::pair<float,command::Interface * > value_type;
			pInterface->serialNo(mSerialNo++);
			mData.insert(value_type(position,pInterface));
		};// insertCommand()
		// 僔儕傾儖No偱攝抲僨乕僞傪嶍彍
		void deleteCommand(const int serialNo){
			CommandList::iterator it = mData.begin();
			while(it != mData.end()){
				if(it->second->serialNo() == serialNo){
					mData.erase(it);
					break;
				}
				it++;
			}
		};// deleteCommand()

		// 攝抲儅僢僾偺埵抲偱揋傪嶍彍 
		void deleteCommand(const float x,const float y,const float position,const command::TYPE type);
		// 僐儅儞僪僆僽僕僃僋僩偺惗惉 
		static command::Interface * const create(const command::TYPE type){return (*mpCreateFunc[type])();};

		// ACCESS //

		// Game僆僽僕僃僋僩傊偺億僀儞僞
		sf::application::scene::Game * game(void){ return mpGame;};
		void game(sf::application::scene::Game *pGame){mpGame = pGame;};
		
		CommandList& commandList(void){return mData;};

		static const int commandMax(void) {return command::MAX;};

	private:
//		command::Interface * create(command::TYPE command_id);
		const int findCommand(const std::string &s);

		CommandList mData;
		CommandList::iterator mDataIter;
		std::string mFileName;
		sf::application::scene::Game * mpGame;
		int mSerialNo;
		// command parse梡 string table 
		static const std::string mCommand[command::MAX];
		static const CreateFuncPtr mpCreateFunc[command::MAX];

	};// ControllerImpl()

}
}
}

#endif // !defined(AFX_DISPOSITIONCONTROL_H__B18EC6D6_B30C_4A24_B747_D0EBBC6F71F2__INCLUDED_)
