/// @file GameCore.h
#ifndef GAMECORE_H
#define GAMECORE_H
#include "../graphic/CoreGraphic.h"
#include "../input/CoreInput.h"
#include "../sound/OggPlayer.h"
#include "RenderPocket.h"
#include "../../object/RenderQueueMaker.h"
#include "../../object/Indicator.h"
#include "../../object/PrintBoard.h"
#include "ControlTable.h"
#include <map>
#include <string>
using std::string;
using std::map;

/**
	@brief 프로세스를 위한 클래스

	모든 프로세스를 총괄하는 클래스입니다.\n
	크게 로딩 프로세스, 컨트롤 프로세스, 렌더링 프로세스를 수행합니다.\n
	각각의 객체들은 역할과 기능별로 여러 컨테이너에 담깁니다.\n
	기본적인 객체는 RObjectPocket에 들어가고 렌더링 효율을 위해 미리 구분되있는 RenderPocket에 담깁니다.\n
	객체의 기본역할은 각자의 객체에서 정의합니다.\n
	프로세스 상황은 ControlTable 객체에 기록하며 객체는 여기에 접근해 상황을 알 수 있습니다.\n
	스크립트의 command oper를 수행할 수 있는 함수셋도 관리합니다.
*/
class GameCore {
	public:
		GameCore(){
			makeRenderQueue_["cube"] = RenderQueueMaker::makeCubeQueue;
			makeRenderQueue_["sprite"] = RenderQueueMaker::makeSpriteQueue;

			makeRObject_["indicator"] = Indicator::makeIndicator;
			makeRObject_["print_board"] = PrintBoard::makePrintBoard;

			commandOper_["show"] = operShow_;
			commandOper_["rotate"] = operRotate_;
			commandOper_["print"] = operPrint_;
		}
		~GameCore(){
			aOggPlayer_.Close();
			clearScriptPocket_();
			clearMainPocket_();
		}
		void initGame(HWND _hWnd, int _width, int _height, bool _bWindowed);
		void run();

	private: //private member
		CoreGraphic aCoreGraphic_;
		CoreInput aCoreInput_;
		OggPlayer aOggPlayer_;

		TiXmlDocument xmlDoc_;

		map<string, RObject* (*)(TiXmlElement*)> makeRObject_;
		map<string, RenderQueue* (*)(RenderPocket&, TiXmlElement*)> makeRenderQueue_;
		map<string, void (GameCore::*)(TiXmlElement*)> commandOper_;
		//makeSObject가 없는것은, SObject를 만드는것은 정해져 있기 때문이다.

		//객체가 생성될때 접근하는 컨테이너
		vector<RenderQueue*> mainRenderQueuePocket_;
		vector<RenderQueue*> scriptRenderQueuePocket_;
		vector<RenderQueue*> * pCurrentRenderQueuePocket_;
		vector<RenderQueue*>::iterator pItrRenderQueue_;

		//객체를 쉽게 렌더링할 수 있도록 정리상자의 역할을 하는 컨테이너
		RenderPocket aRenderPocket_;

		//객체가 상황을 알 수 있게하는 ControlTable
		ControlTable aControlTable_;

		//실제로 컨트롤하는 객체
		vector<RObject*> mainRObjectPocket_;
		vector<RObject*> scriptRObjectPocket_;
		vector<RObject*> * pCurrentRObjectPocket_;
		vector<RObject*>::iterator pItrRObject_;
		TiXmlElement* pCommandElement_;
		string key_;

	private: //private member-fuction
		void putRenderPocket_(TiXmlElement* _pRenderElement);
		void putRObjectPocket_(TiXmlElement* _pRObjectElement);
		void controlScript_(TiXmlElement* _pScriptElement);
		inline void loadXmlFile_(const char* _fileName);
		inline void loadSceneObject_(int _sceneNum);
		//void loadScriptObject_(int _scriptNum);

		void clearMainPocket_();
		void clearScriptPocket_();

		//스크립트의 command oper를 수행하기 위한 함수
		void operShow_(TiXmlElement* _pCommandElement);
		void operRotate_(TiXmlElement* _pCommandElement);
		void operPrint_(TiXmlElement* _pCommandElement);
};

#endif