#pragma once
#include "mof/tstring.hpp"
#include "mof/InputReceiver.hpp"
#include "mof/script/ObjectData.hpp"
#include <vector>
#include <mof/stream/Manipulator.hpp>
#include <mof/Color.hpp>
#include <mof/Vector2D.hpp>
#include <mof/Vector3D.hpp>
	
namespace mof
{
namespace script
{

	class CommandSet
	{
	public:
		enum MoveDirection
		{
			MOVE_UP = 0,
			MOVE_DOWN,
			MOVE_LEFT,
			MOVE_RIGHT,
		};

		enum ElementType
		{
			FOREST = 0,
			EARTH,
			WATER
		};


		/** 
		 * @brief	 メッセージウィンドウを生成するためのコールバック
		 * @return	生成したメッセージウィンドウ
		 */
		virtual int message_create(unsigned int thread_id, const mof::tstring& title, const GameData::entry_t& style, int priority) = 0;
	
		virtual int menu_create(unsigned int thread_id, const mof::tstring& title, const std::vector<mof::tstring>& items, const GameData::entry_t& style, int priority) = 0;
		
		virtual int vertex_buffer_create
		(
		 	unsigned int thread_id,
			const mof::VertexXYZRHWCUV& front,
			const mof::VertexXYZRHWCUV& back,
			const mof::Texture::ptr& texture,
			int priority
		) = 0;

		virtual int sound_create(const mof::tstring& filepath) = 0;
		
		virtual void sound_play(int id) = 0;

		virtual int music_create(const mof::tstring& filepath) = 0;
		
		virtual void music_play(int id) = 0;

		virtual void music_pause(int id) = 0;
		
		virtual int picture_create(unsigned int thread_id, const mof::tstring& filepath, int priority) = 0;
		
		virtual int camera_create() = 0;
		
		virtual int particlegen_create(unsigned int thread_id) = 0;
		
		virtual int solid_create(unsigned int thread_id, const mof::tstring& class_path, int priority) = 0;
		
		virtual int light_create(unsigned int thread_id, const mof::tstring& class_path) = 0;
		
		virtual void set_light(int id, int light_id) = 0;
		
		virtual int board_create(unsigned int thread_id, const mof::tstring& filepath, const GameData::entry_t& style, int priority) = 0;

		/** 
		 * @brief	 メッセージウィンドウにページを追加するためのコールバック
		 * @param[in] メッセージのタイトル
		 * @param[in] メッセージ内容
		 * @return	生成したメッセージウィンドウ
		 */
		virtual int message_next(int id, const tstring& text) = 0;
	   
		virtual void wait_for_key(size_t id, mof::InputReceiver::Key key) = 0;
		
		virtual mof::InputReceiver::Key get_last_key() = 0;
		
		virtual void wait_frame(size_t id, size_t frame) = 0;

		virtual void routine_stop(unsigned int thread_id) = 0;
		
		virtual bool is_waiting(size_t id) const = 0;

		virtual int menu_move_cursor(int id, MoveDirection direction) = 0;
		
		virtual int menu_select(int id) = 0;
		
		virtual int menu_get_current(int id) = 0;
		
		virtual GameData::ptr load_game_data(const mof::tstring& resource_path) = 0;
		
		virtual void save_game_data(const mof::tstring& resource_path, const GameData::ptr& game_data) = 0;

		virtual void print_debug(const mof::tstring& message) = 0;
		
		// 共通のメソッド
		virtual int show(int id, const mof::tstring& class_path) = 0;
		
		virtual int hide(int id, const mof::tstring& class_path) = 0;
		
		virtual void dispose(int id, const mof::tstring& class_path) = 0;

		virtual void set_enable(int id, bool is_enable, const mof::tstring& class_path) = 0;
		
		virtual GameData::ptr get_properties(int id, const mof::tstring& class_path) = 0;

		/**
		 * @brief オブジェクトにビヘイビアを設定
		 * @param[in] id     オブジェクトID
		 * @param[in] target ターゲット識別名
		 * @param[in] seq    指定するシーケンス
		 * @param[in] period シーケンスのピリオド
		 */
		virtual void set_color_behavior(int id, const mof::tstring& class_path, const Manipulator<Color4f>::ptr& seq, FrameNumber period) = 0;
		
		virtual void set_position_behavior(int id, const mof::tstring& class_path, const Manipulator<Vector2D>::ptr& seq, FrameNumber period) = 0;
		
		virtual void set_position_behavior(int id, const mof::tstring& class_path, const Manipulator<Vector3D>::ptr& seq) = 0;
		
		virtual void set_camera_behavior(int id, const mof::tstring& class_path, const Manipulator<Vector3D>::ptr& seq) = 0;
		
		virtual void set_size_behavior(int id, const mof::tstring& class_path, const Manipulator<Vector2D>::ptr& seq, FrameNumber period) = 0;
		
		virtual void set_size_behavior(int id, const mof::tstring& class_path, const Manipulator<Vector3D>::ptr& seq) = 0;
		
		virtual void set_rotate_behavior(int id, const mof::tstring& class_path, const Manipulator<Vector3D>::ptr& seq) = 0;

		virtual void set_texture_coord_tween
		(
			int id,
			const mof::tstring& class_path, 
			const Manipulator<mof::Rectangle<float>>::ptr& seq
		) = 0;

		virtual void joint(int id1, const mof::tstring& class_name1, const mof::tstring& joint_type, int id2, const mof::tstring& class_name2) = 0;

		virtual void quit() = 0;

		// Applicationに依存したコマンド(TODO moflibから排除する仕組み)
		virtual mof::frame_t put_element(ElementType type, int x, int y) = 0;

		virtual void world_sleep() = 0;
		
		virtual int land_region_create(unsigned int thread_id, int x, int y, int priority) = 0;
		
		virtual ~CommandSet(){}

	};

}
}

