/*********************************************************************
*	Soubor matematických funkcí
*	HEADER FILE
*	Autor:	Michal Jirouš
*	Datum: 31.7.2008
*	Soubor:	mathematic.h
*	Popis:	Obsahuje ruzné matematické funkce - sinus, cosinus, které pracuj se stupni
*			funkce pro porovnávání datových typů float, převody řetězců na čísla
**********************************************************************/

#ifndef __MATHEMATIC_H___
#define __MATHEMATIC_H___

#include <math.h>
#include <string>
#include <float.h>

/* Definice přesností pro porovnávání datových typů float */
const float FLOAT_COMPARE_ACCURACY_VERY_LOW			= 0.5f;
const float FLOAT_COMPARE_ACCURACY_LOW				= 0.1f;
const float FLOAT_COMPARE_ACCURACY_BELOW_AVERAGE	= 0.01f;
const float FLOAT_COMPARE_ACCURACY_AVERAGE			= 0.001f;
const float FLOAT_COMPARE_ACCURACY_HIGH				= 0.00001f;
const float FLOAT_COMPARE_ACCURACY_PRECISION		= 0.0f;

//inicializace maximální a minimální hodnoty float
const float MAX_FLOAT = pow( 10.0f, FLT_MAX_10_EXP );
const float MIN_FLOAT = pow( 10.0f, FLT_MIN_10_EXP );

//Ludolfovo číslo
const float M_PI = 3.14159265358979323846f;
const float M_E = 2.71828182845904523536f;
const int SUM_MULTIPLICATOR = 119;

//upravene verze goniometrickych funkci pro pocitani se stupni a ne radiany
float mycos( float angle );	
float mysin( float angle );
float myacos( float angle );
float myasin( float angle);
float mytan( float angle );
float myatan( float value );

float angleToRad( float angle );
float radToAngle( float rad );

int stringToInt( std::string sValue );
float stringToFloat( std::string sValue);
float *stringToFloat4( std::string sValue);


int compareFloats( float a, float b, float resolution = FLOAT_COMPARE_ACCURACY_AVERAGE );
float roundDown( float x );
float roundUp( float x );
float round( float x );
float round( float x, int positions );
int getMaximumPowerOf( int iValue );	//vrací první nalezenou druhou mocninu, která je větší než číslo iValue
bool getFileSum( const char * filename, int &sum, size_t &size );


template <typename T>
bool isInRange( T value, T min, T max )
{
	return !((value < min) || (value > max));
}

template <typename T>
T getFromRange( T fValue, T fMin, T fMax)	//TODO
{
	return std::max( fMin, std::min( fMax, fValue) );
}

//nasobeni matic - optimalizovano pro OpenGL ( pracuje s matici ve formatu 16 hodnot v jednom poli )
template <typename T>
void matrixMult( T *transformationMatrix_16_values, T *transformatedPoint_4_values , T *result_4_values )
{
	for( int i = 0; i < 4; i++ )
		result_4_values[i] = 0;
	for( int i = 0; i < 16; i++ )
	{
		result_4_values[ i / 4 ] += transformationMatrix_16_values[i] * transformatedPoint_4_values[ i % 4 ];
	}
}

template <typename T>
void matrixMultFastTransformPoint( T *matrix16, T *target, T *result )
{
	result[0] = matrix16[0] * target[0] + matrix16[1] * target[1] + matrix16[2] * target[2];
	result[1] = matrix16[4] * target[0] + matrix16[5] * target[1] + matrix16[6] * target[2];
	result[2] = matrix16[8] * target[0] + matrix16[9] * target[1] + matrix16[10] * target[2];
}



#endif
