#ifndef SCALEFUNCTIONS
#define SCALEFUNCTIONS

#include <math.h>
#include <iostream.h>
#include <string.h>
#include <stdio.h>
#include "sortfunctions.h"
#include "defines.h"

/***
 * Function to normalize a vector
 * there is a pointer and reference version of this function
 * \param x       x coordinate
 * \param y       y coordinate
 * \param z       z coordinate
 */
template<class T> void myNormalizeP(T *x, T *y);
template<class T> void myNormalize(T &x, T &y);
template<class T> void myNormalizeP(T *x, T *y, T *z);
template<class T> void myNormalize(T &x, T &y, T &z);


/***
 * Function to fit values of an array into a range
 * \param min       minimal value in array after scaling
 * \param max       maximal value in array after scaling
 */
template<class T> void scaleArray(T *vector, const int length,
                                  const T min, const T max);
/***
 * Function to fit an array of 3 dimensions (usualy vertices) into a volume of size:
 * \param xmin       minimal x value after scaling
 * \param xmax       maximal x value after scaling
 * \param ymin       minimal y value after scaling
 * \param ymax       maximal y value after scaling
 * \param zmin       minimal z value after scaling
 * \param zmax       maximal z value after scaling
 * \param vector     pointer to vector with data, will be scaled according to parameters
 *                   dimensions are assumed as x0, y0, z0, x1, y1, z1 ... xN, yN,zN
 * \param length     absolute length of the vector = 3*number of vertices 
 */
template<class T> void fitVectorToVolume(T *vector, const int length,
                                         const T xmin, const T xmax,
                                         const T ymin, const T ymax,
                                         const T zmin = 0, const T zmax = 0);


/***
 * Function to fit an array in 2 dimensions (usualy vertices) into an area of size:
 * \param xmin       minimal x value after scaling
 * \param xmax       maximal x value after scaling
 * \param ymin       minimal y value after scaling
 * \param ymax       maximal y value after scaling
 * \param vector     pointer to vector with data, will be scaled according to parameters
 *                   dimensions are assumed as x0, y0, x1, y1 ... xN, yN
 * \param length     absolute length of the vector = 2*number of vertices
 */
template<class T> void fitVectorToArea(const T xmin, const T xmax,
                                       const T ymin, const T ymax,
                                       T *vector, const int length);
/***
 * Function to center and scale object without distortion into a range
 * one scale factor for all dimensions is determined and applied
 */
template<class T> void centerAndScaleObject(T *vector, const int length,
                                            const T range, const int Dimension=3);
/***
 * Function to scale object without distortion into a range
 * Object is not necessarily centered
 * NOT YET FINISHED
 */
template<class T> void scaleObject(T *vector, const int length,
                                   const T range, const int Dimension=3);
/***
 * Returns scale factor of an object into a range without distortion
 * (i.e. one scale factor for all dimensions)
 */
template<class T> T scaleObject(T *vector, const int length, const T range, 
                                const T xmin, const T xmax,
                                const T ymin, const T ymax,
                                const T zmin, const T zmax,
                                const int Dimension=3);
/***
 * Function to center object around (0,0,0) in 3D or (0,0) in 3D
 */
template<class T> void centerObject(T *vector, const int length, const int Dimension=3);

/***
 * Function to center object around (0,0,0) in 3D or (0,0) in 3D
 */
template<class T> void centerObject(T *vector, const int length,
                                    const T xmin, const T xmax,
                                    const T ymin, const T ymax,
                                    const T zmin, const T zmax,
                                    const int Dimension=3);
/***
 * Function to get dimensions of an object stored as a 2 or 3 dimensional vertices vector
 * 2D Vector is of the form x0, y0, x1, y1 ... xN, yN
 * 3D Vector is of the form x0, y0, z0, x1, y1, z1 ... xN, yN,zN
 * Dimension is only needed if it is a 2D vector
 */
template<class T> void getObjectBoundaries(T *vector, const int length,
                                           T &xmin, T &xmax,
                                           T &ymin, T &ymax,
                                           T &zmin, T &zmax,
                                           const int Dimension = 3);



/* dummy functions to instantiate double, float, short versions */
void dummyScalefunctions();

#endif //SCALEFUNCTIONS
