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

  This is implementation of the class of all Area 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 "Area.h"
//---------------------------------------------------------------------------

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

Area::Area(PicturObject* uob,std::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; because all is done of ListObject destructor


//Methodes to get greatness 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 Methodes:

unsigned long Area::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 long tmp=1;
long lowb,ub;
if (!VectorList->empty())//if the VectorList is not empty
{
	std::list<Vector*>* tmvl=const_cast<std::list<Vector*>* >(VectorList);
	for (std::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) //go from the smaler to the bigger numbers
		{
			for (long a=lowb;a<=ub;a++)//sum over the time need of the UnderObject for the different values
			{
				(*DefinedVariable)=((double)a);
				tmp=tmp+UnderObject->getTimeNeed(max);
				if (tmp>max) {return tmp;}//just evalue till the max value is reached
			}
		}else{
			for (long a=ub;a<=lowb;a++)//sum over the time need of the UnderObject for the different values
			{
				(*DefinedVariable)=((double)a);
				tmp=tmp+UnderObject->getTimeNeed(max);
				if (tmp>max) {return tmp;}//just evalue till the max value is reached
			}
		}
	}
}
return tmp;
}


//methodes wich changes the object:

bool Area::insertFunctionVector(unsigned int n,UnderFunction* fkt)
//insert the UnderFunction vector fkt in the UnderFunction vector list 
//of the 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 the 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)//if this is the rigth Area objekt
{
	VectorList->insert(VectorList->end(),area);//insert the vector
	return true;
}
return UnderObject->insertAreaVector(n,area);//else try insert it in the UnderObject
}


//common methodes:

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

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, instead makes a new
//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->getNumberOfObjects())>=n)//if this is the wrong element
	{return UnderObject->copyElement(n);}//it should be in the Underobject
//else copy the VectorList
std::list<Vector*> tmpvl;
if (!VectorList->empty())//if the VectorList is not empty
{
	for (std::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, instead makes a new
//pre: the object obj to copy
//post: this object with the values of the given object obj
{
if ((obj->classnameOf())=="Area")//just copy if the other object is a Area object too
{
	//copy the VectorList
	if (!VectorList->empty())//if the VectorList is not empty
	{	//delete old VectorList
		for (std::list<Vector*>::iterator itr=VectorList->begin();itr!=VectorList->end();itr++)
		{
			delete (*itr);
		}
		VectorList->clear();
	}
	//insert the VectorList elements of the other object
	Vector* tmpvec;
	std::list<Vector*>* tmpvl=(static_cast<const Area*>(obj))->getVectorList();
	if (!tmpvl->empty())//if the VectorList is not empty
	{
		for (std::list<Vector*>::iterator i=tmpvl->begin();i!=tmpvl->end();i++)
		{
			tmpvec=(*i)->copy();
			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 equal under objects)
//pre: the other object obj to test
//post: true if this and obj are equal
{
if ((obj->classnameOf())=="Area")
{
	std::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
		{
			std::list<Vector*>* tmvl=const_cast<std::list<Vector*>* >(VectorList);
			//for every element in the VectorList of this object there must be
			//a element in the VectorList of the other object
			for (std::list<Vector*>::iterator i=tmpvl->begin();i!=tmpvl->end();i++)
			{
				bool b=false;
				for (std::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 every element in the VectorList of the other object there must be
			//a element in the VectorList of this object
			for (std::list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
			{
				bool b=false;
				for (std::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;//the object are equal
	}
}
return false;
}

std::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 count from
//post: the string for this object in the output stream
{
stream<<"for(";//just store the name of the object
return ListObject::store(n,stream);//the rest is done by the ListObject store method
}

void Area::makeMatrix(PicturMatrix* pm) const
//make the PicturMatrix of this object
//pre: the PicturMatrix to store the values to
//post: the PicturMatrix of this object
{
long lowb,ub;
std::list<Vector*>* tmvl=const_cast<std::list<Vector*>* >(VectorList);
if (!(tmvl->empty()))
{
	for (std::list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
	{//for all elements in the VectorList do
		lowb=(long)(*((*i)->getComponentPointer(2)));//lower bound
		ub=(long)(*((*i)->getComponentPointer(1)));//upper bound
		if (lowb<ub)  //go from the smaler to the bigger numb
  		{
  			for (long a=lowb;a<=ub;a++)
  			{//evalue the PicturMatrix of the UnderObject for all values and overlap them
  				(*DefinedVariable)=((double)a);
  				UnderObject->makeMatrix(pm);
  			}
  		}else{
  			for (long a=ub;a<=lowb;a++)
  			{//evalue the PicturMatrix of the UnderObject for all values and overlap them
  				(*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 objectsand the PicturMatrix to store the values to
//post: the PicturMatrix of the object
{//the different thing to the makeMatrix() methode is done by the conc objects
long lowb,ub;
std::list<Vector*>* tmvl=const_cast<std::list<Vector*>* >(VectorList);
if (!(tmvl->empty()))
{
	for (std::list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
	{//for all elements in the VectorList do
		lowb=(long)(*((*i)->getComponentPointer(2)));//under bound
		ub=(long)(*((*i)->getComponentPointer(1)));//upper bound
		if (lowb<ub) //go from the smaler to the bigger numbers
		{
			for (long a=lowb;a<=ub;a++)
			{//evalue the PicturMatrix of the UnderObject for all values and overlap them
				(*DefinedVariable)=((double)a);
				UnderObject->makeMatrixOfObject(pm,n);
			}
		}else{
			for (long a=ub;a<=lowb;a++)
			{//evalue the PicturMatrix of the UnderObject for all values and overlap them
				(*DefinedVariable)=((double)a);
				UnderObject->makeMatrixOfObject(pm,n);
			}
		}
	}
}
}
