#ifndef VRMLSHAPE_H
#define VRMLSHAPE_H

#include <cassert>
#include <vector>
using namespace std;

#include <typedefs.h>

/*
\brief  Using VRML as a primitive graphics format.

 EVERYTHING IS TRIANGLES,
 NON-TRIANGLE STRUCTURES ARE NOT SUPPORTED.
 (possible extensions are lines, because primitive)

 Using VRML as a primitive graphics format this data
 structure represents two different formats: 
   -  Primitive VRML
   -  Triangle Stream.
  
 The write{P,PN,PNC} expect the data in Triangle Stream
 format where the corresponding vectors are triangles.
*/
class vrmlshape
{
public:

  /** Each 3 floats is a point and 3 points per triangle. */
  vector<float> point;
  /** Each 3 floats is a normal and 3 normals per triangle. */
  vector<float> normal;
  /** Each 3 floats is a color and 3 colors per triangle. */
  vector<float> color;
  
  /** The global color. */
  float diffuseColor[3];
  /** Write the diffuse color if it is enabled by having
      non negative values. */
  void diffuseColorWrite() const;

  /** For debug print out the classes attributes. */
  ostream & print( ostream & os ) const;

  /** Write wireframe triangles. */
  void writeP() const;
  /** Write Point and Normal per point triangles. */
  void writePN() const;
  /** Write Point, Normal and Color per point triangles. */
  void writePNC() const;

  /** Write the triangles winding by coloring in the 
      vertices Red, Green and Blue. */
  void writePwind() const;
};


/*!
\brief Line Geometry.
*/
class vrmllines
{
public:

  /** Each 3 floats is a point and two consecutive
      points is a line. */
  vector<float> point;
  /** Each 3 floats is a color and two consecutive
      colors is a line. */
  vector<float> color;

  /** Write lines with the points. */
  void writeP() const;
  /** Write a point and color per vertex. */
  void writePC() const;

  /** Used for debugging purposes, the normals are 
      added to the geometry as lines in this class.  */
  template< typename T >
  void addnormals
  ( 
    vrmlshape& s,
    T const & col,
    floatc len
  )
  {
    if (s.normal.empty())
      return;

    uintc imax = s.normal.size();
    for (uint i=0; i<imax; i+=3)
    {
      point.push_back( s.point[i] );
      point.push_back( s.point[i+1] );
      point.push_back( s.point[i+2] );

      point.push_back( s.point[i]+len*s.normal[i] );
      point.push_back( s.point[i+1]+len*s.normal[i+1] );
      point.push_back( s.point[i+2]+len*s.normal[i+2] );

      color.push_back(col[0]);
      color.push_back(col[1]);
      color.push_back(col[2]);
      color.push_back(col[0]);
      color.push_back(col[1]);
      color.push_back(col[2]);
    }
  }
};

#endif



