//#include <osg/MatrixTransform>
//#include <osg/Projection>

//==============================================================================
/*! \file
 * OpenMesh Toolkit for mesh analysis    \n
 * Copyright (c) 2010 by Rostislav Hulik     \n
 *
 * Author:  Rostislav Hulik, rosta.hulik@gmail.com  \n
 * Date:    2010/10/20                          \n
 *
 * This file is part of software developed for support of Rostislav Hulik's dissertation thesis at dcgm-robotics@FIT group.
 *
 * This file 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.
 * 
 * This file 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 file.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Description:
 * - Class for Visualizing directions from each element (normal, curvature direction etc)
 */

#ifndef _OM_DIRECTIONS_GEO_HXX_
#define _OM_DIRECTIONS_GEO_HXX_

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor
// Creates an instance of this class by drawing vectors specified by handle from each vertex
// @param mesh Mesh to work with
// @param handle Handle to vector vertex property
// @param norm Lenght of showed distances
// @param defaultColor Default color of visualised normal
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <class Mesh, class Vector>
OMDirectionsGeometry<Mesh, Vector>::OMDirectionsGeometry(Mesh &mesh, OpenMesh::VPropHandleT<Vector> handle, ScalarT norm, Vec4f defaultColor)
{
	ref_ptr<Vec3Array> vertices = new Vec3Array();	
	DrawElementsUInt *indices =new DrawElementsUInt(PrimitiveSet::LINES, 0);
	ref_ptr<Vec4Array> colors = new Vec4Array();

	Mesh::Normal normal;
	Mesh::VertexIter end = mesh.vertices_end();
	Mesh::Point point;
	unsigned int i = 0;
	// pass each vertex and add two points and line
	for (Mesh::VertexIter it = mesh.vertices_begin(); it != end; ++it)
	{
		point = mesh.point(it);
		normal = mesh.property(handle, it);
		normal *= norm;
		vertices->push_back(Vec3(point[0], point[1], point[2]));
		vertices->push_back(Vec3(normal[0]+point[0], normal[1]+point[1], normal[2]+point[2]));

		indices->push_back(i);
		indices->push_back(i+1);

		i+=2;
	}

	colors->push_back(defaultColor);
	setColorArray(colors);
	setColorBinding(Geometry::BIND_PER_PRIMITIVE_SET);
	getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
	setVertexArray(vertices);
	addPrimitiveSet(indices);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor
// Creates an instance of this class by drawing vectors specified by handle from each face
// @param mesh Mesh to work with
// @param handle Handle to vector vertex property
// @param norm Lenght of showed distances
// @param defaultColor Default color of visualised normal
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <class Mesh, class Vector>
OMDirectionsGeometry<Mesh, Vector>::OMDirectionsGeometry(Mesh &mesh, OpenMesh::FPropHandleT<Vector> handle, ScalarT norm, Vec4f defaultColor)
{
	ref_ptr<Vec3Array> vertices = new Vec3Array();	
	DrawElementsUInt *indices =new DrawElementsUInt(PrimitiveSet::LINES, 0);
	ref_ptr<Vec4Array> colors = new Vec4Array();

	Mesh::Normal normal;
	Mesh::FaceIter end = mesh.faces_end();
	Mesh::Point point;
	unsigned int i = 0;

	// pass each face and add two points and line
	for (Mesh::FaceIter it = mesh.faces_begin(); it != end; ++it)
	{
		mesh.calc_face_centroid(it, point);
		normal = mesh.property(handle, it);
		normal *= norm;
		vertices->push_back(Vec3(point[0], point[1], point[2]));
		vertices->push_back(Vec3(normal[0]+point[0], normal[1]+point[1], normal[2]+point[2]));

		indices->push_back(i);
		indices->push_back(i+1);

		i+=2;
	}

	colors->push_back(defaultColor);
	setColorArray(colors);
	setColorBinding(Geometry::BIND_PER_PRIMITIVE_SET);
	getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
	setVertexArray(vertices);
	addPrimitiveSet(indices);
}

#endif