#ifndef CVERTEXINFOGARLAND_H
#define CVERTEXINFOGARLAND_H

#include <features/CVertexInfoMV.h>
#include <features/CVertexInfoGenerator.h>

//==============================================================================
/**
 * VertexInfoGarland class
 * - vertex info Garland is the zero-mean covariance matrix and it's eigenvalues
 * - this is needed for each vertex when doing the eigensmooth method
 */
class CVertexInfoGarland : public CVertexInfoMV
{
    public :

            //! Constructor parametrized by vertex
            CVertexInfoGarland( vctl::MCVertex * vertex );

            //! Destructor
            virtual ~CVertexInfoGarland();

};

//==============================================================================
/**
 * VertexInfoGeneratorGarland class
 * - generator, that creates zero-mean covariance features for the whole mesh
 */
class CVertexInfoGeneratorGarland : public CVertexInfoGenerator
{
    public :

			//! Smart pointer declaration
            MDS_SHAREDPTR( CVertexInfoGeneratorGarland );

    public :

			//! Two ways of computing the feature
            enum
            {
                FROM_VERTICES   =   0x1,	// from neighbourhood vertices normals
                FROM_TRIANGLES  =   0x2,	// from neighbourhood triangles normals ( default )
            };

			//! Two types of covariance matrices from which the feature is computed
            enum
            {
                TYPE_GARLAND    =   0x1,	// zero-mean covariance matrix
                TYPE_COVARIANCE =   0x2,	// standard covariance matrix against average normal
            };

    protected :

            //! Neighbourhood size
            int			iSize;

            //! Type of feature
            unsigned    iType;

            //! Type of source primitives
            unsigned    iSource;

            //! Flags for additional processing of the feature
            bool        bInvert, bNormalize, bTrim, bCont;

    public :

            //! Standard constructor
            CVertexInfoGeneratorGarland( unsigned type = TYPE_GARLAND, unsigned source = FROM_TRIANGLES, int iSize = 1, bool cont = false );

            //! Destructor
            virtual ~CVertexInfoGeneratorGarland();

            //! Nonequality operator 
            bool    operator!= ( const CVertexInfoGeneratorGarland & g );

            //! Virtual method that generates 
            virtual bool generate( CSmoothingMesh * mesh );

            //! Initialization method
            virtual bool init();

            //! Additional method for creating standard covariance matrices from vertices normals
            void    xMatrixVertCov( vctl::MCVertex * vertex, CSmoothingMesh * mesh, mds::math::CDMatrix & X );

            //! Additional method for creating zero-mean covariance matrices from vertices normals
            void    xMatrixVertGar( vctl::MCVertex * vertex, CSmoothingMesh * mesh, mds::math::CDMatrix & X );

            //! Additional method for creating standard covariance matrices from triangle normals
            void    xMatrixTriCov( vctl::MCVertex * vertex, CSmoothingMesh * mesh, mds::math::CDMatrix & X );

            //! Additional methods for creating zero-mean covariance matrices from triangle normals
            void    xMatrixTriGar( vctl::MCVertex * vertex, CSmoothingMesh * mesh, mds::math::CDMatrix & X );

            //! Normalization
            virtual void normalize();

            //! Sets neighbourhood size
            void    setSize( int size )
            {
                iSize = size;
            }

            //! Returns neighbourhood size
            int     getSize()
            {
                return iSize;
            }

            //! Sets feature type
            void    setType( unsigned type )
            {
                iType = type;
            }

            //! Returns feature type
            unsigned    getType()
            {
                return iType;
            }

            //! Sets feature source
            void    setSource( unsigned source )
            {
                iSource = source;
            }

            //! Returns feature source
            unsigned    getSource()
            {
                return iSource;
            }

			//! Sets cont
            bool        setCont( bool cont )
            {
                bCont = cont;
            }


    public :

			//! Returns new instance of this feature (obsolete)
            static CVertexInfoGenerator * create();

};

#endif // CVERTEXINFOGARLAND_H
