//==============================================================================
/*! \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 OpenMesh export into OpenSceneGraph.
 */

#ifndef _OM_GEOMETRY_H_
#define _OM_GEOMETRY_H_

#include <OpenMesh\Tools\Utils\Timer.hh>
#include <OMToolkit\OMErrorLog.h>
#include <MDSTk\Base\mdsGlobalLog.h>
#include <OpenMesh\Core\IO\exporter\ExporterT.hh>
#include <OMToolkit\OMTypes.h>

#include <osg/Geometry>

namespace osg
{

/**
 * Class representing an interface between OpenMesh and OSG
 * It's inherited from standart osg::Geometry, co it's easy to add mesh geometry into any osg node
 */
template <class Mesh>
class OMGeometry : public Geometry
{
	public:
		/**
		 * Typedef for specifiing additional model attributes 
		 */
		typedef unsigned char AttributeBinding;
			
		/**
		 * Normals will be not added into osg
		 */
		static const AttributeBinding NORMAL_NONE = 1;
	
		/**
		 * Normals will be bound per vertex
		 * If there is no normal associated with vertices, they will be computed
		 */
		static const AttributeBinding NORMAL_PER_VERTEX = 2;
	
		/**
		 * Normals will be bound per face
		 * If there is no normal associated with faces, they will be computed
		 */
		static const AttributeBinding NORMAL_PER_FACE = 4;
	
		/**
		 * Color will not be specified in osg 
		 */
		static const AttributeBinding COLOR_NONE = 8;
	
		/**
		 * Color will be bound per vertex
		 * If there is no color associated with vertices, a default color will be added
		 */
		static const AttributeBinding COLOR_PER_VERTEX = 16;
	
		/**
		 * Color will be bound per face
		 * If there is no color associated with faces, a default color will be added
		 */
		static const AttributeBinding COLOR_PER_FACE = 32;
			
		/**
		 * Constructor - creates an instance of Geometry from an OpenMesh mesh
		 * @param mesh OpenMesh mesh to be converted
		 * @param binding Specifies additional attributes for mesh generation normal binding and color binding. If there is no normal in Mesh, they will be computed
		 * @param defaultColor Specifies default color which will be added, if there is no color attribute in Mesh
		 * @see AttributeBinding
		 */
		OMGeometry(Mesh mesh, AttributeBinding binding = NORMAL_PER_FACE | COLOR_PER_VERTEX, Vec4 &defaultColor = Vec4(0.5, 0.5, 0.5, 1.0));
	
		/**
		 * Allows testing if geometry was successfully loaded
		 * @return True, if all the model was loaded successfully.
		 */
		bool isLoadedOk();

	private:

		/**
		 * Flag is true if loading was successfull
		 */
		bool loaded_done;

		/**
		 * Loads vertices into osg from OpenMesh
		 * @param mesh Structure with a mesh to be loaded
		 * @return True if there was no problem with adding all the vertices.
		 */
		bool LoadVertices(Mesh mesh);
	
		/**
		 * Loads faces into osg from OpenMesh
		 * @param mesh Structure with a mesh to be loaded
		 * @return True if there was no problem with adding all the faces.
		 */
		bool LoadFaces(Mesh mesh);
	
		/**
		 * Loads and associes colors into osg from OpenMesh
		 * @param mesh Structure with a mesh to be loaded
		 * @param defaultColor If there is no color in OpenMesh, this color will be associated to every vertex/face
		 * @param binding OSG color binding.
		 * @see AttributeBinding
		 * @return True if there was no problem with adding all the colors.
		 */
		bool LoadColor(Mesh mesh, osg::Vec4 &defaultColor = Vec4(1.0, 1.0, 1.0, 1.0), Geometry::AttributeBinding binding = Geometry::BIND_PER_VERTEX);
	
		/**
		 * Loads and associes normals into osg from OpenMesh (if there is no normals, they will be computed)
		 * @param mesh Structure with a mesh to be loaded
		 * @param binding OSG normal binding.
		 * @see AttributeBinding
		 * @return True if there was no problem with adding all the normals.
		 */
		bool LoadNormals(Mesh mesh, Geometry::AttributeBinding binding = Geometry::BIND_PER_PRIMITIVE);
	}; // class OMGeometry

#include <OMToolkitOSG/OMGeometry.hxx>
}
#endif