///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Flexporter SDK Beta v1.1
 *	\file		FlexporterSDK.h
 *	\author		Pierre Terdiman
 *	\date		April, 4, 2000
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __FLEXPORTER_SDK__
#define __FLEXPORTER_SDK__

//! SDK Version number
#define FLEXPORTER_VERSION	104

//! Using ICE Core
#define DEFAULT_NEWDELETE
#include "IceCore.h"
using namespace IceCore;

#define MESHMERIZER_API
//for FLEXPORTER CARBON-COPY (remove MESHMERIZER_API)
	//! Submesh properties.
	struct MESHMERIZER_API MBSubmesh
	{
		sdword			MatID;					//!< MaterialID for this submesh
		udword			SmGrp;					//!< Smoothing groups for this submesh
		udword			NbFaces;				//!< Number of faces in this submesh
		udword			NbVerts;				//!< Number of vertices in this submesh
		udword			NbSubstrips;			//!< Number of strips in this submesh
	};

	//! Material properties.
	struct MESHMERIZER_API MBMatInfo
	{
		sdword			MatID;					//!< This material's ID
		udword			NbFaces;				//!< Number of faces having this material
		udword			NbVerts;				//!< Related number of exported vertices
		udword			NbSubmeshes;			//!< Number of related submeshes
	};

	//! The topology structure.
	struct MESHMERIZER_API MBTopology
	{
		MBTopology()
		{
			VRefs				= null;
			FacesInSubmesh		= null;
			Normals				= null;
			SubmeshProperties	= null;
		}
		uword			NbFaces;				//!< Total number of faces
		uword			NbSubmeshes;			//!< Total number of submeshes (e.g. 6 for the reference cube)
		uword*			VRefs;					//!< Vertex references (3 refs for each face)
		uword*			FacesInSubmesh;			//!< Number of faces in each submesh
		float*			Normals;				//!< Face normals
		MBSubmesh*		SubmeshProperties;		//!< NbSubmeshes structures
	};

	//! The geometry structure.
	struct MESHMERIZER_API MBGeometry
	{
		MBGeometry()
		{
			VertsRefs	= null;
			TVertsRefs	= null;
			ColorRefs	= null;
			Verts		= null;
			TVerts		= null;
			Normals		= null;
			CVerts		= null;
			NormalInfo	= null;
		}
		// Basic data
		uword			NbGeomPts;				//!< Number of vertices in the original mesh
		uword			NbTVerts;				//!< Number of mapping coordinates in the original mesh
		uword			NbColorVerts;			//!< Number of vertex-colors in the original mesh
		//
		uword			NbVerts;				//!< Number of vertices in the final mesh (some may have been duplicated) = sum of all NbVerts in MBSubmeshes
		// Indices
		udword*			VertsRefs;				//!< Vertex indices (only !=null if mIndexedGeo, else vertices are duplicated). Index in Verts.
		udword*			TVertsRefs;				//!< UVW indices (only !=null if mIndexedUVW, else UVWs are duplicated). Index in TVerts.
		udword*			ColorRefs;				//!< Vertex-color indices (only !=null if mIndexedColors, else colors are duplicated). Index in CVerts.
		// Vertex data
		float*			Verts;					//!< List of vertices, may be duplicated or not
		float*			TVerts;					//!< List of UV(W) mappings, may be duplicated or not.
		float*			CVerts;					//!< List of vertex colors, may be duplicated or not.
		float*			Normals;				//!< Vertex normals. Can't be indexed.
		udword			NormalInfoSize;			//!< Size of the NormalInfo field.
		udword*			NormalInfo;				//!< Information used to rebuild normals in realtime. See below.
	};

	// More about NormalInfo:
	//
	// NormalInfo contains some extra information used to rebuild vertex-normals in realtime, by averaging
	// a number of face-normals. Each vertex-normal depends on a various number of face-normals. The exact
	// number depends on the mesh topology, but also depends on the smoothing groups.
	//
	// NormalInfo contains data to rebuild one normal/vertex, ie to rebuild NbVerts normals.
	// Format is, for each vertex:
	//		udword		Count				a number of faces
	//		udword		Ref0, Ref1,...		a list of Count face indices
	//
	// To rebuild vertex-normals in realtime you need to:
	// 1) Rebuild all face-normals (which is easy)
	// 2) For each vertex, add Count face-normals according to NormalInfo, then normalize the summed vector.
	//
	// Other techniques exist, of course.

	//! The materials structure.
	struct MESHMERIZER_API MBMaterials
	{
		MBMaterials()
		{
			MaterialInfo	= null;
		}
		udword			NbMtls;					//!< Number of materials found.
		MBMatInfo*		MaterialInfo;			//!< One structure for each material.
	};

	//! Result structure.
	struct MESHMERIZER_API MBResult
	{
		MBTopology		Topology;				//!< Result topology.
		MBGeometry		Geometry;				//!< Result geometry
		MBMaterials		Materials;				//!< Result materials
	};

	//
	// Pseudo-code showing how to use the consolidation and the striper result structures:
	// mVB is a DX7 vertex buffer filled thanks to the MBGeometry structure.
	// mResult is the MBResult structure.
	// mStripRuns and mStripLengths are from the STRIPERRESULT structure.
	//
	//	// Get indices
	//	uword* VRefs = mResult->Topology.VRefs;
	//	// Make one API call / material
	//	for(i=0;i<mResult->Materials.NbMtls;i++)
	//	{
	//		// Select correct material
	//		udword MaterialID = mResult->Materials.MaterialInfo[i].MatID;
	//		// Draw mesh
	//		if(mStripRuns)	renderer->DrawIndexedPrimitiveVB(PRIMTYPE_TRISTRIP, mVB, 0, mResult->Geometry.NbVerts, mStripRuns[i], mStripLengths[i]);
	//		else			renderer->DrawIndexedPrimitiveVB(PRIMTYPE_TRILIST, mVB, 0, mResult->Geometry.NbVerts, VRefs, mResult->Materials.MaterialInfo[i].NbFaces*3);
	//		// Update index pointer for trilists
	//		VRefs+=mResult->Materials.MaterialInfo[i].NbFaces*3;
	//	}
	//

//~for FLEXPORTER CARBON-COPY

	class MeshBuilder2;

//! Include Flexporter headers
#include "FLX_AddPRS.h"
#include "FLX_TimeInfo.h"
#include "FLX_ExportSettings.h"
#include "FLX_BaseInfo.h"
#include "FLX_CropValues.h"
#include "FLX_AddCamera.h"
#include "FLX_AddLight.h"
#include "FLX_AddMaterial.h"
#include "FLX_AddTexture.h"
#include "FLX_AddMesh.h"
#include "FLX_AddController.h"
#include "FLX_AddHelper.h"
#include "FLX_AddMotion.h"
#include "FLX_AddShape.h"
#include "FLX_BaseFormat.h"

#include "IceCharacterStudioNodes.h"

#define DLLEXPORT __declspec(dllexport)

// Exported functions

//! A character string describing the exporter. Appears in Flexporter's Options panel.
DLLEXPORT const char*		ExporterDescription();

//! The extension used for the plug-in's format. (e.g. "txt" for default ascii exporter)
DLLEXPORT const char*		FormatExtension();

//! Returns a pointer to the unique instance of an exporter.
DLLEXPORT ExportFormat*		GetExporter();

//! Returns the default settings for the exporter.
DLLEXPORT ExportSettings*	GetDefaultSettings();

//! Returns the enabled/disabled status for all settings
DLLEXPORT Enabled*			GetEnabled();

//! Returns FLEXPORTER_VERSION. (i.e. the SDK version, not Flexporter's version)
DLLEXPORT int				Version();

#endif // __FLEXPORTER_SDK__
