/*File Name: Conc.cpp
  Author: Betti Österholz ; Date: 18.08.2003
  System: C++

  This is implementation of the Basisclass of all conc objects


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

#include "Conc.h"
//---------------------------------------------------------------------------

//constructors:
Conc::Conc():PicturObject(),Object1(0),Object2(0)
//standart constructor
//constructs a conc object with two PicturObject poiter pointed to 0
{}

Conc::Conc(PicturObject* obj1,PicturObject* obj2):PicturObject(),Object1(obj1),Object2(obj2)
//special constructor
//constructs a conc object with two PicturObject poiter pointed to
//the given objects(if just one given the secound pointer pointed to 0)
//attention: the given objects will not be copied
//pre: the two PicturObject pointers of the Picturobjects to insert
{}

Conc::Conc(const Conc& conc):PicturObject()
//copy constructor
//constructs a copy of the given Conc object
//attention: copy the objects from the given conc object with ther
//  copy constructor
//pre: the Conc object conc to copy
{
Object1= (conc.getNext(true))->copy();//copy first Object of the given conc Object
Object2= (conc.getNext(false))->copy();//copy secound Object of the given conc Object
}

Conc::~Conc()
//destructor
//attention: this destructor destruct just the element and not the 
//objects in it
//nothing to do
{}

//Methodes to get greatnes of order:
unsigned int Conc::getNumberOfValue() const
//evaluate the number of values in this object
//post: Numbers of values in this object
{return ((Object1->getNumberOfValue())+(Object2->getNumberOfValue()));}

unsigned int Conc::getNumberOfVariable() const
//evaluate the number of variables in this object
//post: Numbers of Variables in this object
{return ((Object1->getNumberOfVariable())+(Object2->getNumberOfVariable()));}

unsigned int Conc::getNumberOfListVectors() const
//evaluate the number of List Vectors in this object
//post: Numbers of List Vectors in this object
{return ((Object1->getNumberOfListVectors())+(Object2->getNumberOfListVectors()));}

unsigned int Conc::getNumberOfMovePoints() const
//evaluate the number of Move Points in this object
//post: Numbers of Move Points in this object
{return ((Object1->getNumberOfMovePoints())+(Object2->getNumberOfMovePoints()));}

unsigned int Conc::getNumberOfObjects() const
//evaluate the number of Conc in this object
//post: Numbers of Conc in this object
{
if (Object1==0)
	{if (Object2==0)
	//if both are 0
		{return 1;}
	else
	//if just Object1 is 0
		{return ((Object2->getNumberOfObjects())+1);}
}
if (Object2==0)
//if just Object2 is 0
	{return ((Object1->getNumberOfObjects())+1);}
//if non is 0
return ((Object1->getNumberOfObjects())+(Object2->getNumberOfObjects())+1);
}

unsigned int Conc::getNumberOfConc() const
//evaluate the number of conc Objects in this object
//post: Numbers of conc Objects in this object
{return ((Object1->getNumberOfConc())+(Object2->getNumberOfConc())+1);}

unsigned int Conc::getNumberOfPoints() const
//evaluate the number of PointObject in this object
//post: Numbers of PointObject in this object
{return getNumberOfConc()+1;}

unsigned int Conc::getNumberOfObjectPoints() const
//evaluate the number of real part objects in this object,
//real part objects are part objects how has from a conc
//object downwarts all objects in the conc objects and
//upwarts just one
//post: Numbers of real part objects in this object
{return (getNumberOfConc()*2);}

unsigned int Conc::getNumberOfFunctions() const
//evaluate the number of Function in this object
//post: Numbers of Function in this object
{return ((Object1->getNumberOfFunctions())+(Object2->getNumberOfFunctions()));}

unsigned int Conc::getNumberOfArea() const
//evaluate the number of area Objects in this object
//post: Numbers of area Objects in this object
{return ((Object1->getNumberOfArea())+(Object2->getNumberOfArea()));}

//other get Functions:

int Conc::getValue(unsigned int n) const
//to get the value, of the value with number n in the order of values
//pre: the number n, in the order of values, of the value to return
//post: the value of the value
{
unsigned int x = Object1->getNumberOfValue();
if (x>=n)
{	return Object1->getValue(n);}
return Object2->getValue(n-x);
}

double* Conc::getVariable(unsigned int n) const
//to get the pointer to the variable with number n in the order of variables
//pre: the number n, in the order of variables, of the variable to return
//post: the pointe for the variable
{
unsigned int x = Object1->getNumberOfVariable();
if (x>=n)
{	return Object1->getVariable(n);}
return Object2->getVariable(n-x);
}

unsigned long Conc::getGreatness() const
//to get a idea how great the object is
//post: a number for how great the object is
{return ((Object1->getGreatness())+(Object2->getGreatness())+1);}

unsigned long Conc::getTimeNeed(unsigned long max) const
//to get a idea how long the object need to evaluate 
//post: a number for how much time the object need to evaluate
{
unsigned int tmp=(Object1->getTimeNeed(max));
if (tmp>max) {return tmp;}//yust evalue till the max value is toped
return (tmp+(Object2->getTimeNeed(max))+1);}

bool Conc::isUsedVariable(double* var) const
//checks if the given pointer for a variable var is somewhere in the 
//object(than it is used in the object)
//pre: the pointer for the variable var to search for
//post: true if the variable is find(used), false else
{return ((Object1->isUsedVariable(var))||(Object2->isUsedVariable(var)));}

PicturObject* Conc::getObjectFrom(unsigned int n) const
//to get the object wich has the value n in the order of objects
//pre: the value n in the order of objects of the object to get
//post: the object with the value n in the order of objects if exsits
//     or 0 if not
{
unsigned int x=0;
if (Object1)//if Object1 exsists
{
	x = Object1->getNumberOfObjects();
	if (n==x) return Object1;
	if (n<x) return Object1->getObjectFrom(n);
}
if (Object1)//if Object2 exsists
{
	unsigned int y = Object2->getNumberOfObjects();
	if (n==(x+y+1)) return Object2;
	return Object2->getObjectFrom(n-x-1);
}
return 0;
}

Vector* Conc::getListVectorFrom(unsigned int n) const
//to get the list vector wich has the value n in the order of list vectors
//pre: the value n in the order of list vectors of the list vector to get
//post: the list vector with the value n in the order of list vectors
//    if exsits or 0 if not
{
unsigned int x = Object1->getNumberOfListVectors();
if (n<=x)
{	return Object1->getListVectorFrom(n);}
return Object2->getListVectorFrom(n-x);
}

PicturObject* Conc::getNext(bool b) const
//to get the next object, means the object under the object from wich
//it is called, if the object from wich it is called is a conc object
//gets the first of his objects if b ist true else the second
//pre: a bool value if you want the first(true) or the second(false)
//   object, if ther are two
//post: the object with the value n in the order of objects if exsits
//     or 0 if not
{
if (b) {return Object1;}
return Object2;
}

unsigned int Conc::partObjectToPointPartObject(unsigned int n) const
//to get the value in the point part object order of the object wich
//has the value n in the order of part objects
//pre: the value n in the order of part objects of the object
//post: the value n in the order of point part objects of the same object
//  or 0 if it is no point part object
{
unsigned int x = Object1->getNumberOfConc();
if (n<=(x*2))
	{return Object1->partObjectToPointPartObject(n);}
if (n>=(x*2+2))
	{return ((Object2->partObjectToPointPartObject(n-x*2-2))+x+1);}
return 0;
}

unsigned int Conc::pointPartObjectToPartObject(unsigned int n) const
//to get the value in the part object order of the object wich 
//has the value n in the order of point part objects
//pre: the value n in the order of point part objects of the object
//post: the value n in the order of part objects of the same object
{
unsigned int x = Object1->getNumberOfConc();
if (n<=(x+1))
	{return Object1->partObjectToPointPartObject(n);}
return ((Object2->partObjectToPointPartObject(n-x-1))+x*2+2);
}

unsigned int Conc::movePointToObjectPoint(unsigned int n) const
//to get the value in the object order of the object wich 
//has the value n in the order of move point objects
//pre: the value n in the order of move point objects of the object
//post: the value n in the order of objects of the same object
{
unsigned int x = Object1->getNumberOfMovePoints();
if (n<=x)
	{return Object1->movePointToObjectPoint(n);}
return ((Object2->movePointToObjectPoint(n-x))+Object1->getNumberOfObjects()+1);
}

bool Conc::isDeletableElement() const
//checks if the Element(this) is deletable(Points and conc objects 
//never are, Functions and Area objects are if the variable they define
//is not used)
//post: true if the element is deletable else false
{return false;}

bool Conc::isUsedVariableInElement(double* var) const
//checks if the variable var is used in the object if so returens
//true else false
//pre: the double pointer for the variable to check
//post: true if the variable is used else false
{return false;}

double* Conc::getDefinedVariableFrom(unsigned int n) const
//to get the variable the object, with the value n in the order of
//move point, defined
//pre: the value n of a object in the order of move points
//post: the double pointer of the variable the same object defined 
//  or 0 if no such variable/object
{
unsigned int x = Object1->getNumberOfMovePoints();
if (n<=x)
	{return Object1->getDefinedVariableFrom(n);}
return Object2->getDefinedVariableFrom(n-x);
}

std::list<double*> Conc::getAllDefinedVariableOver(unsigned int n) const
//to get a list off all the Variables defined over the object, with
//the value n in the order of move points
//so you know wich varibles this object can use
//pre: the value of the object, in the order of move point, from
//  wich to get the list of variables defined in objects wich
//  are over it
//post: the list of double pointer of variables wich are defined over it
{
unsigned int x = Object1->getNumberOfMovePoints();
if (n<=x)
	{return Object1->getAllDefinedVariableOver(n);}
return Object2->getAllDefinedVariableOver(n-x);
}

std::list<double*> Conc::getAllDefinedVariableOverValue(unsigned int n) const
//to get a list off all the Variables defined over the value, with
//the value n in the order of values
//so you know wich varibles this value can be seted to
//pre: the value of the value, in the order of values, from
//  wich to get the list of variables defined in objects wich
//  are over it
//post: the list of double pointer of variables wich are defined over it
{
unsigned int x = Object1->getNumberOfValue();
if (n<=x)
	{return Object1->getAllDefinedVariableOverValue(n);}
return Object2->getAllDefinedVariableOverValue(n-x);
}

std::list<double*> Conc::getAllDefinedVariableOverVariable(unsigned int n) const
//to get a list off all the variables defined over the variable, with
//the value n in the order of variable
//so you know wich varibles this variable can be seted to
//pre: the value of the variable, in the order of variable, from
//  wich to get the list of variables defined in objects wich
//  are over it
//post: the list of double pointer of variables wich are defined over it
{
unsigned int x = Object1->getNumberOfVariable();
if (n<=x)
	{return Object1->getAllDefinedVariableOverVariable(n);}
return Object2->getAllDefinedVariableOverVariable(n-x);
}

//Methodes wich changes the Object:

bool Conc::setValueToValue(unsigned int n, int val)
//set the value, of the value with number n in the order of values,
//to the given new value val
//pre: the number n, in the order of values, of the value to set and
//     the value val to set it to
//post: true if the value is set, false else
{
unsigned int x = Object1->getNumberOfValue();
if (n<=x)
	{return Object1->setValueToValue(n,val);}
return Object2->setValueToValue(n-x,val);
}

bool Conc::setValueToVariable(unsigned int n, double* var)
//set the value, of the value with number n in the order of values,
//to the given pointer for the variable var
//pre: the number n, in the order of values, of the value to set and
//     the pointer for the variable var to set it to
//post: true if the value is set, false else
{
unsigned int x = Object1->getNumberOfValue();
if (n<=x)
	{return Object1->setValueToVariable(n,var);}
return Object2->setValueToVariable(n-x,var);
}

bool Conc::setVariableToVariable(unsigned int n, double* var)
//set the variable, with number n in the order of variables,
//to the given pointer for the new variable var
//pre: the number n, in the order of variables, of the variable to set and
//     the pointer for the new variable var to set it to
//post: true if the varable is set, false else
{
unsigned int x = Object1->getNumberOfVariable();
if (n<=x)
	{return Object1->setVariableToVariable(n,var);}
return Object2->setVariableToVariable(n-x,var);
}

unsigned int Conc::setVariableToVariable(double* var1,double* var2)
//set on the positions wher the variable var1 in the object stand the
//variable var2
//pre: the variable var1 to set to the variable var2 and the variable var2
//post: the number of variables set
{
return ((Object1->setVariableToVariable(var1,var2))+(Object2->setVariableToVariable(var1,var2)));
}

bool Conc::setVariableToValue(unsigned int n, int val)
//set the variable, with number n in the order of variables,
//to the given value val and make it a value
//pre: the number n, in the order of variables, of the variable to set and
//     the value val to set it to
//post: true if the varable is set, false else
{
unsigned int x = Object1->getNumberOfVariable();
if (n<=x)
	{return Object1->setVariableToValue(n,val);}
return Object2->setVariableToValue(n-x,val);
}

unsigned int Conc::setVariableToValue(double* var1,int val)
//set on the positions wher the variable var1 in the object stand the
//value val
//pre: the variable var1 to set to the value val and the value val
//post: the number of variables set
{
return ((Object1->setVariableToValue(var1,val))+(Object2->setVariableToValue(var1,val)));
}

bool Conc::changeValueAbout(unsigned int n, int dist)
//set the value, of the value with number n in the order of values,
//to a new value, wich is evaluated from the old value plus the
//value dist
//pre: the number n, in the order of values, of the value to set and
//     the distance dist, to change it about
//post: true if the value is set, false else
{
unsigned int x = Object1->getNumberOfValue();
if (n<=x)
	{return Object1->changeValueAbout(n,dist);}
return Object2->changeValueAbout(n-x,dist);
}

bool Conc::insertObjectInObject(unsigned int n, PicturObject* obj,bool ov)
//insert the object obj in the object with the value n in the order
//of objects,
//if ov are true obj is inserted as the first object in the new conc
//object(obj can be overlapped) else as the secound(not overlapped)
//pre: the position in the object order to insert it(should not be
//  a point), the pointer to the object to insert(the pointer is inserted)
//  and the bool value if it can be overlapped
//post: true if the object obj was inserted
{
unsigned int x = Object1->getNumberOfObjects();
if (n==x)
{
	if (ov) Object1= new Conc(obj,Object1);
	else Object1= new Conc(Object1,obj);
	return true;
}
if (n<=x)
{	return Object1->insertObjectInObject(n,obj,ov);}
unsigned int y = Object2->getNumberOfObjects();
if (n==(x+y+1))
{
	if (ov) Object2= new Conc(obj,Object2);
	else Object2= new Conc(Object2,obj);
	return true;
}
return Object2->insertObjectInObject((n-x-1),obj,ov);
}

bool Conc::overwriteObjectWithObject(unsigned int n, PicturObject* obj)
//overwrite the object, wich has the value n in the order of objects,
//with the given object obj
//attention: the overwriten object will not be deleted
//pre: the position n in the order of objects of the object to
//   overwrite and the object obj with wich to overwrite it
//post: true if the object is overwriten else false
{
unsigned int x = Object1->getNumberOfObjects();
if (n==x)
{
	Object1= obj;
	return true;
}
if (n<=x)
{	return Object1->overwriteObjectWithObject(n,obj);}
unsigned int y = Object2->getNumberOfObjects();
if (n==(x+y+1))
{
	Object2=obj;
	return true;
}
return Object2->overwriteObjectWithObject((n-x-1),obj);
}

bool Conc::removeObject(unsigned int n)
//removes the object wich has the value n in the part object order
//pre: the value n, in the order of part objects, of object to remove
//post: true if the object was removed else false
{
unsigned int x = Object1->getNumberOfObjectPoints();
if (n==x+1)
{
	Object1->deleteObject();
	delete Object1;
	Object1=Object2;//flip Object2 and Object1
	Object2=0;
	return true;
}
if (n==x+2)
{
	Object2->deleteObject();
	delete Object2;
	Object2=0;
	return true;
}
if (n<x)
{
	if (Object1->removeObject(n))//if a object in a conc object is deleted
	{
		if (Object1->hasUnderAllObjects())//if the object under this has all objects, it is not the object wher a object was deleted
			{return true;}
		else{//if the UnderObject was the conc object wher a object was deleted
			unsigned int x=Object1->getNumberOfObjects();
			PicturObject* tobj=Object1->getObjectFrom(x-1);//get the object under it, that was not deleted
			delete Object1;//delete the conc object
			Object1=tobj;//set the not deleted object as the nes UnderObject
			return true;
		}
	}
}

if (Object2->removeObject(n-x-2))//if a object in a conc object is deleted
{
	if (Object2->hasUnderAllObjects())//if the object under this has all objects, it is not the object wher a object was deleted
		{return true;}
	else{//if the UnderObject was the conc object wher a object was deleted
		unsigned int x=Object2->getNumberOfObjects();
		PicturObject* tobj=Object2->getObjectFrom(x-1);//get the object under it, that was not deleted
		delete Object2;//delete the conc object
		Object2=tobj;//set the not deleted object as the nes UnderObject
		return true;
	}
}
return false;
}

bool Conc::removeElement(unsigned int n)
//removes the element wich has the value n in the order of move points
//(the object the element contain goes to the position wher the 
//element was)
//pre: the value n in the order of move points of the element to remove
//post: true if the element is removed else false
{
PicturObject* tobj= cutElement(n);
if (tobj)
{
	delete tobj;
	return true;
}
return false;
}

bool Conc::removeListVector(unsigned int n)
//removes the vector in a list wich has the value n in the order of
//list vectors
//pre: the value n in the order of list vectors of the vector to remove

//post: true if the vector is removed else false
{
unsigned int x = Object1->getNumberOfListVectors();
if (n<=x)
	{return Object1->removeListVector(n);}
return Object2->removeListVector(n-x);
}

PicturObject* Conc::cutElement(unsigned int n,bool b)
//cut the element wich has the value n in the order of move point
//(delete the element on the position and return it)
//if b is false test if the variable the object define is needed and
//if that is true don't delete the object
//pre: the value n in the order of move points of the element to cut
//post: the cuted element
{
unsigned int x = Object1->getNumberOfMovePoints();
if (n==x)
{
	if ((Object1->classnameOf())!="Conc")//if the underObject is not a conc object
	{
		if (b||Object1->isDeletableElement())
		{
			PicturObject* tmp=Object1;
			Object1=Object1->getNext();
			return tmp;
		}else{return 0;}
	}else{return Object1->cutElement(n);}
}
if (n<x)
	{return Object1->cutElement(n);}
unsigned int y = Object2->getNumberOfMovePoints();
if (n==x+y)
{
	if ((Object2->classnameOf())!="Conc")//if the underObject is not a conc object
	{
		if (b||Object2->isDeletableElement())
		{
			PicturObject* tmp=Object2;
			Object2=Object2->getNext();
			return tmp;
		}else{return 0;}
	}
}
return Object2->cutElement(n-x);
}

void Conc::deleteObject()
//deletes the object(the element and all objects in it, uses the
//destructors)
{
Object1->deleteObject();
Object2->deleteObject();
delete Object1;
delete Object2;
Object1=0;
Object2=0;
}

bool Conc::flipObjects(unsigned int n)
//flips the objects of the conc object with the value n in the order
//of flip points(=conc objects) (oject1:=object2 and object2:=object1)
//pre: the value n in the order of flip point of the conc object
//  wich contained objects shold be fliped
//post true if the objects are fliped else false
{
unsigned int x = Object1->getNumberOfConc();
if (n<=x)
	{return Object1->flipObjects(n);}
if (n>x+1)
	{return Object2->flipObjects(n-x-1);}
PicturObject* tmp=Object2;
Object2=Object1;
Object1=tmp;
return true;
}

bool Conc::moveElement(unsigned int n, int howfar)
//move the element with the value n in the order of move points
//howfar steps(over howvar elements down if howfar is positiv else
//over howfar steps up)
//pre: the value n in the order of move point of the object to move
//  and the distanc howfar to move it
//post: true if the object is moved(even if just not howfar steps)
//  else false
{
return moveElementTo(n,0,howfar);
}

bool Conc::moveElementTo(unsigned int & n,PicturObject* obj,int& howfar)
//moves the object obj that(should) stand an the position n in the
//order of move points howfar steps(over howvar elements down if
//howfar is positiv else over howfar steps up)
//obj is needed for the algorithmus of moving
//pre: the position n in the order ofmove points wher the object
//  obj (should)stand, howfar to move it and a Conc pointer
//  for the object
//post: true if the object is moved (even if just not howfar steps)
//  else false
{
if (n==0) {return false;}//no object to move
if (howfar==0)
{
	if (obj==0) return true;//nothing to do
	double* dvar=obj->getDefinedVariableFrom(n);
	bool u1=Object1->isUsedVariable(dvar);
	bool u2=Object2->isUsedVariable(dvar);
	if (u1 && !u2)
	//obj in first object needed
	{
		obj->insertObject(Object1);//aktuell wher the variable is needed in the to move object
		Object1=obj;//to move object as actual
	}
	if (!u1 && u2)
	//obj in secound object needed
	{
		obj->insertObject(Object2);//aktuell wher the variable is needed in the to move object
		Object2=obj;//to move object as actual
	}
	if (u1 && u2)
	//obj in bouth objects needed
	{
		PicturObject* elm2=obj->copyElement(obj->getNumberOfObjects());
		obj->insertObject(Object1);//aktuell wher the variable is needed in the to move object
		Object1=obj;//to move object as actual
		Object2->setVariableToVariable(obj->getDefinedVariableFrom(obj->getNumberOfMovePoints()), elm2->getDefinedVariableFrom(elm2->getNumberOfMovePoints()));
		elm2->insertObject(Object2);//aktuell wher the variable is needed in the to move object
		Object2=elm2;//to move object as actual
	}
	if (!u1 && !u2)
	//obj in non needed
	{
		obj->insertObject(Object1);//insert yust in first
		Object1=obj;//to move object as actual Object1
	}
	return true;
}//end howfar==0
if (howfar>0)//move obj down
{
	unsigned int mp1 = Object1->getNumberOfMovePoints();
	unsigned int mp2 = Object2->getNumberOfMovePoints();
	if (mp1==n)//the first object is the element to move?
	{
		unsigned int o=Object1->movePointToObjectPoint(n);
		if ((Object1->classnameOf())!="Conc")//the first object is the element to move=not a conc object
		{
			//test if moving is posible
			PicturObject* obj2=Object1->getObjectFrom(o-1);//get the object over the to moving
			double* var=Object1->getDefinedVariableFrom(n);
			if (obj2->isUsedVariableInElement(var))//can not move
			{return true;}
			else{
				PicturObject* obj1=Object1;
				Object1=obj2;
				howfar=howfar-1;
				if (Object1->moveElementTo(n,obj1,howfar))//object is moved
					{return true;}
				else{
					howfar=0;
					return moveElementTo(n,obj1,howfar);
				}
			}
		}else
		{return Object1->moveElementTo(n,obj,howfar);}
	}
	if ((mp1+mp2)==n)//the secound object is the element to move?
	{
		unsigned int o1=Object2->movePointToObjectPoint(mp2);
		if ((Object2->classnameOf())!="Conc")//the secound object is the element to move=not a conc object
		{
			//test if moving is posible
			PicturObject* obj2=Object2->getObjectFrom(o1-1);//get the object over the to moving
			double* var=getDefinedVariableFrom(n);
			if (obj2->isUsedVariableInElement(var))//can not move
				{return true;}
			else{
				PicturObject* obj1=Object2;
				Object2=obj2;//cut the secound element
				howfar=howfar-1;
				n=n-Object1->getNumberOfMovePoints();
				if (Object2->moveElementTo(n,obj1,howfar))//object is moved
					{return true;}
				else{
					howfar=0;
					n=getNumberOfMovePoints();
					return moveElementTo(n,obj1,howfar);
				}
			}
		}else
			{return Object2->moveElementTo(n,obj,howfar);}
	}






	if (mp1>n)//the to move object is in the first object
	{return Object1->moveElementTo(n,obj,howfar);}
	if ((mp1<n)&&((mp1+mp2)>n))//the to move object is in the secound object
	{return Object2->moveElementTo(n,obj,howfar);}
	//else the to move object is to move further down ((mp1+mp2)<n n is
	//over this object)
	if (obj==0) {return true;}//nothing to do should not happen
	double* dvar=obj->getDefinedVariableFrom(obj->getNumberOfMovePoints());
	bool u1=Object1->isUsedVariable(dvar);
	bool u2=Object2->isUsedVariable(dvar);
	if (u1 && !u2)
	//obj in first object needed
	{
		if (Object1->isUsedVariableInElement(dvar))//can not move
			{howfar=0;
			return moveElementTo(n,obj,howfar);}//insert here
		else{
			howfar=howfar-1;
			if (Object1->moveElementTo(n,obj,howfar))//object is moved
				{return true;}
			else{
				howfar=0;
				return moveElementTo(n,obj,howfar);//insert here when not moved
			}
		}
	}
	if (!u1 && u2)
	//obj in secound object needed
	{
		if (Object2->isUsedVariableInElement(dvar))//can not move
		{
			howfar=0;
			return moveElementTo(n,obj,howfar);}//insert here
		else{
			howfar=howfar-1;
			if (Object2->moveElementTo(n,obj,howfar))//object is moved
				{return true;}
			else{
				howfar=0;
				return moveElementTo(n,obj,howfar);//insert here when not moved
			}
		}
	}
	if (u1 && u2)
	//obj in bouth objects needed
	{
		if (Object1->isUsedVariableInElement(dvar))//can not move
		{//insert here
			obj->insertObject(Object1);//aktuell wher the variable is needed in the to move object
			Object1=obj;//to move object as actual
		}
		else{
			howfar=howfar-1;
			if (!(Object1->moveElementTo(n,obj,howfar)))//object is not moved
			{//insert here when not moved
				obj->insertObject(Object1);//aktuell wher the variable is needed in the to move object
				Object1=obj;//to move object as actual
			}
		}
		PicturObject* elm2=obj->copyElement(obj->getNumberOfObjects());
		double* dvar2=elm2->getDefinedVariableFrom(0);
		Object2->setVariableToVariable(dvar,dvar2);
		if (Object2->isUsedVariableInElement(dvar2))//can not move
		{//insert here
			elm2->insertObject(Object2);//aktuell wher the variable is needed in the to move object
			Object2=elm2;//to move object as actual
			return true;
		}
		else{
			howfar=howfar-1;
			if (Object2->moveElementTo(n,elm2,howfar))//object is moved
				{return true;}
			else{
				//insert here when not moved
				elm2->insertObject(Object2);//aktuell wher the variable is needed in the to move object
				Object2=elm2;//to move object as actual
				return true;
			}
		}
	}
	if (!u1 && !u2)
	//obj in non needed, insert yust in first object
	{
		howfar=howfar-1;
		if (Object1->moveElementTo(n,obj,howfar))//object is moved
			{return true;}
		else{
			howfar=0;
			return moveElementTo(n,obj,howfar);//insert here when not moved
		}
	}
}//end howfar>0
if (howfar<0)//move obj up
{
	unsigned int x=Object1->getNumberOfMovePoints();
	if (x>=n)//to move object is in the first object
	{
		if (x==n)//to move object is the first move object in the first object
		{
			PicturObject* objv=cutElement(n,true);
			if (objv)
			{
				objv->insertObject(Object2);
				Object2=objv;
				n=(Object1->getNumberOfMovePoints()+Object2->getNumberOfMovePoints());
				return true;
			}else{return false;}
		}
		if (x>n)//to move object is in the first object, but not it
		{
			bool ok=Object1->moveElementTo(n,obj,howfar);
			if (!ok)//doesn't move
				{return false;}
			if (howfar>0) {return true;}//the to move object is at the rigth plase
			unsigned int o=Object1->movePointToObjectPoint(n);//n could change
			unsigned int y=Object1->getNumberOfObjects();//could change
			if ((o+1)==y)//the to move object is two steps down
			{
				//test if moving is posible
				PicturObject* obj=Object1->getObjectFrom(o);
				double* var=Object1->getDefinedVariableFrom(Object1->getNumberOfMovePoints());
				if (obj->isUsedVariableInElement(var))//can not move
				{
					howfar=1;
					return true;
				}
				else{//move to move object in secound object
					PicturObject* obv=cutElement(n,true);
					if (obv)
					{
						if (howfar==-1)//move just one step upwarts
						{
							obv->insertObject(Object1);
							Object1=obv;//flip them
							howfar=1;
							n=n+1;
						}else{//move more then one step upwarts
							obv->insertObject(Object2);
							Object2=obv;//flip them
							howfar=howfar+1;
							n=(Object1->getNumberOfMovePoints()+Object2->getNumberOfMovePoints());//new position n
						}
						return true;
					}else{return false;}
				}
			}else{//last a conc object move the to move object
				PicturObject* objv=cutElement(n,true);
				if (objv)
				{
					objv->insertObject(Object2);
					Object2=objv;
					n=(Object1->getNumberOfMovePoints()+Object2->getNumberOfMovePoints());
					return true;
				}else{return false;}
			}
		}
	}else{//to move object is in the secound object
		unsigned int x2=Object2->getNumberOfMovePoints();
		unsigned int n1=n-x;
		x=x+x2;
		if (x==n)//to move object is the secound object?
			{return true;}
		if (x>n)//to move object is in the secound object, but not it
		{
			bool ok=Object2->moveElementTo(n1,obj,howfar);//side effect n1=n
			if (!ok)//doesn't move
				{return false;}
			if (howfar>0) {return true;}//the to move object is at the rigth plase
			unsigned int o=Object2->movePointToObjectPoint(n);//n could change
			unsigned int y=Object2->getNumberOfObjects();//could change
			if ((o+1)==y)//the to move object is two steps down
			{//move the move object one step up
				PicturObject* obj=Object2->getObjectFrom(o);//get to move object
				double* var=Object2->getDefinedVariableFrom(Object2->getNumberOfMovePoints());
				if (obj->isUsedVariableInElement(var))//can not move
				{
					howfar=1;
					return true;
				}else{
					PicturObject* obv=Object2->cutElement(n,true);
					if (obv)
					{
						obv->insertObject(Object2);
						Object2=obv;
						if (howfar==-1)//move just one step upwarts
							{howfar=1;}
						else{howfar=howfar+1;}
						n=(Object1->getNumberOfMovePoints()+Object2->getNumberOfMovePoints());
						//new position n
						return true;
					}else{return false;}
				}
			}else{//last a conc object move the move object
				return true;
			}
		}
	}
}//end howfar>0
return false;
}


bool Conc::insertObject(PicturObject* obj)
//insert the object obj in this object
//attention: the old (now overwriten) object don't be deleted
//pre: the to insert object obj
//post: true if the object is inserted else false
{return false;}

bool Conc::insertFunctionVector(unsigned int n,UnderFunction* fkt)
//insert the UnderFunction vector fkt in the UnderFunction vector list
//of object with the value n in the order of Function objects
//pre: the to insert UnderFunction vector fkt and the position in the
//  order of Function objects to insert it
//post: true if the UnderFunction is inserted else false
{
unsigned int x=Object1->getNumberOfFunctions();
if (x>=n)
{
	return Object1->insertFunctionVector(n,fkt);
}
return Object2->insertFunctionVector(n-x,fkt);
}

bool Conc::insertAreaVector(unsigned int n,UnderArea* area)
//insert the UnderArea vector area in the UnderArea vector list
//of object with the value n in the order of Area objects
//pre: the to insert UnderArea vector area and the position in the
//  order of Area objects to insert it
//post: true if the UnderArea is inserted else false
{
unsigned int x=Object1->getNumberOfArea();
if (x>=n)
{
	return Object1->insertAreaVector(n,area);
}
return Object2->insertAreaVector(n-x,area);
}

//common Methodes:

Conc* Conc::copy()
//copy this object(means all, even the objects in it)
//post: a pointer to the copy of this object
{return (new Conc(*this));}

PicturObject* Conc::copy(unsigned int n)
//copy the part object(means all, even the objects in it) wich has the value
//n in the order of part objects
//pre: the value n of the object to copy in the order of objects
//post: a pointer to the copy of the object
{
unsigned int x=Object1->getNumberOfObjectPoints();
if (x>n)
{
	return Object1->copy(n);
}
if (x+1==n)
{
	return Object1->copy();
}
if (x+2==n)
{
	return Object2->copy();
}
return Object2->copy(n);
}

PicturObject* Conc::copyElement(unsigned int n)
//copy the element(not the objects in it) wich has the value
//n in the order of objects
//pre: the value n of the element to copy in the order of objects
//post: a pointer to the copy of the element
{
unsigned int x=Object1->getNumberOfObjects();
if (x>=n)
{
	return Object1->copyElement(n);
}
if (x+1==n)
{
	return (new Conc());
}
return Object2->copyElement(n);
}

void Conc::operator=(const GraphicObject* obj)
//copy the given object obj(means all, even the objects in it)
//pre: the object obj to copy
//post: this object with the values of the given object obj
{
if ((obj->classnameOf())=="Conc")
{	
	deleteObject();
	Object1=((static_cast<const Conc*>(obj))->getNext(true))->copy();
	Object2=((static_cast<const Conc*>(obj))->getNext(false))->copy();
}}

bool Conc::equalValue(const GraphicObject* obj) const
//returns if this object and the given object obj are equal
//(have the same values and objects)
//pre: the other object obj to test
//post: true if this and obj are equal
{
if ((obj->classnameOf())=="Conc")
{
	return ((Object1->equalValue((static_cast<const Conc*>(obj))->getNext(true))) &&
		(Object2->equalValue((static_cast<const Conc*>(obj))->getNext(false))));
}
return false;
}

std::string Conc::classnameOf() const
//returns the classname of this object as a string
//post: the classname of this object as a string
{
return  "Conc";
}

bool Conc::store(unsigned int& n,std::stringstream& stream) const
//store the object to the stream, with the syntax from the docu
//pre: the number for the variables to cont from
//post: the string for this object in the output stream
{
stream<<"conc(";
if (Object1 && Object2)
{
	Object1->store(n,stream);
	stream<<",";
	Object2->store(n,stream);
	stream<<")";
}
return true;
}

bool Conc::restore(std::stringstream& in,std::list<double*>& varl)
//restore the object from the stream in, wich is ther given with the
//syntax from the docu, varl is a list with the variables jet defined
//!this object must be created and his syntax(e.g "fkt(" or "p(") deleted
//from the stream
//pre: the input stream to read from and the variablen list of variables
//     jet defined(ever of this is set to his number (eg. to 3 if his 
//     syntax is "x3"))
//post: the object like in the stream
{
char c;
bool b=true;//true if the restoring is working
//Object1
Object1=restoreElementTyp(in);
if ((Object1->classnameOf()=="Function")||(Object1->classnameOf()=="Area")
	||(Object1->classnameOf()=="Conc")||(Object1->classnameOf()=="Point"))
	{b=b&&Object1->restore(in,varl);}
in>>c;//read the ','
Object2=restoreElementTyp(in);
if ((Object2->classnameOf()=="Function")||(Object2->classnameOf()=="Area")
	||(Object2->classnameOf()=="Conc")||(Object2->classnameOf()=="Point"))
	{b=b&&Object2->restore(in,varl);}
in>>c;//read the ')'
return b;
}

void Conc::makeMatrix(PicturMatrix *pm) const
//make the PicturMatrix of this object
//post: the PicturMatrix of this object
{
Object2->makeMatrix(pm);//Object1 overlap Object2
Object1->makeMatrix(pm);
}

void Conc::makeMatrixOfObject(PicturMatrix *pm,unsigned int n) const
//make the PicturMatrix of object wich has the value n in the order 
//of part objects
//pre: the value of the object, to make the PicturMatrix from, in the 
//  order of part objects
//post: the PicturMatrix of the object
{
unsigned int x=Object1->getNumberOfObjectPoints();
if (x>n)
{
	Object1->makeMatrixOfObject(pm,n);
	return;
}
if (x+1==n)
{
	Object1->makeMatrix(pm);
	return;
}
if (x+2==n)
{
	Object2->makeMatrix(pm);
}
Object2->makeMatrixOfObject(pm,n);
}

void Conc::makeMatrixOfPoint(PicturMatrix *pm,unsigned int n) const
//make the PicturMatrix of object wich has the value n in the order 
//of point part objects
//pre: the value of the object, to make the PicturMatrix from, in the 
//  order of point part objects
//post: the PicturMatrix of the object
{
makeMatrixOfObject(pm,pointPartObjectToPartObject(n));
}

bool Conc::hasUnderAllObjects() const
//checks if this object contain for all his contained objects real 
//objects(ther are no null pointer for a contained object) 
//post: true if all contained objects are not null else false
{
return (!((Object1==0)||(Object2==0)));
}
