#pragma once

#include "Mix/Tool/CLR/Core/Dynamics/Design/IBasicDocument.h"
#include "Mix/Tool/CLR/Core/Graphics/Model.h"

namespace Mix{ namespace Tool{ namespace Dynamics{ namespace Design{
	ref class Actor;
}}}}

namespace Mix{ namespace Tool{ namespace Win32{ namespace Graphics{
	class ObjectModel;
}}}}

namespace Mix{ namespace Tool{ namespace Graphics{
	ref class MotionController;
	ref class MotionControllerCollection;
	ref class RootTransform;
}}}

namespace Mix{ namespace Tool{ namespace Graphics{

	public ref class ObjectModel : public Mix::Tool::Graphics::Model, public Mix::Tool::Dynamics::Design::IBasicDocument
	{
	public:
		enum class TimeModes
		{
			Frames30,
			Frames60,
		};

		ref class ImportConfig
		{
		private:
			System::String^ m_FilePath;

			Mix::Tool::Graphics::ModelImportOption m_Option;

			float m_Scaling;
			Mix::Tool::Math::Vector^ m_Rotation;
			Mix::Tool::Math::Vector^ m_Translation;

			bool m_bSmooting;
			float m_SmootingAngle;

			ObjectModel::TimeModes m_TimeModes;

		public:
			ImportConfig( void );

		public:
			property System::String^ FilePath
			{
				System::String^ get( void );
				void set( System::String^ value );
			}

			property Mix::Tool::Graphics::ModelImportOption Option
			{
				Mix::Tool::Graphics::ModelImportOption get( void );
				void set( Mix::Tool::Graphics::ModelImportOption value );
			}

			property float Scaling
			{
				float get( void );
				void set( float value );
			}

			property Mix::Tool::Math::Vector^ Rotation
			{
				Mix::Tool::Math::Vector^ get( void );
				void set( Mix::Tool::Math::Vector^ value );
			}

			property Mix::Tool::Math::Vector^ Translation
			{
				Mix::Tool::Math::Vector^ get( void );
				void set( Mix::Tool::Math::Vector^ value );
			}

			property bool Smooting
			{
				bool get( void );
				void set( bool value );
			}

			property float SmootingAngle
			{
				float get( void );
				void set( float value );
			}

			property ObjectModel::TimeModes TimeMode
			{
				ObjectModel::TimeModes get( void );
				void set( ObjectModel::TimeModes value );
			}
		};

	private:
		ref class InternalBoundingBox : public Mix::Tool::Dynamics::Design::BoundingBox
		{
		private:
			Mix::Tool::Win32::Graphics::ObjectModel* implObjModel;

		internal:
			InternalBoundingBox( Mix::Tool::Win32::Graphics::BASE_SHAPE* _implBaseShape );
			virtual ~InternalBoundingBox( void );

		public:
			property bool IsAvailableDescend
			{
				virtual bool get( void ) override;
			}

			virtual Mix::Tool::Dynamics::Design::BoundingBox^ Descend( int depth ) override;
		};

		ref class InternalBoundingBoxCollection : public Mix::Tool::Dynamics::Design::BoundingBoxCollection
		{
		internal:
			InternalBoundingBoxCollection( void );
			virtual ~InternalBoundingBoxCollection( void );

			void Initialize( Mix::Tool::Win32::Graphics::ObjectModel* _implObjModel );
		};

	private:
		Mix::Tool::Win32::Graphics::ObjectModel* implObjectModel;

		Mix::Tool::Graphics::MotionControllerCollection^ m_MotionControllers;
		Mix::Tool::Graphics::MotionController^ m_UnassignedMotionCtrl;
		Mix::Tool::Graphics::RootTransform^ m_RootTransform;

		ObjectModel::InternalBoundingBoxCollection^ m_BoundingBoxes;
		Mix::Tool::Dynamics::Design::Actor^ m_DynamicsDesigner;

	public:
		ObjectModel( void );
		virtual ~ObjectModel( void );

		bool Import( ObjectModel::ImportConfig^ config );
		bool ImportFinalize( void );

		property Mix::Tool::Graphics::MotionController^ UnassignedMotionController
		{
			Mix::Tool::Graphics::MotionController^ get( void );
		}

		property Mix::Tool::Graphics::MotionControllerCollection^ MotionControllers
		{
			Mix::Tool::Graphics::MotionControllerCollection^ get( void );
		}

		property Mix::Tool::Graphics::RootTransform^ RootTransform
		{
			Mix::Tool::Graphics::RootTransform^ get( void );
		}

		void ResetPose( void );
		void Jump( void );

		bool SaveMotions( void );

	public:
		virtual bool SaveModel( void ) override;

	public:
		property Mix::Tool::Dynamics::Design::BoundingBoxCollection^ BoundingBoxes
		{
			virtual Mix::Tool::Dynamics::Design::BoundingBoxCollection^ get( void );
		}

		property Mix::Tool::Dynamics::Design::Basic^ DynamicsDesigner
		{
			virtual Mix::Tool::Dynamics::Design::Basic^ get( void );
		}
	};

}}}
