#pragma once

#include "Mix/Tool/Win32/Core/Graphics/Node.h"
#include "Mix/Tool/Win32/Core/Graphics/Mesh.h"

#include "Mix/Tool/CLR/Core/Dynamics/Shape.h"
#include "Mix/Tool/CLR/Core/Dynamics/Design/IBasicDocument.h"
#include "Mix/Tool/CLR/Core/Dynamics/Design/Part.h"

#include "Mix/Tool/CLR/Core/Graphics/MaterialSlotCollection.h"

namespace Mix{ namespace Tool{ namespace Graphics{

	public ref class Node : public Mix::Tool::Dynamics::Design::IBasicDocument
	{
	public:
		ref class ChildCollection : public System::Collections::IEnumerable
		{
		private:
			System::Collections::Generic::List<Node^>^ m_List;

		internal:
			ChildCollection( void );
			~ChildCollection( void );

			void Add( Mix::Tool::Graphics::Node^ node );

		public:
			property int Count
			{
				int get( void );
			}

			property Mix::Tool::Graphics::Node^ default[int]
			{
				Mix::Tool::Graphics::Node^ get( int index );
			}

			int IndexOfName( System::String^ name );

		public:
			virtual System::Collections::IEnumerator^ GetEnumerator( void );
		};

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

			bool m_bAvailableDescend;

		internal:
			InternalBoundingBox( Mix::Tool::Win32::Graphics::Node* _implNode, int depth );
			InternalBoundingBox( Mix::Tool::Win32::Graphics::BASE_SHAPE* _implBaseShep,
							Mix::Tool::Win32::Graphics::Node* _implNode,
							bool bAvailableDescend );

			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( Mix::Tool::Win32::Graphics::Node* implNode );
			virtual ~InternalBoundingBoxCollection( void );
		};

	internal:
		Mix::Tool::Win32::Graphics::Node* implNode;

	private:
		Node::InternalBoundingBoxCollection^ m_BoundingBoxes;
		Mix::Tool::Dynamics::Design::Part^ m_DynamicsPartDesigner;
		Node::ChildCollection^ m_Childs;

	internal:
		Node( Mix::Tool::Win32::Graphics::Node* _implNode );
		virtual ~Node( void );

	public:
		property System::String^ Name
		{
			System::String^ get( void );
		}

		property Node::ChildCollection^ Childs
		{
			Node::ChildCollection^ get( void );
		}

	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 );
		}
	};

	public ref class EmptyNode : public Mix::Tool::Graphics::Node
	{
	internal:
		EmptyNode( Mix::Tool::Win32::Graphics::Node* _implNode );
		virtual ~EmptyNode( void );
	};

	public ref class MeshNode : public Mix::Tool::Graphics::Node
	{
	private:
		Mix::Tool::Win32::Graphics::Mesh* implMesh;

		Mix::Tool::Graphics::MaterialSlotCollection^ m_MaterialSlotCollection;

	internal:
		MeshNode( Mix::Tool::Win32::Graphics::Node* _implNode, Mix::Tool::Graphics::MaterialSlotCollection^ ownerMaterialSlotCollection );
		virtual ~MeshNode( void );

		property Mix::Tool::Win32::Graphics::Mesh* ImplMesh
		{
			Mix::Tool::Win32::Graphics::Mesh* get( void );
		}

	public:
		property Mix::Tool::Graphics::MaterialSlotCollection^ MaterialSlots
		{
			Mix::Tool::Graphics::MaterialSlotCollection^ get( void );
		}

		property unsigned int Key
		{
			unsigned int get( void );
		}

		property unsigned int VertexCount
		{
			unsigned int get( void );
		}

		property unsigned int IndexCount
		{
			unsigned int get( void );
		}

		property unsigned int PolygonCount
		{
			unsigned int get( void );
		}

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

	public ref class BoneNode : public Mix::Tool::Graphics::Node
	{
	internal:
		BoneNode( Mix::Tool::Win32::Graphics::Node* _implNode );
		virtual ~BoneNode( void );
	};

}}}
