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

  This is implementation of the class of all Area objects

*/

#include "Area.h"
//---------------------------------------------------------------------------

Area::Area():ListObject()
//standart constructor
//constructs a blank Area object
{}

Area::Area(PicturObject* uob,list<Vector*> vl):ListObject(uob, vl)
//special constructor
//constructs a Area object with a new pointer for the defined variable
//the given vector list vl for the VectorList and a UnderObject pointer 
//pointed to the given pointer uob 
{}

Area::Area(const Area& are):ListObject(are)
//copy constructor
//constructs a copy of the given Area are object
//attention: copy the objects from the given Area object 
//pre: the Area object are to copy
{}

Area::~Area()
//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 Area::getNumberOfFunctions() const
//evaluate the number of Function in this object
//post: Numbers of Function in this object
{return UnderObject->getNumberOfFunctions();}

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


//other get Functions:

unsigned long Area::getTimeNeed() 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 long tmp=0;
if (!VectorList->empty())//if the VectorList is not empty
{
	list<Vector*>* tmvl=const_cast<list<Vector*>* >(VectorList);
	for (list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
	{
		tmp=tmp+((*i)->getTimeNeed());
	}
}
return (tmp*(UnderObject->getTimeNeed()))+1;
}


//Methodes wich changes the Object:

bool Area::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
{return UnderObject->insertFunctionVector(n,fkt);}

bool Area::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
{
if ((UnderObject->getNumberOfArea()+1)==n)
{
	VectorList->insert(VectorList->end(),area);
	return true;
}
return UnderObject->insertAreaVector(n,area);
}


//common Methodes:

Area* Area::copy()
//copy this object(means all, even the objects in it)
//post: a pointer to the copy of this object
{
Area* tmpa=new Area(*this);
tmpa->setVariableToVariable(DefinedVariable,tmpa->getDefinedVariableFrom(tmpa->getNumberOfMovePoints()));
return tmpa;
}

PicturObject* Area::copyElement(unsigned int n)
//copy the element(not the objects in it) wich has the value
//n in the order of objects
//don't copy the defined variable
//pre: the value n of the element to copy in the order of objects
//post: a pointer to the copy of the element
{
if ((UnderObject->getNumberOfObjectPoints())>n)
{
	return UnderObject->copyElement(n);
}
list<Vector*> tmpvl;
if (!VectorList->empty())//if the VectorList is not empty
{
	for (list<Vector*>::iterator i=VectorList->begin();i!=VectorList->end();i++)
	{
		tmpvl.insert(tmpvl.end(),(*i)->copy());
	}
}
return (new Area(0,tmpvl));
}

void Area::operator=(const GraphicObject* obj)
//copy the given object obj(means all, even the objects in it)
//don't copy the defined variable
//pre: the object obj to copy
//post: this object with the values of the given object obj
{
if ((obj->classnameOf())=="Area")
{
	if (!VectorList->empty())//if the VectorList is not empty
	{
		for (list<Vector*>::iterator itr=VectorList->begin();itr!=VectorList->end();itr++)
		{
			delete (*itr);
		}
		VectorList->clear();
	}
	Vector* tmpvec;
	list<Vector*>* tmpvl=(static_cast<const Area*>(obj))->getVectorList();
	if (!tmpvl->empty())//if the VectorList is not empty
	{
		for (list<Vector*>::iterator i=tmpvl->begin();i!=tmpvl->end();i++)
		{
			tmpvec=(*i)->copy();
			tmpvec->setVariableToVariable((static_cast<const Area*>(obj))->getDefinedVariableFrom((static_cast<const Area*>(obj))->getNumberOfMovePoints()),DefinedVariable);//set all defined variables to the new DefinedVariable
			VectorList->insert(VectorList->end(),tmpvec);
		}
	}
}
}

bool Area::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())=="Area")
{
	list<Vector*>* tmpvl=(static_cast<const Area*>(obj))->getVectorList();
	if (((VectorList->empty())==(tmpvl->empty()))&&(((static_cast<const Area*>(obj))->getNext())->equalValue(UnderObject)))
	{
		if (!tmpvl->empty())//if the VectorList is not empty
		{
			
			list<Vector*>* tmvl=const_cast<list<Vector*>* >(VectorList);
			for (list<Vector*>::iterator i=tmpvl->begin();i!=tmpvl->end();i++)
			{
				bool b=false;
				for (list<Vector*>::iterator j=tmvl->begin();j!=tmvl->end();j++)
				{
					b=b||(*i)->equalValue(*j);//if the same Vector is in the both vector list
				}
				if (!b) return false;//if the vector form tmpvl is not found in VectorList
			}
			for (list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
			{
				bool b=false;
				for (list<Vector*>::iterator j=tmpvl->begin();j!=tmpvl->end();j++)
				{
					b=b||(*i)->equalValue(*j);//if the same Vector is in the both vector list
				}
				if (!b) return false;//if the vector form VectorList is not found in tmpvl
			}
		}
		return true;
	}
}
return false;
}

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

bool Area::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<<"for(";
return ListObject::store(n,stream);
}

void Area::makeMatrix(PicturMatrix* pm) const
//make the PicturMatrix of this object
//post: the PicturMatrix of this object
{
long lowb,ub;
list<Vector*>* tmvl=const_cast<list<Vector*>* >(VectorList);
if (!(tmvl->empty()))
{
	for (list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
	{
  		lowb=(long)(*((*i)->getComponentPointer(2)));//under bound
  		ub=(long)(*((*i)->getComponentPointer(1)));//upper bound
  		if (lowb<ub) //if not change
  		{
  			for (long a=lowb;a<=ub;a++)
  			{
  				(*DefinedVariable)=((double)a);
  				UnderObject->makeMatrix(pm);
  			}
  		}else{
  			for (long a=ub;a<=lowb;a++)
  			{
  				(*DefinedVariable)=(double)a;
				UnderObject->makeMatrix(pm);
			}
		}
	}
}
}

void Area::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
{
long lowb,ub;
list<Vector*>* tmvl=const_cast<list<Vector*>* >(VectorList);
if (!(tmvl->empty()))
{
	for (list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
	{
		lowb=(long)(*((*i)->getComponentPointer(2)));//under bound
		ub=(long)(*((*i)->getComponentPointer(1)));//upper bound
		if (lowb<ub) //if not change
		{
			for (long a=lowb;a<=ub;a++)
			{
				(*DefinedVariable)=((double)a);
				UnderObject->makeMatrixOfObject(pm,n);
			}
		}else{
			for (long a=lowb;a<=ub;a--)
			{
				(*DefinedVariable)=(double)a;
				UnderObject->makeMatrixOfObject(pm,n);
			}
		}
	}
}
}
