//==============================================================================
/*! \file
 * OpenMesh Toolkit for mesh analysis    \n
 * Copyright (c) 2010 by Rostislav Hulik     \n
 *
 * Author:  Rostislav Hulik, rosta.hulik@gmail.com  \n
 * Date:    2010/11/08                          \n
 *
 * Copyright (C) Brno University of Technology
 *
 * 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:
 * - Methods computing a mesh color from specified scalar attributes
 * - Color is set like unsigned char vector (r, g, b, 255)
 */

#ifndef _OM_VISUALISER_H_
#define _OM_VISUALISER_H_

#include <OpenMesh\Core\Mesh\BaseKernel.hh>
#include <OpenMesh\Core\IO\importer\ImporterT.hh>
#include <OMToolkit\OMSerializableVector.h>

namespace OMToolkit {

/**
 * Class computing a mesh color from specified scalar attributes
 * @tparam Mesh Specifies a mesh type to work with
 * @tparam Scalar Specifies a scalar type of attribute (Attention, class expects a scalar type!!)
 */
template <class Mesh, class Scalar>
class OMVisualiser 
{
	public:
		/**
		 * Constructor - creates a link to a mesh and initializes variables
		 * @param mesh Pointer to a mesh
		 */
		OMVisualiser(Mesh *mesh);	

		/**
		 * Computes colors from a vertex scalar property and saves them into mesh
		 * @param vertexProperty Handle to a property, from which we will compute colors
		 * @param ommitExtremaPercent Number of percent which will be ommited from extrema (for ex. value 2.0 ommits 2% of brightest and darkest points)
		 */
		void ComputeColors(OpenMesh::VPropHandleT<Scalar> vertexProperty, Scalar ommitExtremaPercent);
		
		/**
		 * Computes colors from a face scalar property and saves them into mesh
		 * @param vertexProperty Handle to a property, from which we will compute colors
		 * @param ommitExtremaPercent Number of percent which will be ommited from extrema (for ex. value 2.0 ommits 2% of brightest and darkest points)
		 */
		void ComputeColors(OpenMesh::FPropHandleT<Scalar> faceProperty, Scalar ommitExtremaPercent);

		/**
		 * Returns values of Red, Green and Blue extremas (for painting a legend)
		 * @param maxBlue Property value for (0, 0, 255, 255) color
		 * @param maxGreen Property value for (0, 255, 0, 255) color
		 * @param maxRed Property value for (255, 0, 0, 255) color
		 */
		void getLegend(Scalar &maxBlue, Scalar &maxGreen, Scalar &maxRed);
	
	protected:

		/**
		 * Method computes a color from given value
		 * @param current Property value
		 * @return Color vector
		 */
		OpenMesh::Vec4uc getColor(Scalar current);

		/**
		 * Intern pointer to a mesh
		 */
		Mesh *m_mesh;

		/**
		 * Importer for mesh saving
		 */
		OpenMesh::IO::ImporterT<Mesh> importer;

		/**
		 * Intern red maximum
		 */
		Scalar m_maxRed;

		/**
		 * Intern green maximum
		 */
		Scalar m_maxGreen;

		/**
		 * intern blue maximum
		 */
		Scalar m_maxBlue;

		/**
		 * Difference between real values and shifted ones
		 */
		Scalar m_Difference;
}; // class OMVisualiser

/**
 * Extension of Visualiser to handle vector types
 * @tparam Mesh Mesh type to work with
 * @tparam Vector Vector type of the property
 */
template <class Mesh, class Vector>
class OMVectorVisualiser : public OMVisualiser<Mesh, typename Vector::value_type>
{
	protected:
		/**
		 * Vector scalar type
		 */
		typedef typename Vector::value_type Scalar;

	public:
		/**
		 * Constructor - creates a link to a mesh and initializes variables
		 * @param mesh Pointer to a mesh
		 */
		OMVectorVisualiser(Mesh *mesh) : OMVisualiser<Mesh, Scalar>(mesh)
		{
		}

		/**
		 * Computes colors from a vertex vector property and saves them into mesh
		 * @param vertexProperty Handle to a property, from which we will compute colors
		 * @param vectorComponent Number of vector component to be visualised
		 * @param ommitExtremaPercent Number of percent which will be ommited from extrema (for ex. value 2.0 ommits 2% of brightest and darkest points)
		 */
		bool ComputeColors(OpenMesh::VPropHandleT<Vector> vertexProperty, unsigned int vectorComponent, Scalar ommitExtremaPercent);
		
};

/**
 * Method computes a color from given value
 * @param current Property value
 * @param min Minimal value
 * @param max Maximal value
 * @return Color vector
 */
OpenMesh::Vec4uc getColor(float current, float min, float max);

#include <OMToolkit\OMVisualiser.hxx>

} // namespace OMToolit
#endif