/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NGEOREDUCER__
#define __NGEOREDUCER__


		#include "math/vector.h"


namespace GS {
	namespace Core {
		class Geometry;

struct	nLLEDGE
{
	uint		a, b;
	nLLEDGE		*p, *n;
};

struct	nEENTRY
{
	nLLEDGE	*edge;
	nEENTRY	*n;
};

typedef	nEENTRY *	pnEENTRY;

class	nEDGELIST
{
public:

		pnEENTRY	*lut;
		nLLEDGE		*root;
		uint		vtx_count, nedg;

		void		SetVertexCount(uint);
		void		Add(uint, uint);
		void		Remove(nLLEDGE *);
		void		RemapEdges(uint, uint);
		nLLEDGE		*GetEdge(uint, uint);

		nEDGELIST ();
		~nEDGELIST ();
};

class	nLLTRI
{
public:

		uint		a, b, c;
		ushort		m;
		Vector4		normal;
		nLLTRI		*p, *n;

		char		UseVertex(uint);
		void		ReplaceVertex(uint, uint);
};

struct	nTENTRY
{
	nLLTRI	*tri;
	nTENTRY	*n;
};

typedef	nTENTRY *	pnTENTRY;

class	nLTRILIST
{
public:

		pnTENTRY	*lut;
		nLLTRI		*root;
		Geometry	*sg;

		void		SetGeo(Geometry *);
		nLLTRI		*Add(uint, uint, uint);
		void		ReplaceVertex(uint, uint);
		void		AddTriToVertex(nLLTRI *, uint);
		void		RemoveTriFromVertex(nLLTRI *t, uint v);
		void		Remove(nLLTRI *);
		void		ComputeNormal(nLLTRI *);

		uint		ntri;

		nLTRILIST ();
		~nLTRILIST ();
};

struct	nLVERTEX
{
		char		active, locked;
		float		cost;
		uint		tgtcollapse;
};

class	GeometryReducer
{
public:

		nEDGELIST			elist;
		nLTRILIST			tlist;
		nLVERTEX			*vlist;

		nLVERTEX			*AddVertex(uint v);
		void				RemoveVertex(uint v);
		void				ComputeVertexCost(Geometry *, uint);
		float				ComputeEdgeCost(Geometry *, nLLEDGE *);
		Geometry			*Reduce(Geometry *, float k);
		char				IsBorder(uint v);
};

	} // Core
} // GS


#endif	// __NGEOREDUCER__