//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2015, University of Osnabrueck                                                                         //
//   All rights reserved.                                                                                               //
//                                                                                                                      //
//   Redistribution and use in source and binary forms, with or without modification, are permitted provided that the   //
//   following conditions are met:                                                                                      //
//                                                                                                                      //
//   1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following//
//       disclaimer.                                                                                                    //
//                                                                                                                      //
//   2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the       //
//       following disclaimer in the documentation and/or other materials provided with the distribution.               //
//                                                                                                                      //
//   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, //
//   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  //
//   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
//   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR    //
//   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  //
//   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE   //
//   USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                           //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <vector>
typedef std::vector<double> PointVec;
typedef std::vector< PointVec > PointsVec;
typedef std::pair <int, double> PosAWeight;
typedef std::vector< PosAWeight > PosAWeightVec;

#ifndef RALANS_ALONE_H
#define RALANS_ALONE_H 

class RaLaNSList;

#include <string>
//for doing fast List calculations with RaLaNS
#include "ralans-list.h"

//length of a 3d point(for a vector)
#define LENPOINT 3

//1. used to decide whether to the function should calculate for the transmitters or receivers
#define TRANS 0
#define REC 1

//Defines for outside area
#define OUT 1
#define IN 0

//Defines to check wether the point is on the upper border
#define ONUP 1
#define NOTONUP 0

//Defines for Header numbers
#define POINT 0	
#define LINE 1	
#define AREA 2	
#define CUBIC 3
#define LIST 4	

//Defines for Header Lengths
#define LENPOINTHEAD 3
#define LENLINEHEAD 9
#define LENAREAHEAD 7
#define LENCUBICHEAD 9

//the initialization value for the vectors
#define INITVALUE 0

//Defines for axis
#define XAXIS 0
#define YAXIS 1
#define ZAXIS 2

//the default maximum distance between 2 points for signal calculation
#define THRESHOLD 20.0

//the default value for the number of bad signal, which will be excluded
#define BADNUM 0

//the maximum for calculating the minimal distance
#define MAXDST 1e20

//the signal value for no signal
#define NOSIGNAL -3076.53

//the signal value whether to interpolate or not                                                                        
#define INTERPOLATE true  

//the default number of interpolation points for list calculation
#define LISTINTERPOLATIONNUM 2

//For time measurement



//For turning debug messages on or off
//#define DEBUGFLAG
#ifdef DEBUGFLAG
#define DEBUG_MSG(str) std::cout << str << std::endl;
#define START long int start = GetTime()
#define DIFF(context) DEBUG_MSG(context << ": TIME: diff=" << GetTime() - start)
#else
#define DEBUG_MSG(str)
#define START
#define DIFF(context)
#endif



//For prining error messages
#define ERROR(str) std::cerr << str << std::endl

//the signal value whether to interpolate or not
/**
 * \ingroup propagation
 *
 * \brief a propagation model for RaLaNS.
 * 
 * Can be used with the RaLaNS to work with networks as a standalone application.
 */
class RaLaNSAlone
{
	public:
		/**
		 * \brief Default constructor
		 *
		 * initializes some vectors, does not set any attribute, like the filename
		 */
		RaLaNSAlone();

		/**
		 * \brief Default constructor
		 *
		 * sets the file with the data and all other attributes with their default value
		 *
		 * \param filename the path to the data file with the data. 
		 * The file can be either a txt or a zip file.
		 */
		RaLaNSAlone(std::string filename);

		/**
		 * \brief Default constructor
		 *
		 * sets all attributes according to their given value
		 *
		 * \param filename the path to the data file with the data. 
		 * The file can be either a txt or a zip file.
		 *
		 * \param threshold sets the maximum value for the distance between the query point 
		 * and the nearest mathing point for a valid signal calculation. 
		 *
		 * \param noSignal the value for no signal
		 *
		 * \param interpolate sets interpolation on or off.
		 *
		 * \param badNum sets the maximal number of exclusions for bad signals(noSignal) during the
		 * interpolation process in the grid. 
		 */
		RaLaNSAlone(std::string filename, double threshold, double noSignal, 
				bool interpolate, int badNum, int listInterpolationNum);
		/**
		 * \brief Default destructor
		 *
		 * has no function
		 */
		~RaLaNSAlone();


		/**
		 * \brief Sets the data
		 *
		 * sets the file with the data and generates the needed data from that file.
		 * if a fault happens, it prints an error messages through std::err to describe the fault.
		 * 
		 * \param filename the path to the data file with the data. 
		 * The file can be either a txt or a zip file.
		 *
		 * \return true, if the data was set correctly.
		 * False, if the data was not set correctly. An explanation is given through standard error.
		 */
		bool SetFile( std::string filename );

		/**
		 * \brief get path to data file
		 *
		 * returns the path to the data file.
		 *
		 * \return the path of the data file as a string
		 */
		std::string GetFile( void ) const;

		/**
		 * \brief Turn interpolation on or off
		 *
		 * sets interpolation on or off. This boolean values decides whether the
		 * calculation will be done with interpolation or without.
		 * If TRUE: With interpolation
		 * If FALSE: Without interpolation
		 * 
		 * \param interpolate the new value for interpolate
		 */
		void SetInterpolate(bool interpolate);

		/**
		 * \brief get interpolate
		 *
		 * returns the current value for interpolate. For Details look at RaLaNSAlone::SetInterpolate
		 *
		 * \return the value of interpolate
		 */
		bool GetInterpolate() const;

		/**
		 * \brief Sets the badNum parameter
		 *
		 * sets the maximal number of exclusions for bad signals(noSignal) during the
		 * interpolation process in the grid. 
		 * This value should be max. 3 for areas or 7 for cubics.
		 * With this value you can exclude no signal values from the interpolation process, because
		 * already 1 no signal value can change the result of the interpolation signifficantly.
		 * 
		 * \param badNum the new value for badNum
		 */
		void SetBadNum(int badNum);

		/**
		 * \brief get badNum
		 *
		 * gets the maximal number of exclusions for bad signals(noSignal) during the
		 * interpolation process in the grid.
		 *
		 * \return the value of badNum
		 */
		int GetBadNum() const;

		/**
		 * \brief Sets noSignal
		 *
		 * sets the noSignal value. The no signal value is the value, which states that there is no
		 * signal, if the real signal value is below or even to the no signal value. 
		 * If the real signal value from a transmitter to a receiver is below this value, it will be set
		 * to the no signal value instead.
		 * By changing this value you can change the result of the interpolation of a no signal value is
		 * included in the interpolation process, because if this value is f.x. -500 instead of -3000
		 * the result of the interpolation will be higher, too.
		 * 
		 * \param noSignal the new value for noSignal
		 */
		void SetNoSignal(double noSignal);

		/**
		 * \brief get noSignal
		 *
		 * gets the noSignal value
		 *
		 * \return the value of noSignal
		 */
		double GetNoSignal() const;

		/**
		 * \brief Sets the threshold
		 *
		 * sets the maximum value for the distance between the query point 
		 * and the nearest mathing point for a valid signal calculation. 
		 * This value will be used when the nearest point to mobilitymodel is calculated and
		 * the distance is checked. When the distance is bigger than the 1 setted here, an
		 * error message will be printed via std::err.
		 * 
		 * \param newThreshold the new value for threshold
		 */
		void SetThreshold(double newThreshold);

		/**
		 * \brief get threshold
		 *
		 * gets the maximum distance between 2 nearest points for signal calculation. 
		 *
		 * \return the value of the threshold
		 */
		double GetThreshold() const;


		/**
		 * \brief Set interpolation points number for lists
		 *
		 * set the number of points for the interpolation process. If this number is f.x. 2, it will looked for
		 * the nearest 2 points in the list to the query point and those will be used for interpolation.
		 * If this number is higher, the result can be more realistic, because it includes more points around
		 * the query point, but it can also happen that a noSignal value gets included, which changes the result
		 * a lot and probably does not simulate the reality right. 
		 *
		 * If you set the number higher, it takes a bit longer.
		 *
		 * \param listInterpolationNum the new number of interpolation points for lists
		 */
		void SetListInterpolationNum(int listInterpolationNum);

		/**
		 * \brief Get number of interpolation points
		 *
		 * Get the current number of interpolation points. 
		 * For more details about listInterpolationNum look at RaLaNSAlone::SetListInterpolationNum
		 *
		 * \return the number of interpolation points
		 */
		int GetListInterpolationNum() const;

		/**
		 * \brief calculates the signal strength
		 *
		 * calculates the signal strength for the signal from the given transmitter to the given receiver.
		 * This function uses all setted attributes(threshold, badNum, noSignal, interpolate) for its
		 * calculation.
		 * So of course all attributes should have been set before calling this function for right behaviour.
		 *
		 * \param transmitter the 3d represenation of the given transmitter
		 *
		 * \param receiver the 3d represenation of the given receiver
		 *
		 * \return the value for the signal strength from the given transmitter to the given receiver
		 */
		double DoCalc (std::vector<double> transmitter,
				std::vector<double> receiver) const;

	private:

		bool construct(std::string filename, double threshold, double noSignal, bool interpolate, int badNum, 
				int listInterpolationNum);

		/**
		 * \brief set one of the headers
		 *
		 * sets either the transmitter header, which is the first line in the file
		 * or the receiver header, which is the 2nd line in the file
		 * 
		 * \param headerStringWithSpaces the complete header line as a string
		 * 
		 * \param &header the pointer to the header, which will store the received information 
		 * 
		 * \param &type the type of the data: POINT, LINE, AREA, CUBIC or LIST
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 */
		void setHeader(std::string headerStringWithSpaces, 
				std::vector< std::vector<double> > &header, 
				int &type, int TransOrRec);

		/**
		 * \brief sets Point header
		 *
		 * function will be called if one of the headers is a point. 
		 * The point data will be set
		 * 
		 * \param pointVec a vector, which represents 1 point
		 * 
		 * \param &header the pointer to the header, which will store the point
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 */
		void setPoint(std::vector<double> pointVec, 
				std::vector< std::vector<double> > &header, int TransOrRec);

		/**
		 * \brief sets Line header
		 *
		 * function will be called if one of the headers is a line. The line data will be set
		 * 
		 * \param lineVec a vector, which represents a line
		 * 
		 * \param &header the pointer to the header, which will store the line
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 */
		void setLine(std::vector<double> lineVec, 
				std::vector< std::vector<double> > &header, int TransOrRec);

		/**
		 * \brief sets Area header
		 *
		 * function will be called if one of the headers is a area. The area data will be set
		 * 
		 * \param areaVec a vector, which represents an area
		 * 
		 * \param &header the pointer to the header, which will store the area
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 */
		void setArea(std::vector<double> areaVec, 
				std::vector< std::vector<double> > &header, int TransOrRec);

		/**
		 * \brief does loop for Area or Cubic
		 *
		 * function will be called if one of the headers is a area or cubic.
		 * This function sets the transmitters or receivers in a loop.
		 * 
		 * \param beginVec a vector, which represents the beginning of the area or cubic
		 * 
		 * \param &header the pointer to the header, which will store the area or cubic
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 */
		void setAreaAndCubic(std::vector<double> beginVec, 
				std::vector< std::vector<double> > &header, int TransOrRec);

		/**
		 * \brief sets Cubic header
		 *
		 * function will be called if one of the headers is a cubic. 
		 * The cubic data will be set
		 * 
		 * \param cubicVec a vector, which represents a cubic
		 * 
		 * \param &header the pointer to the header, which will store the cubic
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 */
		void setCubic(std::vector<double> cubicVec, 
				std::vector< std::vector<double> > &header, int TransOrRec);

		/**
		 * \brief sets list header
		 *
		 * function will be called if one of the headers is a list. The list data will be set
		 * 
		 * \param listVec a vector, which represents a list
		 * 
		 * \param &header the pointer to the header, which will store the list
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 */
		void setList(std::vector<double> listVec, 
				std::vector< std::vector<double> > &header, int TransOrRec);

		/**
		 * \brief generates "far away" destination error
		 *
		 * this function throws an NS3 Error to handle points, 
		 * which are too far away from anyother setted point.
		 * 
		 * \param a the position, which is too far away from any point
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \param pos the position of the point(transmitter or receiver) in the vector, which is the nearest.
		 * 
		 * \param currentMinDst the minimal destination from point a to any other point
		 */
		std::string genDistError(const std::vector<double> &point, int TransOrRec, 
				int pos, double dst, const std::vector<std::vector<double> > &points) const;

		/**
		 * \brief throws "far away" destination error
		 *
		 * this function throws an NS3 Error to handle points, 
		 * which are too far away from anyother setted point.
		 * 
		 * \param a the position, which is too far away from any point
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \param pos the position of the point(transmitter or receiver) in the vector, which is the nearest.
		 * 
		 * \param currentMinDst the minimal destination from point a to any other point
		 */
		void throwDistError(const std::vector<double> &point, int TransOrRec, 
				int pos, double dst, const std::vector<std::vector<double> > &points) const;

		/**
		 * \brief checks "far away" destination error
		 *
		 * this function checks the distance, 
		 * before it throws the "far away" destination error.
		 * 
		 * \param a the position, which is too far away from any point
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \param pos the position of the point(transmitter or receiver) in the vector, which is the nearest.
		 *
		 * \return true, if the the error has not been thrown. False, if it has.
		 */
		bool checkDistError(const std::vector<double> &point, int TransOrRec, int pos, 
				const std::vector<std::vector<double> > &points) const;

		/**
		 * \brief checks "far away" destination error
		 *
		 * this function checks the distance, 
		 * before it throws the "far away" destination error.
		 * 
		 * \param a the position, which is too far away from any point
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \param pos the position of the point(transmitter or receiver) in the vector, 
		 * which is the nearest.
		 * 
		 * \param currentMinDst the minimal destination from point a to any other point
		 *
		 * \return true, if the the error has not been thrown. False, if it has.
		 */
		bool checkDistError(const std::vector<double> &point, int TransOrRec, 
				int pos, double currentMinDst,
				const std::vector<std::vector<double> > &points) const;

		/** 
		 * \brief calculates distance between 2 points
		 *
		 * this function calculates the distance between a 3d mobilitymodel point 
		 * and a 3d vector point.
		 * 
		 * \param point1 first point for distance calculation
		 * 
		 * \param point2 second point for distance calculation
		 *
		 * \return the distance
		 */
		double calcDist(const std::vector<double> &point1, const std::vector<double> &point2) const;

		/**
		 * \brief checks wether the point is in the axis range
		 *
		 * checks wether the mobilitymodel point decoded as a vector is in the range 
		 * of all points(transmitters or receivers) based on the given axis.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 *
		 * \param axis the axis, for which the check should be done
		 *
		 * \return a value, which contains information 
		 * about the location of the mobilitymodel a with regard to the z axis
		 */
		int checkIn(const std::vector<double> &point, const std::vector<std::vector<double> > &points, 
				int axis) const;

		/**
		 * \brief checks wether the point is in the range
		 *
		 * checks wether the mobilitymodel point is in the range of the given points.
		 * This function is intended to be used for AREAs und CUBICs.
		 * 
		 * \param point the 3d query point
		 *
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \return a value, which contains information about the location of the mobilitymodel a
		 */
		int checkIn(const std::vector<double> &point, const std::vector<std::vector<double> > &points) const;

		/**
		 * \brief checks wether the point is on the upper bound
		 *
		 * checks wether the vector point is on the upper bound
		 * of all points(transmitters or receivers) based on the given axis.
		 * 
		 * \param a the vector point, for which the check should be done
		 * 
		 * \param points contains the receivers or transmitters vector
		 *
		 * \param axis the axis, for which the check should be done
		 *
		 * \return a value, which contains information 
		 * about the location of the mobilitymodel a with regard to the given axis
		 */
		int checkOnUp(const std::vector<double> &point, const std::vector<std::vector<double> > &points, 
				int axis) const;

		/**
		 * \brief calculates the nearest position for the transmitters or receivers in an area
		 *
		 * calculates the position in the transmitter or receiver vector of the point, which
		 * is nearest to mobilitymodel point a.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return the position of the nearest point in the vector(transmitter or receiver
		 * vector)
		 */
		int calcNearestPosArea(const std::vector<double> &point, 
				const std::vector<std::vector<double> > &points, int TransOrRec) const;

		/**
		 * \brief calculates the nearest position for the transmitters or receivers in a cubic
		 *
		 * the calculation assumes that the mobilitymodel position is inside the cubic.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return the position of the nearest point in the vector(transmitter or receiver
		 * vector)
		 */
		int calcNearestPosCubic(const std::vector<double> &point, 
				const std::vector<std::vector<double> > &points, int TransOrRec) const;

		/**
		 * \brief initializes some value
		 *
		 * initializes the vectors len and step
		 */
		void initValues();

		/**
		 * \brief calculates the nearest position for the transmitters or receivers the normal
		 * way
		 *
		 * This way of calculation goes through all points and checks for each point, if it is
		 * the nearest and sets the point then as nearest.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return the position of the nearest point in the vector(transmitter or receiver
		 * vector)
		 */
		int calcNearestPosElse(const std::vector<double> &point, 
				const std::vector<std::vector<double> > &points) const;

		/**
		 * \brief calculates the nearest position for the transmitters or receivers for a list
		 *
		 * \param point the 3d point
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return the position of the nearest point in the vector(transmitter or receiver
		 * vector)
		 */
		int calcNearestPosList(const std::vector<double> &point, int TransOrRec) const;

		/**
		 * \brief calculates the nearest point
		 *
		 * the calculation assumes that the mobilitymodel position a is in the range 
		 * of all given points based on the chosen axis.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param axis the axis(x, y or z) for which the calculation should be done
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return the exact position of the mobility model point a according to the chosen axis. 
		 */
		double calcNearestPos(const std::vector<double> &point, int axis, 
				const std::vector<std::vector<double> > &points, int TransOrRec) const;
		/**
		 * \brief calculates the nearest point
		 *
		 * the calculation assumes that the mobilitymodel position a is in the range 
		 * of all given points based on the chosen axis.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \param type the type of the data. Either POINT, LINE, AREA, CUBIC or LIST.
		 * 
		 * \return the exact position of the mobility model point a according to the chosen axis. 
		 */
		int calcNearestPosAll(const std::vector<double> &point, 
				const std::vector<std::vector<double> > &points, 
				int TransOrRec, int type) const;

		/**
		 * \brief calculates the points to interpolate for the transmitters or receivers in an area
		 *
		 * calculates the points of the area, which are needed for the interpolation. 
		 * Every point is described by its position in the vector 
		 * and its weight for the interpolation process.
		 * This way of calculation needs constant time.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return a vector of all interpolation points, which are described by a pair of
		 * their position and their weight.
		 */
		std::vector< std::pair <int, double> > getInterpolPointsArea(const std::vector<double> &point, 
				const std::vector<std::vector<double> > &points, int TransOrRec) const;

		/**
		 * \brief calculates the points to interpolate for the transmitters or receivers for the list
		 *
		 * calculates the points of the list, which are needed for the interpolation. 
		 * Every point is described by its position in the vector 
		 * and its weight for the interpolation process.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return a vector of all interpolation points, which are described by a pair of
		 * their position and their weight.
		 */
		std::vector< std::pair <int, double> > getInterpolPointsList(const std::vector<double> &point, 
				int TransOrRec) const;

		/**
		 * \brief calculates the points to interpolate for the transmitters or receivers in an cubic
		 *
		 * calculates the points of the cubic, which are needed for the interpolation. 
		 * Every point is described by its position in the vector 
		 * and its weight for the interpolation process.
		 * This way of calculation needs constant time.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return a vector of all interpolation points, which are described by a pair of
		 * their position and their weight.
		 */
		std::vector< std::pair <int, double> > getInterpolPointsCubic(const std::vector<double> &point, 
				const std::vector<std::vector<double> > &points, int TransOrRec) const;

		/**
		 * \brief calculates the points to interpolate for the transmitters or receivers
		 *
		 * calculates the points , which are needed for the interpolation. 
		 * Every point is described by its position in the vector 
		 * and its weight for the interpolation process.
		 * This way of calculation needs linear time based on the number of transmitters or 
		 * receivers. 
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return a vector of all interpolation points, which are described by a pair of
		 * their position and their weight.
		 */
		std::vector< std::pair <int, double> > getInterpolPointsElse(const std::vector<double> &point, 
				const std::vector<std::vector<double> > &points) const;

		/**
		 * \brief creates interpolation points for noSignal values
		 *
		 * this function creates a vector with 1 interpolation point, 
		 * which has a negative position and a weight of 1.
		 * 
		 * \return a vector with 1 interpolation point
		 */
		std::vector< std::pair <int, double> > makeNoSignalInterpolPoints() const;

		/**
		 * \brief calculates the nearest point
		 *
		 * the calculation assumes that the mobilitymodel position a is in the range 
		 * of all given points based on the chosen axis.
		 * This way of calculation needs constant time.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param axis the axis(x, y or z) for which the calculation should be done
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return a vector of all interpolation points, which are described by a pair of
		 * their position and their weight.
		 */
		std::vector< std::pair <int, double> > getInterpolPoints(const std::vector<double> &point, int axis, 
				const std::vector<std::vector<double> > &points, int TransOrRec) const;

		/**
		 * \brief calculates all the points needed for the interpolation
		 *
		 * the calculation assumes that the mobilitymodel position a is in the range 
		 * of all given points based for all axises.
		 * the way of calculation is determinded by the type.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \param type the type of the data. Either POINT, LINE, AREA, CUBIC or LIST.
		 * 
		 * \return a vector of all interpolation points, which are described by a pair of
		 * their position and their weight.
		 */
		std::vector< std::pair <int, double> > getInterpolPointsAll(const std::vector<double> &point, 
				const std::vector<std::vector<double> > &points, 
				int TransOrRec, int type) const;

		/**
		 * \brief calculates the nearest point
		 *
		 * the calculation assumes that the mobilitymodel position a is in the range 
		 * of all given points based on the chosen axis.
		 * 
		 * \param point the 3d query point
		 * 
		 * \param axis the axis(x, y or z) for which the calculation should be done
		 * 
		 * \param points contains the receivers or transmitters vector
		 * 
		 * \param TransOrRec decide whether this is for the transmitters or receivers
		 * 
		 * \return the exact position of the mobility model point a according to the chosen axis. 
		 */
		double DoCalcNoInterpol(std::vector<double> transmitter, std::vector<double> receiver) const;

		/**
		 * \brief prints all points
		 *
		 * puts all points into a string
		 *
		 * \param points the points, which shall be printed
		 *
		 * \return a string with all points
		 */
		std::string printPoints(const std::vector< std::vector<double> > &points, std::string transOrRec) const;

		/**
		 * \brief prints all parameters
		 *
		 * prints all parameters if the debug mode is on
		 */
		void debugParams();

		/**
		 * \brief generates the data
		 *
		 * generetes the data from the given file
		 * 
		 * \return true, if the data was set correctly.
		 * False, if the data was not set correctly. An explanation is given through standard error.
		 */
		bool GenMap();

		/**
		 * \brief prints all transmitters
		 *
		 * prints all transmitters via NS_LOG_DEBUG
		 */
		std::string printInterpolPoints(const std::vector< std::pair<int, double> > &interpolPoints, 
				const std::vector< std::vector<double> > &points) const;

		int typeTrans;//!< the type of the trasnmitter header
		int typeRec;//!< the type of the reciever header

		std::vector<std::vector<double> > signals;//!< contains signals from transmitters to receivers
		std::vector<std::vector<double> > transmitters;//!< contains all transmitters with their 3D position
		std::vector<std::vector<double> > receivers;//!< contains all receivers with their 3D position

		std::vector<int> len;//!< contains the number of points in each dimension for the receivers and transmitters

		std::vector<double> step;//!< contains the step size in each dimension for the receivers and transmitters

		double DoCalcInterpol (std::vector<double> transmitter,
				std::vector<double> receiver) const;

		std::string filename;//!< location of the data file
		double threshold;//!< the maximum distance between 2 points for singal calculation
		double noSignal;//!< the signal value for cases, in which there is no signal
		bool interpolate;//!< option for interpolation. if true, interpolation will be done, if false not.
		int badNum;//!< option for the number of bad signals(noSignal), which will be ignored.
		mutable std::vector<RaLaNSList> listCalc;//!< vector to listCalculators for the transmitter and receiver
		int listInterpolationNum;//!< option for the number of bad signals(noSignal), which will be ignored.
};

#endif /* RALANS_ALONE_H */
