/**********************************************************************
 *<
	FILE: edmdata.h

	DESCRIPTION:  Some stuff used by the edit mesh modifier that is
	              useful for some of the other modifiers

	CREATED BY: Rolf Berteig

	HISTORY: created 18 March, 1995

 *>	Copyright (c) 1994, All Rights Reserved.
 **********************************************************************/

#ifndef __EDMDATA__
#define __EDMDATA__

class AdjEdgeList;
class AdjFaceList;

#ifndef UNDEFINED
#define UNDEFINED	0xffffffff
#endif

class MEdge {
	public:
		DWORD f[2];
		DWORD v[2];
		
		int EdgeIndex(Face *faces,int side);
		BOOL Selected(Face *faces,BitArray &esel);
		Point3 Center(Point3 *verts);
		Point3 ButterFlySubdivide(Mesh *mesh,AdjFaceList *af,float tens);
		BOOL AFaceSelected(BitArray &fsel);
	};

class AdjEdgeList {
	public:
		DWORDTab *list; 	// 1 DWORDTab per vertex. The Tab is a list of indices into the edge list, 1 for each edge adjacent to the vertex
		Tab<MEdge> edges;	// Table of edges
		int nverts;			// size of 'list'.

		AdjEdgeList(Mesh& amesh);
		~AdjEdgeList();
		AdjEdgeList& operator=(AdjEdgeList& a) {assert(0);return *this;}
		void AddEdge( DWORD fi, DWORD v1, DWORD v2 );
		DWORDTab& operator[](int i) { return list[i]; }
		int FindEdge(DWORD v0, DWORD v1);
		void RemoveEdgeFromVertex(DWORD v,DWORD e);
		void AddEdgeToVertex(DWORD v,DWORD e);
	};


class AdjFace {
	public:
		DWORD f[3];
		AdjFace() { f[0] = f[1] = f[2] = UNDEFINED; }		
	};

class AdjFaceList {
	public:
		Tab<AdjFace> list;

		AdjFace& operator[](int i) { return list[i]; }
		AdjFaceList(Mesh& mesh,AdjEdgeList& el);
	};

class FaceClusterList {
	public:
		// Cluster #, one for each face - non-selected faces have UNDEFINED for their id.
		DWORDTab clust;
		DWORD count;
	
		// This version separates cluster also using a minimum angle and optionally the selection set
		FaceClusterList(Mesh *mesh, AdjFaceList& adj,float angle,BOOL useSel=TRUE);
		void ClusterID(Mesh *mesh, int f, AdjFaceList& adj, DWORD id, float angle,BOOL useSel);

		// Uses selection set
		FaceClusterList(BitArray& fsel, AdjFaceList& adj);
		void ClusterID(int f,BitArray& fsel, AdjFaceList& adj, DWORD id);
				
		DWORD operator[](int i) { return clust[i]; }
		void MakeVertCluster(Mesh &mesh,DWORDTab& vclust);
	};


class EdgeClusterList {
	public:
		DWORDTab clust;
		DWORD count;
		
		EdgeClusterList(Mesh &mesh,BitArray &esel,AdjEdgeList &adj);
		BOOL ClusterID(Mesh& mesh, int index, BitArray& esel, AdjEdgeList& adj, DWORD id);
		DWORD ID(int f, int e) {return clust[f*3+e];}
		DWORD operator[](int i) {return clust[i];}
		void MakeVertCluster(Mesh &mesh,DWORDTab& vclust);
	};


class FaceElementList {
	public:
		// For each face, which element is it in
		DWORDTab elem;
		DWORD count;
		FaceElementList(Mesh &mesh,AdjFaceList& af);
		void AddFacesToElem(int face,Mesh &mesh,AdjFaceList& af,DWORD e);
		DWORD operator[](int i) {return elem[i];}
	};

void FlipMeshNormal(Mesh *mesh,DWORD face);

#endif // __EDMDATA__

