//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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.                                           //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef RALaNS_LIST_H
#define RALaNS_LIST_H

class RaLaNSAlone;

#include "ralans-alone.h"
#include <ANN/ANN.h>
#include <map>

class RaLaNSList
{
	public:

		/**
		 * \brief Default Constructor 
		 *
		 * has no function
		 */
		RaLaNSList();

		/**
		 * \brief Constructor 
		 *
		 * constructs a the calculator for RaLaNS lists with a vector of the points, which are in the RaLaNS
		 * list and a pointer to the RaLaNSAlone class to get the threshold value, when it is needed for the
		 * calculation.
		 *
		 * \param &points the points vector, which represents the 3d points in the list.
		 *
		 * \param *ralansAlone a pointer to the RaLaNSAlone Object to get the threshold value, when it is
		 * needed.
		 */
		RaLaNSList (const std::vector<std::vector<double> > &points, RaLaNSAlone *ralansAlone);

		/**
		 * \brief Default Destructor 
		 *
		 * has no function
		 */
		~RaLaNSList();

		/**
		 * \brief calculates the nearest point 
		 *
		 * calculates the nearest point based on euclidean distance to the given point.
		 *
		 * \param point the query point, for which this function searches for the nearest point to it.
		 *
		 * \return the index of the nearest point in the points vector, which was set in the constructor.
		 */
		int calcNearestPos(PointVec point);

		/**
		 * \brief calculates the interpolation points
		 *
		 * calculates all points in the threshold radius around the given point. Then weights them by their
		 * distance to the given point to use all these points for the interpolation.
		 *
		 * \param point the query point, for which this function generates the interpolation points.
		 *
		 * \return a vector with pairs of indexes and corresponding weights. The weights add up to 1 and the
		 * indexes represent the position in the points vector, which was set in the constructor.
		 */
		PosAWeightVec getInterpolPoints(PointVec point);

	private:
		/* data */

		ANNkd_tree *tree;

		RaLaNSAlone *ralansAlone;

		ANNpointArray pa;

		bool constructed;

		void calcNearestPos(PointVec point, int num, ANNidxArray &nnAry, ANNdistArray &dists);

		PosAWeightVec makeInterpolPointsVec(ANNidxArray nnAry, ANNdistArray dists, int num);

		ANNpointArray PointsToANNPointArray(const std::vector<std::vector<double> > &points);

		ANNpoint PointVecToANNPoint(const std::vector<double> &point);
};

#endif /* RaLaNS_LIST */
