/*File Name: Environment.h
  Author: Betti Österholz ; Date: 03.08.2003
  System: C++


  Copyright (C) 2004  Betti Österholz

  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
*/

#ifndef ___ENVIRONMENT_h__
#define ___ENVIRONMENT_h__

#include <string>
#include <sstream>
#include <list>
#include <iostream>

#include "mersenne.h"                   // define classes for random number generators

#include "Parameter.h"
#include "Individual.h"

#include "Vector.h"
#include "Color.h"
#include "Position.h"
#include "PicturObject.h"
#include "Function.h"
#include "Area.h"
#include "Conc.h"
#include "Point.h"

using std::cout;
using std::endl;
using std::flush;
using std::list;
using std::stringstream;

class Environment
{
protected:

Parameter ParameterV;

list<Individual*> IndividualList;
long double GoodnessSum;
long double BadnessSum;//Badness=1/Goodness
double BestGoodness;
PicturMatrix Original;
unsigned long LastId;
TRandomMersenne rg;//random generator
unsigned long MaxTimeNeed;
list<Individual*> ImmortalList;//the list of imortal individuals
long double WorstImmortal;

unsigned int printPrimitivDocu;//to count the Iterations till the last output of the primitv documentation (Documentation of DocumentParamter 7 and 8)


public:

	Environment();
	//standart constructor
	//doe's nothing

	Environment(Parameter parm);
	//special constructor
	//set the parameters
	//pre: the parameter for the new Enviroment object
	
	~Environment();
	//standart destructor

	void start();
	//the method to start the genetic allgorithm

	void init();
	//this method initialisize the Individuals

	bool reachTerminalCondition() const;
	//returns if the terminal condition is reached
	//post: true if the terminal condition is reached

	void load(const char* file,const unsigned int num);
	//load n Pictur objects from the file file into this object
	//if no n objects load as much as exsists

	void makeNewIndividual();
	//makes a new Individual with the genetic operations and put it to
	//the Individuals in the IndividualList

	void eraseIndividual();
	//erase Individuals from the IndividualList till it has the right size

	bool insertIndividual(Individual* idv);
	//insert a Individual to the IndividualList, if non equal(Value)
	//Individual is in the IndividualList

	bool insertObject(PicturObject* obj);
	//insert a Individual in the IndividualList, if non equal(Value)
	//Individual is in the IndividualList
	//the new Individual is createt from the given Object obj
	//if the created Individual could not inserted the given object is destroyd
	//pre: the Picturobject obj to create the new inividual from
	//post: a new Individual with the given object in the individual list
	//  if no equal individual are allready in it

	double getRandom(long double max) const;
	//to get a random number from 0 to max, ther are (ULONG_MAX) random numbers
	//pre: the maximum for the random number
	//post: a random number from 0 to max

	double getGoodness(PicturObject* obj);
	//returns the Goodness of the given Pictur Object to the Orginal PicturMatrix
	//post: a double value for the Goodness of the given Pictur Object to the 
	//  Orginal PicturMatrix

	bool setParameter(Parameter parm);
	//set the parameters to the given parameters parm
	//pre: the parameters to set the parameters of this object to
	//post: true if the parameters are set, else false

	Parameter getParameter() const;
	//retuns the Parameters of this object
	//post: the parameters of this object

	unsigned long getNumberOfIndividuals() const;
	//returns the number of individuals in the Individual list
	//post:the number of individuals in the Individual list

	Individual* selectIndividual();
	//select a individual from the individual list
	//post: a individual from the individual list

	PicturObject* Operation0(PicturObject* obj);
	//insert a new random Point on a random position in a selected 
	//PicturObject that overlap the selected object

	PicturObject* Operation1(PicturObject* obj);
	//insert a new random Point on a random position in a selected
	//PicturObject that is overlap by the selected object

	PicturObject* selectPartObject(PicturObject* obj);
	//select a part object from the given PicturObject obj
	//pre: a PicturObject to select a part object from
	//post: the copy of the selected a part object from the given PicturObject obj

	PicturObject*  Operation2(PicturObject* obj);
	//insert a random PartObject of a selected PicturObject on a random
	//position in a other selected PicturObject that overlap the selected PartObject

	PicturObject* Operation3(PicturObject* obj);
	//insert a random PartObject of a selected PicturObject on a random
	//position in a other selected PicturObject that not overlap the selected PartObject

	PicturObject* Operation4(PicturObject* obj);
	//delete a part object of the copy of a selected individual

	PicturObject* Operation5(PicturObject* obj);
	//change a value of the copy of a selected individual

	PicturObject* Operation6(PicturObject* obj);
	//change a variable of the copy of a selected individual

	PicturObject* Operation7(PicturObject* obj);
	//insert a new Variable, on a position wher a value stands, that is defined
	//over the object in wich is the Vector wher the variable is inserted

	PicturObject* Operation8(PicturObject* obj);
	//insert a new Value on a position wher a variable stands, that is generated
	//random

	PicturObject* Operation9(PicturObject* obj);
	//insert a new Function element on the root position and insert the
	//variable that the new Function element define an a random position

	PicturObject* Operation10(PicturObject* obj);
	//insert a new Area element on the root position and insert the
	//variable that the new Area element define an a random position

	PicturObject* Operation11(PicturObject* obj);
	//deletes from 10 Area or Function Elements on a random position the
	//Elements that can be deleted(the variable they define are not required below them)

	PicturObject* Operation12(PicturObject* obj);
	//insert a function vector in a function vector list of a random choosen function element

	PicturObject* Operation13(PicturObject* obj);
	//insert a area vector in a area vector list of a random choosen Area element

	PicturObject* Operation14(PicturObject* obj);
	//remove a random choosen list vector

	PicturObject* Operation15(PicturObject* obj);
	//move a random choosen element af a random choosen Individual random choosen steps

	PicturObject* Operation16(PicturObject* obj);
	//flip the objects of a random choosen conc Object

	PicturObject* Operation17(PicturObject* obj);
	//insert a random Point from the original in a selected PicturObject that overlap the selected object

	PicturObject* Operation18(PicturObject* obj);
	//insert a random Point from the original in a selected PicturObject that not overlap the selected object

	PicturObject* Operation19(PicturObject* obj);
	//deletes a random ListVector Object that is may be not needed
	//replaces the defined variable of this object with the value that uis
	//defined by the Listobject
	//if the choosen ListObject has just values in his list vectors and the
	//values stands for one(Area) evaluted value the function of the ListObject
	//define, the ListVector element is deleted and the variable it defined is
	//replaced by the value
	//try deleting 10 chosen ListVectors, till one is deleted

	PicturObject* Operation20(PicturObject* obj);
	//insert slanting variables

	PicturObject* Operation21(PicturObject* obj);
	//insert a slanting line

};

#endif
