/*
/ PRIMITIVE.H
/ ***********
/ Provides a range of primitive types, mostly from
/ the Direct3D prims. All have texture coordinates
/ except the Utah Teapot..
/
/ Will Beddow 2010 - http://343gs.com/brainstem
/
/ This software is currently under development
/ and is subject to change and improvement. Some
/ aspects of the system are incomplete and/or 
/ unstable due to ongoing implementation.
/
*/

#ifndef __PRIMITIVE_H__
#define __PRIMITIVE_H__

#include "Compile.h"
#include "Types.h"
#include "Node.h"
#include "Texture.h"
#include "Matrix.h"
#include "Mesh.h"

#include "BstmDevice.h"

#include <Windows.h>

namespace Brainstem
{
	class Primitive : public ISceneNode
	{
	public:
		Primitive(IDirect3DDevice9* device);
		~Primitive();

		virtual bool Init() = 0;
		void Update();
		void Render(ICamera* camera);
		void Release();

		void SetEffect(ID3DXEffect* effect);

		void ApplyTexture(ITexture* texture);
		ITexture* GetTexture();

		BoundingVolume GetBounds()
		{
			BoundingVolume mBounds = Mesh->Bounds;
			mBounds.ApplyTransforms(World);

			return mBounds;
		}

		IMesh* Mesh;

		virtual const char* GetName() { return "Primitive Model"; }

		void SetTechnique(const char* technique) { Technique = technique; }
		virtual const char* GetTechnique() { return Technique; };

	protected:
		IDirect3DDevice9* Device;
		ID3DXEffect* Effect;
		const char* Technique;

		IPtr<ITexture> Tex;
	};

	class Plane : public Primitive
	{
		public:
			Plane(IDirect3DDevice9* device, float width, float height);
			~Plane();

			const char* GetName() { return "Plane Primitive"; }

			bool Init();
		private:
			float Width;
			float Height;
		
	};

	class Teapot : public Primitive
	{
		public:
			Teapot(IDirect3DDevice9* device);
			~Teapot();

			const char* GetName() { return "Teapot Primitive"; }

			bool Init();
	};

	class Sphere : public Primitive
	{
		public:
			Sphere(IDirect3DDevice9* device, float radius, unsigned int slices, unsigned int stacks);
			~Sphere();

			const char* GetName() { return "Sphere Primitive"; }

			bool Init();
		private:
			float Radius;
			unsigned int Slices;
			unsigned int Stacks;
	};

	class Box : public Primitive
	{
		public:
			Box(IDirect3DDevice9* device, float width, float height, float depth);
			~Box();

			const char* GetName() { return "Box Primitive"; }

			bool Init();
		private:
			float Width;
			float Height;
			float Depth;
	};
}

#endif