#ifndef MESH_H
#define MESH_H

#include <string>

#include <kLibrary\Factory\factory.h>

#include "object.h"

#include "material.h"
#include "texture.h"

#include <boundingbox.h>

namespace CBK
{
	typedef kLibrary::Factory<Material, IDirect3DDevice9*> materialFactory;
	typedef kLibrary::Factory<Texture, IDirect3DDevice9*> textureFactory;

	struct MeshParam
	{
		IDirect3DDevice9* device;
		materialFactory* materialLoader;
		textureFactory* textureLoader;

		MeshParam(IDirect3DDevice9* device = 0, materialFactory* materialLoader = 0, textureFactory* textureLoader = 0)
		{
			this->device = device;
			this->materialLoader = materialLoader;
			this->textureLoader = textureLoader;
		}
	};

	typedef kLibrary::factory::Item<const MeshParam&> item;

	class Mesh : public item
	{
	public:
		Mesh(const MeshParam& params, const std::string& name = "");
		~Mesh(void);
		
		Mesh& setDevice(IDirect3DDevice9* device);
		IDirect3DDevice9* getDevice(void);

		virtual void apply(void);
		virtual void draw(const DWORD& subset = 0);
		Mesh& drawBoundingBox(void);

		const size_t& getSubsetCount(void) const;

		//Allow material setting
		Mesh& setMaterialLoader(materialFactory* materialLoader);
		materialFactory* getMaterialLoader(void) const;
		Mesh& setMaterial(const std::string& name, const size_t& subset = 0);
		const Material* getMaterial(const size_t& subset = 0) const;

		//Allow texture setting
		Mesh& setTextureLoader(textureFactory* textureLoader);
		textureFactory* getTextureLoader(void) const;
		Mesh& setTexture(const std::string& name, const size_t& subset = 0);
		const Texture* getTexture(const size_t& subset = 0) const;

		const float& getTerrainYOffset(void) const;
		Mesh& setTerrainYOffset(const float& yOffset);

		void calcBoundaries(void);
		const float& getCollisionSphereRadius(void) const;
		const cbk::BoundingBox& getBoundingBox(void) const;

		virtual Mesh& reset(void);

	protected:
		IDirect3DDevice9* _device;
		
		size_t _subsets;
		ID3DXMesh* _mesh;
		float _yOffset;

		cbk::BoundingBox _bb;
		float _CollideSphereRadius;

		std::vector<Material*> _materials;
		kLibrary::Factory<Material, IDirect3DDevice9*>* _materialLoader;

		std::vector<Texture*> _textures;
		kLibrary::Factory<Texture, IDirect3DDevice9*>* _textureLoader;
	};
}

#endif //MESH_H