// This is a part of the Object Oriented Mathematical Library
// Copyright (C) 1999-2008 Renishaw plc
//
// This source file is the confidential property of Renishaw plc.
// Reproduction or transmission in whole or in part, in any form or
// by any means, electronic, mechanical or otherwise, is prohibited
// without the prior written consent of the copyright owner.
//
// objfloat.h -- floating point arithmetic
//               global utilities: types, constants, variables and functions


#ifndef __OBJFLOAT_H__
#define __OBJFLOAT_H__


// ========================================================================================================================
#include "OOMathsExport.h"
// This is needed to set default params to the functions to follow
#include "ObjValue.h"

// 03/12/07 - New includes added for fix for bug #7321
#include <map> // Required to create maps
#include "Windows.h" // Required to access thread ID's
using namespace std;

// 03/12/07 - Map and pairs types defined for storing tolerance values
typedef map <DWORD, double> DWORD_2_DOUBLE_MAP;
typedef pair <DWORD, double> DWORD_DOUBLE_PAIR, *LPDWORD_DOUBLE_PAIR;

// ========================================================================================================================
// 03/12/07 - Get and set methods for each tolerance created. The tolerances will now
// only be accessible via these methods. The default parameters for the set methods are
// defined in objvalue.h.
OOMATHS_API void MaSetLarge(double Max = MaLargeDefault);
OOMATHS_API double MaGetLarge();
OOMATHS_API void MaSetZero(double Min = MaZeroDefault);
OOMATHS_API double MaGetZero();
OOMATHS_API void MaSetTol(double Epsilon = MaTolDefault);
OOMATHS_API double MaGetTol();
OOMATHS_API void MaSetSqrtTol(double Epsilon = MaSqrtTolDefault);
OOMATHS_API double MaGetSqrtTol();
OOMATHS_API void MaSetLengthTol(double LengthTol = MaLengthTolDefault);
OOMATHS_API double MaGetLengthTol();
OOMATHS_API void MaSetMinEdgeLength(double MinEdgeLength = MaMinEdgeLengthDefault);  
OOMATHS_API double MaGetMinEdgeLength();
OOMATHS_API void MaSetDegreeTol(double DegreeTol = MaDegreeTolDefault); 
OOMATHS_API double MaGetDegreeTol();
OOMATHS_API void MaSetRadianTol(double RadianTol = MaRadianTolDefault);  
OOMATHS_API double MaGetRadianTol();
OOMATHS_API void MaSetMinAngle(double MinAngle  = MaMinAngleDefault);  
OOMATHS_API double MaGetMinAngle();

// simple type

enum EMaBoolean { Ma_FALSE,   Ma_TRUE };
enum EMaStatus  { Ma_FAILURE, Ma_SUCCESS };

// ========================================================================================================================
// 04/12/07 - Fit Return Enum declared for use as return value for new Ex methods
// required by Prod+ team to gracefully return a success or failure value for the fit.
typedef enum EMaFitResult
{
   SUCCESS,
   DID_NOT_CONVERGE,
   UNKNOWN_FAILURE
} EMaFitResult;

// mathematical constants

extern OOMATHS_API const double Ma_PI;      // = 3.14159265358979323846;
extern OOMATHS_API const double Ma_2PI;     // = 6.28318530717958647692;
extern OOMATHS_API const double Ma_E;       // = 2.7182818284590452354 ;
extern OOMATHS_API const double Ma_SQRT2;   // = 1.41421356237309504880;

// iterations - Added 26/11/07
// Although the MaMaxiterations is an integer not a float type, it has been added to
// this file as it is used in the same manner as the existing Ma**Tol globals. It did
// not warrant the extra effort to create new files for this single global, even though
// it's inclusion here is in contradiction to the naming convention.
//extern OOMATHS_API const long MaMaxIterations;

// ========================================================================================================================
// arithmetic

inline int  MaSign(int a){return (a < 0) ? -1 : 1;}
inline int  MaSign(double a){return (a < 0) ? -1 : 1;}
inline void MaSwap(int *a, int *b){int c = *a;   *a = *b;   *b = c;}
inline void MaSwap(double *a, double *b){ double c = *a;   *a = *b;   *b = c;}
inline int MaMin(int a, int b){return(a < b)?a:b;}
inline int MaMax(int a, int b){return(a > b)?a:b;}
inline double MaMin(double a, double b){return(a < b)?a:b;}
inline double MaMax(double a, double b){return(a > b)?a:b;}

inline EMaBoolean MaIsZero(double a, double min = MaGetZero()){return (fabs(a) < min)? Ma_TRUE : Ma_FALSE;}
inline EMaBoolean MaIsLarge(double a, double max = MaGetLarge()){return (fabs(a) > max) ? Ma_TRUE: Ma_FALSE;}
inline EMaBoolean MaIsEqual(double a, double b, double tol = MaGetTol()){return(fabs(a - b) < tol)? Ma_TRUE:Ma_FALSE;}
OOMATHS_API EMaBoolean MaIsEqual(int na, int nb, double *pa, double *pb, double tol = MaGetTol());

OOMATHS_API double MaPythag(double a, double b);             // calculate sqrt(a*a + b*b)
OOMATHS_API double MaPythag(double a, double b, double c);   // calculate sqrt(a*a + b*b + c*c)

OOMATHS_API void MaSort(int n, double *pa);                  // sort array into asending numerical order
OOMATHS_API void MaSort(int n, double *pa, int *index);      // produce index table, array not changed
OOMATHS_API void MaSort(int n, double *pa, double *pb);      // arrange array pb as sorted array pa

// trigonometry

inline double MaDegreeToRadian(double degree){ return degree * Ma_PI * 0.00555555555555555555555556; }
inline double MaRadianToDegree(double radian) { return radian / Ma_PI * 180.0; }
OOMATHS_API double MaAngleIn360Degree(double degree);
OOMATHS_API double MaAngleIn2Pi(double radian);
OOMATHS_API double MaArcCosSin(double CosValue, double SinValue);               // find angle in radians
OOMATHS_API void MaCosSin(double radian, double *CosValue, double *SinValue);   // find cos and sin values

// hyperbolic function

OOMATHS_API double acosh (double x);   // x >= 1.0

// geometry

OOMATHS_API EMaBoolean MaIsTriangle(double a, double b, double c, double min = MaGetMinEdgeLength());

// Useful Macros 

// ========================================================================================================================
#define MA_SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define MA_SAFE_ARRAY_DELETE(p) { if(p) { delete[] (p); (p)=NULL; } }


#define _CMA_DEPRECATE_TEXT(_Text) __declspec(deprecated(_Text))

/* Define _CMA_DEPRECATE */
#ifndef _CMA_DEPRECATE
#ifdef _CMA_NO_DEPRECATE
#define _CMA_DEPRECATE(_Replacement)
#else
#define _CMA_DEPRECATE(_Replacement) \
_CMA_DEPRECATE_TEXT("This function or variable may be unsafe. Consider using " \
#_Replacement " instead. See online help for details.")
#endif
#endif

#endif // __OBJFLOAT_H__

// ========================================================================================================================
