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

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

//constructors:
Point::Point():PicturObject(),PositionV(Position()),ColorV(Color())
//standart constructor
//constructs a Point object with the standart constructor of for Color
//and Position
{}

Point::Point(Position pos,Color col):PicturObject(),PositionV(pos),ColorV(col)
//special constructor
//constructs a Point object with the given Color col as the Color object
//and the given Position object pos as the Positions Object of this new object
//pre: the the Color col and the Position pos for the new Point object
{}

Point::Point(const Point& poi):PicturObject(),PositionV(*((const_cast<Point*>(&poi))->getPosition()))
	,ColorV(*((const_cast<Point*>(&poi))->getColor()))
//copy constructor
//constructs a copy of the given Point object
//attention: copy the objects from the given Point object
//pre: the Point object poi to copy
{}


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

//Methodes to get greatnes of order:
unsigned int Point::getNumberOfValue() const
//evaluate the number of values in this object
//post: Numbers of values in this object
{return ((ColorV.getNumberOfValue())+(PositionV.getNumberOfValue()));}

unsigned int Point::getNumberOfVariable() const
//evaluate the number of variables in this object
//post: Numbers of Variables in this object
{return ((ColorV.getNumberOfVariable())+(PositionV.getNumberOfVariable()));}

unsigned int Point::getNumberOfListVectors() const
//evaluate the number of List Vectors in this object
//post: Numbers of List Vectors in this object
{return 0;}

unsigned int Point::getNumberOfMovePoints() const
//evaluate the number of Move Points in this object
//post: Numbers of Move Points in this object
{return 0;}

unsigned int Point::getNumberOfObjects() const
//evaluate the number of Point in this object
//post: Numbers of Point in this object
{return 1;}

unsigned int Point::getNumberOfConc() const
//evaluate the number of Point Objects in this object
//post: Numbers of Point Objects in this object
{return 0;}

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

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

unsigned int Point::getNumberOfFunctions() const
//evaluate the number of Function in this object
//post: Numbers of Function in this object
{return 0;}

unsigned int Point::getNumberOfArea() const
//evaluate the number of area Objects in this object
//post: Numbers of area Objects in this object
{return 0;}

//other get Functions:

int Point::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 = PositionV.getNumberOfValue();//the values in the first vector
if (x>=n)//if n is smaler the value is in the first vector PositionV
{	return PositionV.getValue(n);}
return ColorV.getValue(n-x);//else in the secound Vector ColorV
}

double* Point::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 = PositionV.getNumberOfVariable();//the variable in the first vector
if (x>=n)//if n is smaler the variable is in the first vector PositionV
{	return PositionV.getVariable(n);}
return ColorV.getVariable(n-x);//else in the secound Vector ColorV
}

unsigned long Point::getGreatness() const
//to get a idea how great the object is
//post: a number for how great the object is
{return ((PositionV.getGreatness())+(ColorV.getGreatness())+1);}

unsigned long Point::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
{return ((PositionV.getTimeNeed())+(ColorV.getTimeNeed())+1);}

bool Point::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 ((PositionV.isUsedVariable(var))||(ColorV.isUsedVariable(var)));}

PicturObject* Point::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
{return 0;} //error: no Object under this; should not hapend

Vector* Point::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
{return 0;} //error: no Object under this; should not hapend

PicturObject* Point::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 Point 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
{return 0;} //error: no Object under this; should not hapend

unsigned int Point::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
{return 1;}

unsigned int Point::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
{return n-2;}//if n-2 is <0 no problem the next conc add 2 or error
	//ther is no conc and so no part object

unsigned int Point::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
{return 0;} //error: no Object under this; should not hapend

bool Point::isDeletableElement() const
//checks if the Element(this) is deletable(Points and Point 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 Point::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 ((PositionV.isUsedVariable(var))||(ColorV.isUsedVariable(var)));}

double* Point::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
{return 0;} //error: no Object under this or variables defined; should not
	//hapend

std::list<double*> Point::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
{
std::list<double*>* newl=new std::list<double*>;
return (*newl);
}

std::list<double*> Point::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
{std::list<double*>* newl=new std::list<double*>;
return (*newl);}

std::list<double*> Point::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
{std::list<double*>* newl=new std::list<double*>;
return (*newl);}

Color* Point::getColor()
//to get the color of this point
//post: the Color of this point
{return &ColorV;}

Position* Point::getPosition()
//to get the Position of this point
//post: the Position of this point
{return &PositionV;}


//Methodes wich changes the Object:

bool Point::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 = PositionV.getNumberOfValue();//the values in the first vector
if (x>=n)//if n is smaler the value to set is in the first vector PositionV
{	return PositionV.setValueToValue(n,val);}
return ColorV.setValueToValue(n-x,val);//else in the secound Vector ColorV
}

bool Point::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 = PositionV.getNumberOfValue();//the values in the first vector
if (x>=n)//if n is smaler the value to set is in the first vector PositionV
{	return PositionV.setValueToVariable(n,var);}
return ColorV.setValueToVariable(n-x,var);//else in the secound Vector ColorV
}

bool Point::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 = PositionV.getNumberOfVariable();//the variables in the first vector
if (x>=n)//if n is smaler the variable to set is in the first vector PositionV
{	return PositionV.setVariableToVariable(n,var);}
return ColorV.setVariableToVariable(n-x,var);//else in the secound Vector ColorV
}

unsigned int Point::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 PositionV.setVariableToVariable(var1,var2)+ColorV.setVariableToVariable(var1,var2);
}


bool Point::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 = PositionV.getNumberOfVariable();//the variables in the first vector
if (x>=n)//if n is smaler the variable to set is in the first vector PositionV
{	return PositionV.setVariableToValue(n,val);}
return ColorV.setVariableToValue(n-x,val);//else in the secound Vector ColorV
}

unsigned int Point::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 PositionV.setVariableToValue(var1,val)+ColorV.setVariableToValue(var1,val);
}

bool Point::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 = PositionV.getNumberOfValue();//the values in the first vector
if (x>=n)//if n is smaler the value change is in the first vector PositionV
{	return PositionV.changeValueAbout(n,dist);}
return ColorV.changeValueAbout(n-x,dist);//else in the secound Vector ColorV
}

bool Point::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 Point
//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
{return false;}//error: no Object under this to insert; should not
	//hapend

bool Point::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
{return false;}//error: no Object under this to overwrite; should not
	//hapend

bool Point::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
{return false;}//error: no Object under this to remove; should not hapend

bool Point::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
{return false;}//error: no element under this to remove; should not hapend

bool Point::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
{return false;}//error: no list vectors in or under to remove; should not hapend

PicturObject* Point::cutElement(unsigned int n,bool b)
//returns 0, because no object to cut
//pre: the value n in the order of move points of the element to cut
//post: 0
{return 0;}//error: no elements under this to cut; should not hapend

void Point::deleteObject()
//deletes the object(the element and all objects in it, uses the 
//destructors)
{}

bool Point::flipObjects(unsigned int n)
//flips the objects of the Point object with the value n in the order
//of flip points(=Point objects) (oject1:=object2 and object2:=object1)
//pre: the value n in the order of flip point of the Point object
//  wich contained objects shold be fliped
//post true if the objects are fliped else false
{return false;}//error: no conc objects under this wher to flip; should not hapend

bool Point::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 Point::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 Point pointer
//  for the object
//post: true if the object is moved (even if just not howfar steps)
//  else false
{
return false;
}

bool Point::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;}//error: no objects under this wher to insert; should not hapend

bool Point::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 false;}//error: no function vectors in or under this wher to insert
	//; should not hapend

bool Point::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 false;}//error: no area vectors in or under this wher to insert
	//; should not hapend

void Point::setColor(Color col)
//to set the color of this point
//pret: the new Color col for this point
{ColorV=col;}

void Point::setPosition(Position pos)
//to set the Position of this point
//pre: the Position pos for this point
{PositionV=pos;}


//common Methodes:

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

PicturObject* Point::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
{return 0;}//error: no part object in or under this to copy
	//; should not hapend

PicturObject* Point::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
{return (new Point(*this));}

void Point::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())=="Point")
{
	Point* objt=(const_cast<Point*>(static_cast<const Point*>(obj)));
	PositionV=(*(objt->getPosition())->copy());
	ColorV=(*(objt->getColor())->copy());
}}

bool Point::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())=="Point")
{
	Point* objt=(const_cast<Point*>(static_cast<const Point*>(obj)));
	return ((objt->getPosition())->equalValue(&PositionV) &&
		(objt->getColor())->equalValue(&ColorV));
}
return false;
}

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

bool Point::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<<"p(";
PositionV.store(n,stream);
stream<<",";
ColorV.store(n,stream);
stream<<")";
return true;
}

bool Point::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
//next is position
b=(PositionV.restore(in,varl))&&b;
in>>c;//read','
b=(ColorV.restore(in,varl))&&b;
in>>c;//read')'
return b;
}

void Point::makeMatrix(PicturMatrix *pm) const
//make the PicturMatrix of this object
//post: the PicturMatrix of this object
{
unsigned long pos[4]={0,0,0,0};
for(unsigned int i=0;i<PositionV.getNumberOfComponents();i++)
	{pos[i]=(unsigned long)(*(PositionV.getComponentPointer(i+1)));}
pm->setColorOnPosition(pos,ColorV);
}

void Point::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
{makeMatrix(pm);}

void Point::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 Point::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 true;}
