/*File Name: cUnivers.h
  Author: Betti Oesterholz ; Date: 12.01.2005
  System: C++


  Copyright (C) 2004  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 2, June 1991, of the License, or
  (at your option) 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, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

This file contains the program for a univers.
Ther are 2 basictypes in this univers points and conections(positiv and
negativ) betwean them. Points are changing Points of the univers.
Every tick(minimum time) every point creates a new zero distance. (nothing is
produced, conservation of distances) A zero distance is a positiv (+1) and a
negativ (-1) distance. The 2 signed distances are random conected to a
neigbor of the point or a new point. (each possibility has same probability)
Neigbor points of a point are points that are conected with distances to the point.
Two not eqaul signed distances betwean to points destroy each other.(add to zero)
If one part (signed distance) of a zero distanc is destroyed, but not the
other, the other distance one end ist displaced from the point of his
creation to the point that was conected with the creation point by the
destroyed distance. (the distance betwean the end and the point becomes zero)

*/

#some tested

#tested
	cUnivers();
	/*standart constructor, constructs a new univers with standart values
	standart statistic file is: "./statistics.txt"*/

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

	cUnivers(cUnivers &univ);
	/*copy constructor, constructs a copy of the given univers*/


	~cUnivers();
	/*standart destructor
	destructs the univers and closes all open files of the univers*/

	list<cPoint*> &copycUniversStructur(list<cPoint*> &univ) const;
	/*returns a copy of the given univers
	pre: a univers to copy
	post: a copy of the given univers*/

#tested
	list<cPoint*>* getcUniversStructur() {return &univers;}
	/*returns a pointer to the univers
	post: the pointer to the univers structur*/

	TUPart getcUnivers();
	/*returns the univers data
	don't copy the univers
	post: the data of the univers in a TUPart, with the pointer to the univers structur*/

	unsigned long getNumberOfPoints() const {return univers.size();}
	/*returns the number of the points in the univers
	post: the number of the points of the univers*/

	unsigned long getInternalTime() const {return iTime;}
	/*returns the internal Time(number of ticks till creation) of the univers
	post: the internal time of the univers*/

	unsigned long getNumberOfPDistance() const {return pDistance;}
	/*returns the number of the positiv Distances in the univers
	post: the number of the positiv Distances of the univers*/

	unsigned long getNumberOfNDistance() const {return nDistance;}
	/*returns the number of the negativ Distances in the univers
	post: the number of the negativ Distances of the univers*/

	unsigned long* getNumberOfLastTransitions()
	/*returns the number of the different transitions in the last tick(0-9)
	like in the transition diagram above; array point 0 is the transition sum
	post: the number of the transitions of the univers*/
	{trans[0]=trans[1]+trans[2]+trans[3]+trans[4]+trans[5]+trans[6]+trans[7]+trans[8]+trans[9];
	return trans;}

	unsigned long getLastName() const {return last;}
	/*returns the last name number of the univers in the univers
	post: the number of the negativ Distances of the univers*/

	bool getCommentsActiv() const {return outComent;}
	/*returns if comments are shown
	post: true if comments are shown, else false*/

	unsigned long getCutCycle() const {return cutAfter;}
	/*returns the after wich number of maxTime a cut is performed
	if 0 is returned don't cut
	post: after wich number of maxTime a cut is performed*/

	unsigned long getOutcUniversCycle() const {return outUniv;}
	/*returns the after wich number of maxTime a the univers is outputed
	if 0 is returned don't output
	post: after wich number of maxTime the univers is outputed*/

	unsigned long getOutStatisticCycle() const {return outStat;}
	/*returns the after wich number of maxTime a the statistics is outputed
	if 0 is returned don't output
	post: after wich number of maxTime the statistics is outputed*/

	long getTimeBase() const {return bTime;}
	/*returns the time base of the univers(the time the univers begins is user defined)
	post: the time base*/

	unsigned long getMaxNumberOfTime() const {return maxTime;}
	/*returns the maximal Time
	if 0 repeat infinum
	post: the maximal Time*/

	unsigned long getMaxNumberOfPoints() const {return maxPoints;}
	/*returns the maximal number of points(maximal number after a tick)
	if 0 repeat infinum
	post: the maximal number of maxTime*/

	unsigned long getCheckMaxPoints() const {return checkMaxPoints;}
	/*returns every wich number of ticks the maxPoints condition should be
	checked; if 0 never check
	post: the number of ticks the max point condition is checked*/

	char* getStatisticFileName() const {return statFileName;}
	/*returns the statistic file name
	post: the statistic file name*/

	char* getcUniversFolderName() const {return uFolder;}
	/*returns the univers folder name, wher the actual universes files are writen to
	post: the univers folder*/

	char* getcUniversFileBaseName() const {return bUName;}
	/*returns the univers file base name, with wich the saved universes begin with
	post: the univers base name*/

	double getCutNearDimension() const {return cutNearDimension;}
	/*returns the cutNearDimension value
	post: the cutNearDimension value*/

	double getCutMaxClassRatio() const {return cutMaxClassRatio;}
	/*returns the cutMaxClassRatio value
	post: the cutMaxClassRatio value*/

	unsigned long getOutRealTime() const {return outRealTime;}
	/*returns if the real time statistic should be outputed
	post: the outRealTime value*/

	char* getRTimeFileName() const {return rTimeFileName;}
	/*returns the real time statistic file name
	post: the real time statistic name*/

	unsigned long getOutCutStatistic() const {return outCutStatistic;}
	/*returns if the cut statistic should be outputed
	post: the outCutStatistic value*/

	char* getCutFileName() const {return cutFileName;}
	/*returns the cut statistic file name
	post: the cut statistic name*/

//set methods

	unsigned long addNumberOfPDistance(const long pDDist);
	/*adds the given number to the number of positiv distances of the univers
	if the old number of positiv distances plus the given value is lower 0 the
	number of positiv distances is set to 0
	pre: number(positiv or negativ) to add to the positiv distances
	post: the changed postitiv distances of the univers*/

	unsigned long  addNumberOfNDistance(const long nDDist);
	/*adds the given number to the number of negativ distances of the univers
	if the old number of negativ distances plus the given value is lower 0 the
	number of negativ distances is set to 0
	pre: number(positiv or negativ) to add to the negativ distances
	post: the changed negativ distances of the univers*/

	unsigned long addTransPosible(const long ntrans);
	/*adds the given number to the number of posible transitions of the univers
	if the old number of transitions posible plus the given value is lower 0 the
	number of transitions posible is set to 0
	pre: number(positiv or negativ) to add to the transitions posible
	post: the changed transitions posible of the univers*/

	unsigned long evalueTransPosible();
	/*evalues the posible transitions for this univers;
	the transPosible value of this univers is changed
	post: the number of posible transitions*/

	void setCommentsActiv(const bool comAc) {outComent=comAc;}
	/*set if comments are shown
	pre: a value if the comments should be shown*/

	void setCutCycle(const unsigned long cutA){cutAfter=cutA;}
	/*set after wich number of ticks a cut is performed, 0 don't cut
	pre: after wich number of ticks a cut is performed
	post: true if the value is changed, else false*/

	bool setOutStatisticCycle(const unsigned long outS);
	/*set after wich number of ticks a the statistics is outputed, if 0 don't output
	pre: after wich number of ticks the statistics is outputed*/

	void setTimeBase(const long bTim) {bTime=bTim;}
	/*set the time base of the univers(the time the univers begins is user defined)
	pre: the time base*/

	void setMaxNumberOfTime(const unsigned long mTm) {maxTime=mTm;}
	/*set the maximal Time(number of ticks performed), if 0 repeat infinum
	pre: the maximal Time*/

	void setMaxNumberOfPoints(const unsigned long mPoi) {maxPoints=mPoi;}
	/*set maximal number of points(maximal number after a tick)
	if 0 infinum points
	pre: the maximal number of points till stop*/

	void setCheckMaxPoints(const unsigned long cMP) {checkMaxPoints=cMP;}
	/*sets every wich number of ticks the maxPoints condition should be
	checked; if 0 never check
	pre: the number of ticks the max point condition is checked*/

	bool setStatisticFileName(char* statF);
	/*set statistic file name, close the old statistic file, opens the new
	statistic File and print the statistic head to it, if posibel
	pre: a pointer to the statistic file name
	post: true if the change was posibel(could open the new file), else false*/

	bool setOutcUniversCycle(const unsigned long outU);
	/*set after wich number of ticks a the univers is outputed, if 0 don't output
	pre: after wich number of ticks the univers is outputed
	post: true if the value is changed, else false*/

	bool setcUniversFolderName(char* uFol);
	/*set the univers folder name, wher the actual universes files are writen to
	pre: a pointer to the the univers folder
	post: true if the value is changed, else false*/

	bool setcUniversFileBaseName(char* uFB);
	/*set the univers file base name, with wich the saved universes begin with
	pre: the univers base name
	post: true if the value is changed, else false*/

	void setCutNearDimension(const double cND) {cutNearDimension=cND;}
	/*set the cutNearDimension value
	pre: the cutNearDimension value*/

	void setCutMaxClassRatio(const double cMCR) {cutMaxClassRatio=cMCR;}
	/*set the cutMaxClassRatio value
	pre: the cutMaxClassRatio value*/

	bool setOutRealTime(bool rT);
	/*set if the real time statistic should be outputed
	pre: the outRealTime value
	post: true if the value is changed, else false*/

	bool setRTimeFileName(char* rTimeF);
	/*set real time statistic file name, close the old statistic file, opens the new
	statistic File and print the statistic head to it, if posibel
	pre: a pointer to the real time statistic file name
	post: true if the value is changed, else false*/

	void printRealTimeStatisticHead() const;
	/*prints the head of the real time statistic to the real time statistic file*/

	bool setOutCutStatistic(bool cut);
	/*set if the cut statistic should be outputed
	pre: the outCutStatistic value
	post: true if the value is changed, else false*/

	bool setCutFileName(char* cutF);
	/*set cut statistic file name, close the old statistic file, opens the new
	statistic File and print the statistic head to it, if posibel
	pre: a pointer to the cut time statistic file name
	post: true if the value is changed, else false*/

	void printCutStatisticHead() const;
	/*prints the head of the cut statistic to the real time statistic file*/

#tested
	bool printcUnivers(ostream &ostream);
	/*prints the values of the univers to the given output stream, if it exists
	pre: the outputstream ostream to print the univers to
	post: if the stream exists true and the actual univers in the stream
		ostream in a readebel form(integer numbers seperated by ",",";" and "."),
		false else*/

#tested
	bool readcUnivers(istream &stream);
	/*replaces the actual univers with the univers of the stream, if it exists,
	for that deletes the old univers and reads the values of the univers from
	the stream(the values should be of the form of printcUnivers uses)
	pre: the input stream stream to read the univers from
	post: if the stream exists true and this univers is the univers readed from
		the stream, else false*/

	void cutcUnivers(const double dim, const double maxClass);
	/*Trys to delete parts of the univers that are no more conected to the main part.
	The main part is the part, wich is the biggest(in number of Distances)
	under the parts that are not smaler than (maxClass * (biggest Part)) and that
	has a dimension nearest to dim.
	pre: the value of the dimension dim to be nearest to and the minimum ratio
		maxClass the universes to choos must have (if 1 the bigest univers will
		allways be choosen)
	post: the choosen univers as this univers*/

	void evalueTransition(cPoint* poi, unsigned long wich);
	/*Makes a random transition of the transition diagram with the cPoint poi
	(p2 in the diagram) and two random neigthbours(includes new cPoints)(p1 and
	p3 in the diagram).
	pre: the choosen point poi of the univers and the number for wich distances to choos
	post: the this univers changed through the transition
	ATTENTION!: Declared in cPointXXX.cpp file*/

	void tick();
	/*Evalue a tick, minimal time change, of the univers.
	Evalue a transition for ervery point in the univers
	post: this univers changed*/

	void tick(unsigned long trans);
	/*Evalue a tick, minimal time change, of the univers. For that trans
	random choosen points of the univers a random transition is performed.
	Points that have no neigthbours are deleted.
	post: this univers changed*/

	bool printStatisticHead(ostream* ostream) const;
	/*Print the head of the statistics to the statistic stream, if it exists.
	The diverent rows a seperated by ";".
	pre: the output stream ostream to print the statistics head to
	post: true if the stream exists and the head of the statistics in the
		output stream, else false */

	bool printStatistic(ostream* ostream);
	/*Print the the statistics of the actual univers and the last transitions
	to the statistic stream, if it exists. The diverent rows a seperated by ";".
	Prints one line.
	pre: the output stream ostream to print the actual statistics to
	post: if the stream exists true and the actual statistics in the output
		stream, else false*/

	void outputStatistic();
	/*output the the statistics of the actual univers and the last transitions
	to the consol(cout). 
	post:  the actual statistics on the console*/

	bool endCondition() const;
	/*Evalues the end condition for the univers. Means when the evaluation of
	the univers is stoped.
	case 1: the time iTime is higer than the maximum number of ticks(maxTime,
		maxTime=0 -> inf) or (the number of points should be checked (it is the
		checkMaxPoints tick) and it is higher then the maximal number of points
		(maxPoints, maxPoints=0 -> inf))
	post: true if the end condition holds and the univers should be stoped,
		else false*/


	void start(unsigned long trans=0);
	/*Starts the evaluation of the univers. Makes ticks till the end condition
	holds.
	post: the this univers changed*/
	
#tested
	bool operator==(cUnivers &univ);
	/*the equal realtion for cUnivers
	pre: two cUnivers
	post: true if the cUnivers same points in the same amount, false else*/




