/*  Copyright (C) 2008-2013 National Institute For Space Research (INPE) - Brazil.

    This file is part of the TerraLib - a Framework for building GIS enabled applications.

    TerraLib 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 3 of the License,
    or (at your option) any later version.

    TerraLib 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 TerraLib. See COPYING. If not, write to
    TerraLib Team at <terralib-team@terralib.org>.
 */

/*! 
  \file terralib/geometry/WKTActions.h

  \brief A class that implements the semanthic actions to grammar rules for well known text (WKT) format for Geometry.
         Basically, the class is responsible to generate a geometry element.

  \warning Do not use this class. It is for TerraLib internal use. Try the te::gm::WKTReader instead.
*/

#ifndef __TERRALIB_GEOMETRY_INTERNAL_WKTACTIONS_H
#define __TERRALIB_GEOMETRY_INTERNAL_WKTACTIONS_H

// TerraLib
#include "Enums.h"

// boost
#include <boost/spirit/include/qi.hpp>

namespace te
{
  namespace gm
  {
// Forward declarations
    class Geometry;
    class LineString;
    class Point;
    class Polygon;
    class PolyhedralSurface;
  
    /*!
      \class WKTActions
      
      \brief A class that implements the Grammar Rules for well known text (WKT) format for Geometry.
     */
    class WKTActions
    {
      public:

        /** @name Constructor
         *  Initilizer methods.
         */
        //@{

        /*! \brief Default constructor. */
        WKTActions();

        /*! \brief Destructor. */
        ~WKTActions();

        //@}

        /*! 
          \brief This method resets the Action class to original state. 
          
          \note Should be called case the parser processing faill.
          \note Basically, it is responsable to free the memory.
         */
        void reset();

        /** @name Actions methods.
          * Actions methods to WKT geometry parser.
          */
        //@{

        void createPoint(const boost::fusion::vector2<double, double>& c);

        void createPointZ(const boost::fusion::vector3<double, double, double>& c);

        void createPointM(const boost::fusion::vector3<double, double, double>& c);

        void createPointZM(const boost::fusion::vector4<double, double, double, double>& c);

        void createPoint();

        void createPointZ();

        void createPointM();

        void createPointZM();

        void createLine();

        void createLineZ();

        void createLineM();

        void createLineZM();

        void createLinearRing();

        void createLinearRingZ();

        void createLinearRingM();

        void createLinearRingZM();

        void createPolygon();

        void createPolygonZ();

        void createPolygonM();

        void createPolygonZM();

        void createMultiPoint();

        void createMultiPointZ();

        void createMultiPointM();

        void createMultiPointZM();

        void createMultiLineString();        

        void createMultiLineStringZ();

        void createMultiLineStringM();

        void createMultiLineStringZM();

        void createMultiPolygon();

        void createMultiPolygonZ();

        void createMultiPolygonM();

        void createMultiPolygonZM();

        void createPolyhedralSurface();

        void createPolyhedralSurfaceZ();

        void createPolyhedralSurfaceM();

        void createPolyhedralSurfaceZM();

        void createTIN();

        void createTINZ();

        void createTINM();

        void createTINZM();

        void createTriangle();

        void createTriangleZ();

        void createTriangleM();

        void createTriangleZM();

        void createGeometryCollection();

        void createGeometryCollectionZ();

        void createGeometryCollectionM();

        void createGeometryCollectionZM();

        void endGeometry();

        void end();

        //@}

        /** @name Access method.
        * Method to access the geometry generated.
        */
        //@{

        /*!
          \brief It returns the geometry generated by the parser process.

          \note The caller of this method will take the ownership of the geometry.
         */
        Geometry* getGeometry();

        //@}

      private:

        /** @name Auxiliaries methods.
        * Auxiliaries methods to WKT geometry parser.
        */
        //@{
        
        void buildLine(LineString* l);

        void buildPolygon(const GeomType& t);

        void buildPolygon(Polygon* p);

        void buildMultiPoint(const GeomType& t);

        void buildMultiLineString(const GeomType& t);

        void buildMultiPolygon(const GeomType& t);

        void buildPolyhedralSurface(PolyhedralSurface* ps);

        void buildGeometryCollection(const GeomType& t);
       
        //@}

      private:

        Geometry* m_g;                          //<! Result geometry generated by the parser process.

        std::vector<Point*>      m_points;      //<! Set of point that can be generated during the parser process.
        std::vector<LineString*> m_lines;       //<! Set of lines that can be generated during the parser process.
        std::vector<Polygon*>    m_polygons;    //<! Set of polygon that can be generated during the parser process.
        std::vector<Geometry*>   m_geometries;  //<! Set of geometries that can be generated during the parser process.
    };

  } // namespace gm
}   // namespace te

#endif  // __TERRALIB_GEOMETRY_INTERNAL_WKTACTIONS_H

