#ifndef CCMIO_TEST_MESH_H
#define CCMIO_TEST_MESH_H

#include <vector>
#include <string>
#include <map>
#include "ccmio.h"
#include "IOException.h"

#define kMaxPolygonSize		64
struct MeshVertex
{
    int id;
    float coord[3];
};

struct MeshCell
{
    int id;
    int type;
};

struct MeshFace
{
    int id;
    int cells[2];
    bool isBoundary;
    int boundary;
    int nVerts;
    int verts[kMaxPolygonSize];
};

class Mesh {
 public:
    typedef std::vector< MeshVertex > VertexArray;
    typedef std::vector< MeshCell > CellArray;
    typedef std::vector< MeshFace > FaceArray;
    typedef std::vector< std::map< int, int > > CellVertsArray;

    Mesh() : nVertices(0), nCells(0), err(kCCMIONoErr), noCheck(false) {};

    bool operator== ( const Mesh& that );
    inline bool operator!= ( const Mesh& that )
	{ return(!(*this == that)); };
    void PrintInfo();
    void WriteCCMIO( CCMIOID& state, CCMIOID& processor );
    void OffsetIDs( int offset );
    inline CCMIOError GetError() { return(err); };
    inline void CopyCells( const Mesh& mesh )
	{
	    this->cells = mesh.cells;
	}
#if 0
    inline void SetNoCheckCellsAndBoundaries( bool enable )
	{ this->noCheck = true; }
    inline std::string<char> GetFilename()
	{ return(this->filename); }
#endif

    void CheckFaceOrientation(CellVertsArray& cells);
    static bool CreateCellVertsArray( const Mesh& mesh, CellVertsArray& cells );

 //protected:
 public:
    VertexArray vertices;	// Unpacked vertices
    VertexArray packedVerts;	// Packed copies of the vertices
    CellArray cells;		// Unpacked cells
    std::vector<bool> cellUsed;
    FaceArray internalFaces;
    FaceArray boundaryFaces;
    int nBoundaries;
    int nVertices;
    int nCells;
    CCMIOError err;
    bool noCheck;
    std::string filename;

    static bool CompareInternalFace( const Mesh& mesh1,
				     const MeshFace& face1,
				     const Mesh& mesh2,
				     const MeshFace& face2 );
    static bool CompareBoundaryFace( const Mesh& mesh1,
				     const MeshFace& face1,
				     const Mesh& mesh2,
				     const MeshFace& face2 );
    static bool CompareFaceVertices( const Mesh& mesh1,
				     const MeshFace& face1,
				     const Mesh& mesh2,
				     const MeshFace& face2 );
    static void PrintFaceError( const Mesh& mesh1, const MeshFace& face1,
				const Mesh& mesh2, const MeshFace& face2,
				bool isInternal);

    bool FindFace(int id, FaceArray::iterator& fit);

    template <class T>
    CCMIOID CreateIndexMap( std::vector<T>& items, CCMIOID& entity,
			  CCMIOEntity type, const char *description,
			  bool isCell = false );
};

#endif // CCMIO_TEST_MESH_H
