#ifndef BLUECORE_MESH_MANAGER_H
#define BLUECORE_MESH_MANAGER_H

#include <map>
#include <string>

#include "RenderDevice.h"
#include "Math/Vector.h"
#include "Math/Plane.h"
#include "Utilities/Buffer.h"
#include "Utilities/Referenced.h"

namespace BlueCore {

typedef struct
{
	Vector3Float point;
	float u, v;
	Vector3Float normal;
} Vertex;

typedef struct
{
  unsigned short a, b, c;
} TriangleIndices;

typedef struct
{
public:
	unsigned int first;
	unsigned int count;
} Subset;

typedef struct
{
	unsigned short neighbours[3];
	PlaneFloat plane;
	bool backFace;
} ShadowFace;

class Mesh : public Referenced
{

  ref_ptr<RenderDevice> _Device;

public:

	Buffer<Vertex> VertexBuffer;
	Buffer<TriangleIndices> IndexBuffer;
	Buffer<Subset> SubsetBuffer;

	Buffer<Vector3Float> tangents;
	Buffer<Vector3Float> bitangents;
	Buffer<ShadowFace> shadowfaces;
	
public:

	Mesh (RenderDevice* device);

  void render ();
  void upload ();

protected:

	~Mesh();

};



class MeshManager : public Referenced
{
private:

	std::map<std::string, weak_ptr<Mesh> > _Meshes;

	bool saveToCache ( Mesh *mesh, const std::string &name );

	bool loadFromCache ( Mesh *mesh, const std::string &name );

  ref_ptr<RenderDevice> _Device;

public:

	MeshManager (RenderDevice *device);

	~MeshManager();

	Mesh *loadMesh (const std::string &name);
};

} // namespace BlueCore

#endif
