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

  This is implementation of the class of all Function objects

*/

#include <math.h>

#include "Function.h"
//---------------------------------------------------------------------------

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

Function::Function(PicturObject* uob,list<Vector*> vl):ListObject(uob, vl)
//special constructor
//constructs a Function 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 
{}

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

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

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


//other get Functions:

unsigned long Function::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 Function::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
{
if ((UnderObject->getNumberOfFunctions()+1)==n)
{
	VectorList->insert(VectorList->end(),fkt);
	return true;
}
return UnderObject->insertFunctionVector(n,fkt);
}

bool Function::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
{
return UnderObject->insertAreaVector(n,area);
}


//common Methodes:

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

PicturObject* Function::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 Function(0,tmpvl));
}

void Function::operator=(const GraphicObject* obj)
//copy the given object obj(means all, even the objects in it) to this object
//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())=="Function")
{
	if (!VectorList->empty())//if the VectorList is not empty
	{
		for (list<Vector*>::iterator itr=VectorList->begin();itr!=VectorList->end();itr++)
		{
			delete (*itr);
		}
		delete VectorList;
		VectorList->clear();
	}

	list<Vector*>* tmpvl=(static_cast<const Function*>(obj))->getVectorList();
	Vector* tmpvec;
	VectorList=new list<Vector*>;
	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 Function*>(obj))->getDefinedVariableFrom((static_cast<const Function*>(obj))->getNumberOfMovePoints()),DefinedVariable);//set all defined variables to the new DefinedVariable
			VectorList->insert(VectorList->end(),tmpvec);
		}
	}
}
}

bool Function::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())=="Function")
{
	list<Vector*>* tmpvl=(static_cast<const Function*>(obj))->getVectorList();
	if (((VectorList->empty())==(tmpvl->empty()))&&(((static_cast<const Function*>(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 Function::classnameOf() const
//returns the classname of this object as a string
//post: the classname of this object as a string
{return "Function";}

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

void Function::makeMatrix(PicturMatrix *pm) const
//make the PicturMatrix of this object
//post: the PicturMatrix of this object
{
double *a,*b,*c;//a*b^c
double sum=0;
list<Vector*>* tmvl=const_cast<list<Vector*>* >(VectorList);
if (!(tmvl->empty()))
{
	for (list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
	{
		a=((*i)->getComponentPointer(1));
		b=((*i)->getComponentPointer(2));
		c=((*i)->getComponentPointer(3));
		sum=sum+(*a)*exp((*c)*log(*b));
	}
}
(*DefinedVariable)=sum;
UnderObject->makeMatrix(pm);
}

void Function::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
{
double *a,*b,*c;//a*b^c
double sum=0;
list<Vector*>* tmvl=const_cast<list<Vector*>* >(VectorList);
if (!(tmvl->empty()))
{
	for (list<Vector*>::iterator i=tmvl->begin();i!=tmvl->end();i++)
	{
		a=((*i)->getComponentPointer(1));
		b=((*i)->getComponentPointer(2));
		c=((*i)->getComponentPointer(3));
		sum=sum+(*a)*exp((*c)*log(*b));
	}
}
(*DefinedVariable)=sum;
UnderObject->makeMatrixOfObject(pm,n);
}
