/**
 * @class cUniversTools
 * file name: cUniversTools.h
 * @author Betti Oesterholz
 * @date 12.01.2005
 * @mail webmaster@bernd-oesterholz.name
 *
 * System: C++
 *
 * This class represents a basic univers.
 * Copyright (C) @c GPL3 2008  Betti Oesterholz
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
/*
History:
*/


#ifndef ___UNIVERSTOOLS_h__
#define ___UNIVERSTOOLS_h__

#include "cUnivers.h"


class cUniversTools: public cUnivers{

public:
	/**
	 * standart constructor, constructs a new univers with standart values
	 * standart statistic file is: "./statistics.txt"
	 */
	cUniversTools():cUnivers(){}

	/**
	 * parameter constructor, constructs a new univers with the given values
	 * BEWARE!: this constructor copies just the char* pointers, but not the 
	 * 	string in them!
	 * @param outC output comments
	 * @param cutA cut after steps, standart: 0
	 * @param mTm number of maxTime, standart: 1000
	 * @param maxP maxPoints the univers should have, standart: 0 (=infinity points)
	 * @param cMP check maxPoints condition every  (checkMaxPoints) ticks,
	 *		 standart: 1
	 * @param stat name of the statistic file, standart: "./statistics.txt"
	 * @param uFol folder wher to write the universes to, standart: "./universes/"
	 * @param bUN the filenamestart of the univers files, standart: "univers"
	 * @param cutDim the dimension to prefer by cut (cutNearDimension), 
	 *		standart: 3.0
	 * @param cutRatio the Ratio till wich to generate the max class by cut 
	 *		(cutMaxClassRatio), standart: 1.0
	 * @param appU append univers if appU is true, standart: false
	 */
	cUniversTools(bool outC,unsigned int cutA=0,unsigned long mTm=100,
		unsigned long maxP=0, unsigned int cMP=1, 
		const char* stat="./statistics.txt", const char* uFol="./universes/", 
		const char* bUN="univers",double cutDim=3.0,double cutRatio=1.0):
	cUnivers(outC ,cutA ,mTm,maxP ,cMP,stat,uFol,bUN ,cutDim ,cutRatio){}

	/**
	 * copy constructor, constructs a copy of the given univers cUniversTools
	 * @param uTools the univers to copy
	 */
	cUniversTools(cUniversTools &uTools):cUnivers(uTools){}

	/**
	 * unions of two point lists
	 * doesn't copy univers points (copies just the pointers)
	 * @param liPoints1 the first point list to union
	 * @param liPoints2 the secound point list to union
	 * @return the unioned point list, a list which includes the points of 
	 *		both input lists liPoints1 and liPoints2
	 */
	list<cPoint*> unionPointLists (list<cPoint*> liPoints1, list<cPoint*> liPoints2 ) const;

	/**
	 * intersec two point lists
	 * doesn't copy univers points (copies just the pointers)
	 * @param liPoints1 the first point list to intersec
	 * @param liPoints2 the secound point list to intersec
	 * @return the interseced point list, a list which includes just the
	 *		points of which are in both input lists liPoints1 and liPoints2
	 */
	list<cPoint*> intersectionPointLists( list<cPoint*> &liPoints1, list<cPoint*> &liPoints2 ) const;

	/**
	 * checks if the intersection of two point lists is empty
	 * @param liPoints1 the first point list to intersec
	 * @param liPoints2 the secound point list to intersec
	 * @return true if the intersection of the input lists liPoints1 and 
	 *		liPoints2 would be empty, else false
	 */
	bool intersectionPointListsIsEmpty( list<cPoint*> &liPoints1, list<cPoint*> &liPoints2 ) const;

	/**
	 * get the points of the point list liPoints1 that are not in the point 
	 * list liPoints2
	 * doesn't copy univers points (copies just the pointers)
	 * @param liPoints1 the first point list to get the points from
	 * @param liPoints2 the secound point list of points not to return
	 * @return the list of the points which are in the list liPoints1 but not
	 *		in the list liPoints2
	 */
	list<cPoint*> getPointsNotInPointLists( list<cPoint*> &liPoints1, list<cPoint*> &liPoints2 ) const;

	/**
	 * prints the values of the given univers structur to the given output
	 * stream, if it exists
	 * @param ostream the outputstream to print the univers to
	 * @param universStructur the univers structur to print
	 * @return if the stream exists true and the given structur univers in
	 * 	the stream ostream in a readebel form(integer numbers seperated
	 * 	by ",",";" and "."), false else
	 */
	bool printUniverseStructur(ostream* ostream, list<cPoint*> &universStructur) const;

	/**
	 * find the points in the univers with the names of the numbers in the
	 * given list and return the list of pointers to them (doesn't copy the
	 * points), if they exists
	 * @param listOfPointNames a list of integer names of the points to find
	 * @return a list of pionters to the points found
	 */
	list<cPoint*> findPoints( list<unsigned long> &listOfPointNames );

	/**
	 * get all neigbours in the univers of the point orgin till the distantce
	 * dist;
	 * doesn't copy univers points (copies just the pointers);
	 * negativ and positiv distances are treated equal
	 * @param orgin the original point to get the neibours from 
	 * @param distance the distance till wich to get the neibours
	 * @return a list of pointers to the neibours till distance dist of the 
	 *		orgin point
	 */
	list<cPoint*> getNeigbours( cPoint* orgin, const unsigned int distance );

	/**
	 * get all neigbours in the univers of the point orgin with the minimum
	 * distantce to the point;
	 * doesn't copy univers points(copies just the pointers);
	 * negativ and positiv distances are treated equal;
	 * @param orgin the original point to get the neibours from 
	 * @param distance the distance till wich to get the neibours
	 * @return a list of pointers to the neibours with the distance to the orgin point
	 */
	list<cPoint*> getMinNeigbours( cPoint* orgin, const unsigned int distance );

	/**
	 * gets the minimal distance (number af negativ and positiv distnaces
	 * betwean) betwean two points in the univers; the points are given as
	 * iterators of the univers; 
	 * negativ and positiv distances are treated equal; 
	 * if the distance is -1 the points are not connected
	 * @param pPoint1 a iterator of the univers to a point in the univers
	 * @param pPoint2 a iterator of the univers to a point in the univers
	 * @return the minimal (number of) distance betwean pPoint1 and pPoint2
	 */
	long getDistance(cPoint* pPoint1, cPoint* pPoint2);

	/**
	 * This method gets the minimal distance in the univers (number af negativ
	 * and positiv distnaces betwean) betwean the given point poi1 and the 
	 * given points.
	 * The point poi1 is given as iterator of the univers and the points as
	 * a iteratorlist of iterators of the univers.
	 * Negativ and positiv distances are treated equal.
	 *
	 * @param poi1 the iterator to the destination point
	 * @param points a itoratorlist of the points in the univers to which the
	 * 	minimal distance should be evalued
	 * @return the minimal distance of the points of the list as a list of
	 * 	pairs of points and distances, if a distance is -1 the point is not
	 * 	conected to the destination point
	 */
	list< pair<cPoint*,long> > getDistanceToPoints(cPoint* poi1, list<cPoint*> &points);

	unsigned int getUniversPartSize(cPoint* orgin);
	/*get the size of the Part univers in wich the Point orgin is to the point orgin,
		this means the greatest minimal distance to a point in the part univers
	pre: the original orgin point to get the univers size to
	post: the greatest minimal distance a point has to the given orgin point*/

	list<cPoint*> getSurface(list<cPoint*> &poiL);
	/*gets the surface; the points of the given point list poiL that have
	neigbours not in the point list poiL
	doesn't copy univers points(copies just the pointers)
	pre: point list of wich to find the surface
	post: the surface of the given point list poiL*/

	list<cPoint*> makeGrid(cPoint* sPoi, const unsigned int dist, const unsigned int number);
	/*makes a grid of number nodes(if possible else less) with the startpoint
	sPoi and the minimum distance of dist betwean the points in this univers
	the grid is in its distances betwean the points not optimal(minimal)
	; negativ and positiv distances are treated equal
	pre: the startpoint sPoi for the grid as a pointer to a point of this
		univers, the number of points the grid should have and the minimum
		distance dist betwean them
	post: the points of the grid*/

	unsigned long getNumberOfPosDistances(list<cPoint*> &area);
	/*returns the number of the positv distances betwean the points in the
	given area of this univers
	pre: the area to evalue the positiv distances of
	post:  the number of positiv distances betwean the points of the area*/


	unsigned long getNumberOfNegDistances(list<cPoint*> &area);
	/*returns the number of the negativ distances betwean the points in the
	given area of this univers
	pre: the area to evalue the negativ distances of
	post: the number of negativ distances betwean the points of the area*/


};
 #endif
