///////////////////////////////////////////////////////////////////////////////
/// @file deMesh.hpp
///
/// @brief mesh class interface
///
/// @author Assassin
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Aug 2003
/// @author Assassin
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DEMESH_HPP
#define DEMESH_HPP

#include "deGlobalTypes.hpp"
#include "deBrush.hpp"

class IdeMesh;
class IdeSurface;
class IdeBrush;

// factory functions
/// Create an instance of IdeMesh
DEBRUSH_API IdeMesh*	IdeMesh_CreateMesh();
/// Get the IdeMesh WorldObject interface ID
DEBRUSH_API long		IdeMesh_GetWOInterfaceID();
DEBRUSH_API deBoolean	IdeMesh_LoadStaticFromXFile(const char * filename, IdeMesh* pMesh, const deTransformInfo * Transform = NULL);

struct deMeshVertexData
{
	deVertex *positions;
	deVertex *normals;
	deTexCoord *uvcoords; // deTexCoord[numtexstages][numpoints]
	deARGB *colors;
	u32 numpoints;
	u32 numtexstages;
};
struct deMeshIndexData
{
	// set only one of these to a valid pointer, and the other to NULL
	u16* indices16;
	u32* indices32;
	u32 numindices;
	u32 indexoffset;
	IdeSurface* surface;
};

/// A storage class for static triangulated meshes.
/// Related functions: IdeMesh_CreateMesh, IdeMesh_GetWOInterfaceID
//class IdeMesh : virtual public IdeWorldObject
DE3D_INTERFACE(IdeMesh, IdeWorldObject)
{
protected:
	~IdeMesh() {}
public:
	/// Destroys all contained geometry
	virtual void ClearGeometry() = 0;

	/// Builds from a brush
	virtual deBoolean BuildFromBrushGeometry(IdeBrush* brush) = 0;

	// next 3 functions used for building compiled meshes from raw mesh data
	/// Builds from a set of vertex & index data, set through AddVertices and AddIndices.
	/// This will only take into account the geometry that has been input through AddVertices and AddIndices
	/// since the last time a mesh was built.
	virtual deBoolean BuildFromVertices() = 0;
	/// adds vertex data, fills indexoffset with offset to beginning of vertex data in main vertex buffer
	virtual deBoolean AddVertices(const deMeshVertexData & vertexdata, long & indexoffset) = 0;
	/// adds index data, which contains indexoffset and surface information
	virtual deBoolean AddIndices(const deMeshIndexData & indexdata) = 0;

	// next few functions used for manually editing a mesh.
	// do not use both these and the Build___ functions.
	/// Sets the number of submeshes, and destroys all existing submeshes
	virtual void SetNumSubMeshes(u32 NumSubs, deBoolean Dynamic = deTRUE) = 0;
	virtual deBoolean SetSurface(u32 SubNum, IdeSurface* Surface) = 0;
	virtual IdeSurface* GetSurface(u32 SubNum) = 0;
	virtual deBoolean SetNumFaces(u32 SubNum, u32 NumFaces) = 0;
	virtual u32 GetNumFaces(u32 SubNum) = 0;
	// feed in variables that can store 2d arrays, [NumSubs][NumFaces[SubNum]*3]
	virtual deBoolean Lock(deVertex** &positions, deTexCoord2** &uvcoords, deARGB** &colors) = 0;
	virtual deBoolean Unlock(deVertex** &positions, deTexCoord2** &uvcoords, deARGB** &colors) = 0;

	// below mainly for internal use
	virtual IdeVertexBuffer* GetMainVertexBuffer() = 0;
	virtual long GetNumSubMeshes() = 0;
	virtual IdeVertexBuffer* GetSubMeshVertexBuffer(long index) = 0;
	virtual IdeVertexBuffer* GetSubMeshIndexBuffer(long index) = 0;
	virtual IdeSurface* GetSubMeshSurface(long index) = 0;

	virtual deDouble GetBoundRadius() = 0;
	virtual void GetBBox(deAABB& outBox) = 0;
};

#endif

