/// This file is part of the X3DToolKit library
/// Copyright (C) 2002-2004  Yannick Le Goc (legoc@imag.fr)

/// http://artis.imag.fr/Members/Yannick.Legoc/X3D/

/// This library is free software; you can redistribute it and/or
/// modify it under the terms of the GNU Lesser General Public
/// License as published by the Free Software Foundation; either
/// version 2.1 of the License, or (at your option) any later version.

/// This library is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
/// Lesser General Public License for more details.

/// You should have received a copy of the GNU Lesser General Public
/// License along with this library; if not, write to the Free Software
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#ifndef X3DTK_MESH_MESHDATA_H
#define X3DTK_MESH_MESHDATA_H

#include "X3DTypes.h"
#include "TypeList.h"
#include "MESH_SFFace.h"

#include <map>

namespace X3DTK {
namespace MESH {

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D vertex point data.
 *
 *  \ingroup MeshSceneGraph
 */

class VertexPointData
{
public:
  /// Sets the point.
  void setPoint(const SFPoint3f &point) {_point = point;};
  /// Gets the point.
  inline const SFPoint3f &getPoint() const {return _point;};
  
private:
  SFPoint3f _point;  
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D vertex normal data.
 *
 *  \ingroup MeshSceneGraph
 */

class VertexNormalData
{
public:
  /// Sets the normal of face. 
  void setNormalOfFace(const SFVec3f &normal, BaseSFFace *face);
  /// Gets the normal of face.
  const SFVec3f &getNormalOfFace(BaseSFFace *face) const;
  
  /// Gets the normal map.
  const std::map<BaseSFFace *, unsigned short> &getMap() const {return _normalMap;};
  /// Gets the normal array.
  const MFVec3f &getNormalArray() const {return _normalArray;};
  
private:
  MFVec3f _normalArray; 
  std::map<BaseSFFace *, unsigned short> _normalMap;
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D vertex color data.
 *
 *  \ingroup MeshSceneGraph
 */

class VertexColorData
{
public:
  /// Sets the normal of face.
  void setColorOfFace(const SFColorRGBA &color, BaseSFFace *face);
  /// Sets the normal of face.
  const SFColorRGBA &getColorOfFace(BaseSFFace *face) const;
  
  /// Gets the color map.
  const std::map<BaseSFFace *, unsigned short> &getMap() const {return _colorMap;};
  /// Gets the color array.
  const MFColorRGBA &getColorArray() const {return _colorArray;};
  
private:
  MFColorRGBA _colorArray;
  std::map<BaseSFFace *, unsigned short> _colorMap;
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D vertex texture coordinate data.
 *
 *  \ingroup MeshSceneGraph
 */

class VertexTexCoordData
{
public:
  /// Sets the normal of face.
  void setTexCoordOfFace(const SFPoint2f &texCoord, BaseSFFace *face);
  /// Sets the normal of face.
  const SFPoint2f &getTexCoordOfFace(BaseSFFace *face) const;

  /// Gets the texCoord map.
  const std::map<BaseSFFace *, unsigned short> &getMap() const {return _texCoordMap;};
  /// Gets the color array.
  const MFPoint2f &getTexCoordArray() const {return _texCoordArray;};
   
private:
  MFPoint2f _texCoordArray;
  std::map<BaseSFFace *, unsigned short> _texCoordMap;
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D face normal data.
 *
 *  \ingroup MeshSceneGraph
 */

class FaceNormalData
{
public:
  /// Sets the normal.
  void setNormal(const SFVec3f &normal) {_normal = normal;};
  /// Gets the normal.
  inline const SFVec3f &getNormal() const {return _normal;};
  
private:
  SFVec3f _normal;  
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D face color data.
 *
 *  \ingroup MeshSceneGraph
 */

class FaceColorData
{
public:
  /// Sets the normal.
  void setColor(const SFColorRGBA &color) {_color = color;};
  /// Gets the normal.
  inline const SFColorRGBA &getColor() const {return _color;};
  
private:
  SFColorRGBA _color;  
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D mesh normal data.
 *
 *  \ingroup MeshSceneGraph
 */

class MeshNormalData
{
public:
  /// Sets the boolean normal, true if vertex has normal.
  void setNormal(bool value) {_normal = value;};
  /// Sets the boolean normalPerVertex.
  void setNormalPerVertex(bool value) {_normalPerVertex = value;};
  /// Sets the crease angle.
  void setCreaseAngle(float value) {_creaseAngle = value;};
  
  /// Returns true if the Mesh has normals.
  inline bool hasNormal() const {return _normal;};
  /// Gets the boolean faceNormal.
  inline bool getNormalPerVertex() const {return _normalPerVertex;};
  /// Gets the crease angle.
  inline float getCreaseAngle() const {return _creaseAngle;};
  
private:
  bool _normal;
  bool _normalPerVertex;
  float _creaseAngle;
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D mesh color data.
 *
 *  \ingroup MeshSceneGraph
 */

class MeshColorData
{
public:
  /// Sets the boolean Color, true if vertex has Color.
  void setColor(bool value) {_color = value;};
  /// Sets the boolean colorPerVertex.
  void setColorPerVertex(bool value) {_colorPerVertex = value;};
  /// Sets the boolean RGBA.
  void setRGBA(bool value) {_rgba = value;};
  
  /// Returns true if the Mesh has Colors.
  inline bool hasColor() const {return _color;};
  /// Gets the boolean faceColor.
  inline bool getColorPerVertex() const {return _colorPerVertex;};
  /// Gets the boolean RGBA.
  inline bool getRGBA() const {return _rgba;};
  
private:
  bool _color;
  bool _colorPerVertex;
  bool _rgba;
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D mesh texture coordinate data.
 *
 *  \ingroup MeshSceneGraph
 */

class MeshTexCoordData
{
public:
  /// Sets the boolean TexCoord, true if vertex has TexCoord.
  void setTexCoord(bool value) {_texCoord = value;};
  /// Returns true if the Mesh has TexCoords.
  inline bool hasTexCoord() const {return _texCoord;};
  
private:
  bool _texCoord;
};

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default solid data.
 *
 *  \ingroup MeshSceneGraph
 */

class MeshSolidData
{
public:
  /// Sets the boolean solid, true if backculling is enabled.
  void setSolid(bool value) {_solid = value;};
  /// Returns true if the Mesh has TexCoords.
  inline bool isSolid() const {return _solid;};
  
private:
  bool _solid;
};


#ifdef TEMPLATE_SPECIALIZATION_SUPPORTED

/*! \brief Type declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D vertex datas.
 *
 *  \ingroup MeshSceneGraph
 */

typedef clist<tlist<VertexPointData, tlist<VertexNormalData, tlist<VertexColorData, tlist<VertexTexCoordData> > > > > VertexData;

/*! \brief Type declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D edge datas.
 *
 *  \ingroup MeshSceneGraph
 */

typedef nil EdgeData;

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D face data.
 *
 *  \ingroup MeshSceneGraph
 */

typedef clist<tlist<FaceNormalData, tlist<FaceColorData> > > FaceData;

/*! \brief Structure declared in <b><X3DTK/MESH/scenegraph.h></b> defining the default X3D mesh data.
 *
 *  \ingroup MeshSceneGraph
 */

typedef clist<tlist<MeshNormalData, tlist<MeshColorData, tlist<MeshTexCoordData, tlist<MeshSolidData> > > > > MeshData;

#else

class VertexData : public VertexPointData, public VertexNormalData, public VertexColorData, public VertexTexCoordData
{};

class EdgeData
{};

class FaceData : public FaceNormalData, public FaceColorData
{};

class MeshData : public MeshNormalData, public MeshColorData, public MeshTexCoordData, public MeshSolidData 
{};

#endif

}
}

#endif
