/*----------------------------------------------
Programmer: Alberto Bobadilla (labigm@gmail.com)
Date: 2015/06
----------------------------------------------*/
#ifndef __PRIMITIVEMANAGERSINGLETON_H_
#define __PRIMITIVEMANAGERSINGLETON_H_

#include "RE\Mesh\PrimitiveClass.h"
#include "RE\Mesh\PrimitiveWireClass.h"
#include "RE\Mesh\MeshDrawerSingleton.h"


namespace ReEng
{

//System Class
class ReEngDLL PrimitiveManagerSingleton
{
	static PrimitiveManagerSingleton* m_pInstance; // Singleton of the class

	MeshClass* m_pAxis = nullptr; //Axis primitive
	MeshClass* m_pGrid = nullptr; //Grid primitive
	MeshClass* m_pLine = nullptr; //Line primitive
	MeshClass* m_pPlane = nullptr; //Plane primitive
	MeshClass* m_pCube = nullptr; //Cube primitive
	MeshClass* m_pCubeWire = nullptr; //Cube Wire primitive
	MeshClass* m_pCone = nullptr; //Cone primitive
	MeshClass* m_pConeWire = nullptr; //Cone Wire primitive
	MeshClass* m_pCylinder = nullptr; //Cylinder primitive
	MeshClass* m_pCylinderWire = nullptr; //Cylinder Wire primitive
	MeshClass* m_pTube = nullptr; //Tube primitive
	MeshClass* m_pTubeWire = nullptr; //Tube Wire primitive
	MeshClass* m_pTorus = nullptr; //Torus primitive
	MeshClass* m_pTorusWire = nullptr; //Torus Wire primitive
	MeshClass* m_pSphere = nullptr;//Sphere primitive
	MeshClass* m_pSphereWire = nullptr;//Sphere Wire primitive

	MeshDrawerSingleton* m_pMeshDrawer = nullptr;

public:
	/* Gets/Constructs the singleton pointer */
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT:
	*/
	static PrimitiveManagerSingleton* GetInstance();
	/* Destroys the singleton */
	/*
	 USAGE:
	ARGUMENTS: ---
	OUTPUT: ---
	*/
	static void ReleaseInstance(void); //Singleton Release

	/* Render the axis on the specified position */
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddAxisToQueue(matrix4 a_m4ToWorld);

	/* Renders the cube on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddPlaneToQueue(matrix4 a_m4ToWorld, vector3 a_v3Color = REDEFAULT);

	/* Renders the cube on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddCubeToQueue(matrix4 a_m4ToWorld, vector3 a_v3Color = REDEFAULT, int a_RenderOption = RERENDER::SOLID | RERENDER::WIRE);

	/* Renders the cone on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddConeToQueue(matrix4 a_m4ToWorld, vector3 a_v3Color = REDEFAULT, int a_RenderOption = RERENDER::SOLID | RERENDER::WIRE);

	/* Renders the cylinder on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddCylinderToQueue(matrix4 a_m4ToWorld, vector3 a_v3Color = REDEFAULT, int a_RenderOption = RERENDER::SOLID | RERENDER::WIRE);

	/* Renders the tube on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddTubeToQueue(matrix4 a_m4ToWorld, vector3 a_v3Color = REDEFAULT, int a_RenderOption = RERENDER::SOLID | RERENDER::WIRE);

	/* Renders the torus on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddTorusToQueue(matrix4 a_m4ToWorld, vector3 a_v3Color = REDEFAULT, int a_RenderOption = RERENDER::SOLID | RERENDER::WIRE);
	
	/* Renders the sphere on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddSphereToQueue(matrix4 a_m4ToWorld, vector3 a_v3Color = REDEFAULT, int a_RenderOption = RERENDER::SOLID | RERENDER::WIRE);

	/* Renders the sphere on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddGridToQueue(float a_fSize = 1.0f, int a_Axis = REAXIS::XY, vector3 a_v3Color = REDEFAULT);
	
	/* Renders the sphere on the specified position*/
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddLineToQueue(vector3 a_v3Start, vector3 a_v3End, vector3 a_v3StartColor = REDEFAULT, vector3 a_v3EndColor = REDEFAULT);

	/* Renders a camera shape on the specified position */
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT: ---
	*/
	void AddCameraToQueue(matrix4 a_m4ToWorld, vector3 a_v3Color = REDEFAULT);
	
private:
	/* Constructor */
	/*
	 USAGE:
	ARGUMENTS: ---
	OUTPUT:
	*/
	PrimitiveManagerSingleton(void);
	/* Copy constructor */
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT:
	*/
	PrimitiveManagerSingleton(PrimitiveManagerSingleton const& other);
	/* Copy Assignment operator */
	/*
	 USAGE:
	ARGUMENTS:
	OUTPUT:
	*/
	PrimitiveManagerSingleton& operator=(PrimitiveManagerSingleton const& other);
	/* Destructor */
	/*
	 USAGE:
	ARGUMENTS: ---
	OUTPUT: ---
	*/
	~PrimitiveManagerSingleton(void);

	/* Releases the objects memory */
	/*
	 USAGE:
	ARGUMENTS: ---
	OUTPUT: ---
	*/
	void Release(void);
	/* Initializates the objects fields */
	/*
	 USAGE:
	ARGUMENTS: ---
	OUTPUT: ---
	*/
	void Init(void);
};

}

#endif //__PRIMITIVEMANAGERSINGLETON_H_