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

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

//yust for debugging
#include <iostream>
using std::cout;
using std::endl;
using std::flush;

   //Construktors:
Vector::Vector():NumberOfComponents(0)
//standart constructor
//makes a blank object
{}

Vector::Vector(const Vector& vec)
//copy constructor
//makes a vector object with the same values as the given vector vec
//pre: the vector vec to copy
{	
NumberOfComponents=vec.getNumberOfComponents();
Component= new TComponent[NumberOfComponents];
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	Component[i].IsValue=vec.isComponentValue(i+1);
	if (Component[i].IsValue)
		{Component[i].Value=new double(*(vec.getComponentPointer(i+1)));}
	else{
		Component[i].Value=vec.getComponentPointer(i+1);//if the component is a variable it pointed to the same variable as the original vector vec
	}
}
}

Vector::Vector(unsigned int noc):NumberOfComponents(noc)
//parameter constructor
//makes a vector object with noc components all values set to 0
//pre: the number of components to produce
{	
Component= new TComponent[NumberOfComponents];
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	Component[i].Value=new double(0.0);
	Component[i].IsValue=true;
}
}

Vector::~Vector()
//destructor
//deletes the components
{
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	//yust delte the value pointer, for the variables other objects are responsible
	if (Component[i].IsValue) {delete Component[i].Value;}
}
delete Component;
}



int Vector::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 or 0 if not exsists
{
unsigned int nov=0;
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (Component[i].IsValue) nov++;
	if (nov==n) {return (int)(*(Component[i].Value));}
}
return 0;
}

double* Vector::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 or 0 if not exsists
{
unsigned int nov=0;
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (!Component[i].IsValue) nov++;
	if (nov==n) return Component[i].Value;
}
return 0;
}

unsigned long Vector::getGreatness() const
//to get a idea how great the object is
//post: a number for how great the object is, her number of components
{
	return NumberOfComponents;
}

bool Vector::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 nov=0;
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (Component[i].IsValue) nov++;
	if ((nov==n)&&(Component[i].IsValue))
	{
		(*(Component[i].Value))=double(val);
		return true;
	}
}
return false;
}

bool Vector::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 nov=0;
if (n!=0) //if the value exsists
	for (unsigned int i=0;i<NumberOfComponents;i++)
	{
		if (Component[i].IsValue) nov++;
		if ((nov==n)&&(Component[i].IsValue))
		{
			//delete the value pointer
			delete Component[i].Value;
			Component[i].Value=var;
			Component[i].IsValue=false;
			return true;
		}
	}
return false;
}

bool Vector::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 nov=0;
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (!Component[i].IsValue) nov++;
	if ((nov==n)&&(!Component[i].IsValue))
	{
		//don't delete the variable pointer
		Component[i].Value=var;
		return true;
	}
}
return false;
}

unsigned int Vector::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
{
unsigned int nov=0;
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (Component[i].Value==var1)//if component is the to set variable
	{
		Component[i].Value=var2;
		nov=nov+1;
	}
}
return nov;
}


bool Vector::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 nov=0;
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (!Component[i].IsValue) nov++;
	if ((nov==n)&&(!Component[i].IsValue))
	{
		//don't delete the variable pointer
		Component[i].Value=new double(val);
		Component[i].IsValue=true;
		return true;
	}
}
return false;
}

unsigned int Vector::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
{
unsigned int nov=0;
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (Component[i].Value==var1)//if component is the to set variable
	{
		Component[i].Value=new double(val);
		Component[i].IsValue=true;
		nov=nov+1;
	}
}
return nov;
}

bool Vector::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 nov=0;
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (Component[i].IsValue) nov++;
	if ((nov==n)&&(Component[i].IsValue))
	{
		(*(Component[i].Value))=(*(Component[i].Value))+dist;
		return true;
	}
}
return false;
}

bool Vector::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
{
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (Component[i].Value==var) return true;
}
return false;
}

bool Vector::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()==classnameOf())
{
	for (unsigned int i=0;i<NumberOfComponents;i++)
	{
	//if the components are not everywhere the same return false
		if (!(isComponentValue(i+1)==(((Vector*)obj)->isComponentValue(i+1))))
			{return false;}
		if ((isComponentValue(i+1))&&(!((*getComponentPointer(i+1))==(*(((Vector*)obj)->getComponentPointer(i+1))))))
			{return false;}
		if ((!(isComponentValue(i+1)))&&(!((getComponentPointer(i+1))==((((Vector*)obj)->getComponentPointer(i+1))))))
			{return false;}
	}
	return true;
}
return false;
}

void Vector::operator=(const GraphicObject* obj)
//copy the given object obj
//pre: the pointer to the object obj to copy
//post: this object with the values of the given object obj
{
//delete old values
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	//yust delte the value pointer, for the variables other objects are responsible
	if (Component[i].IsValue) {delete Component[i].Value;}
}
delete Component;
//set new values
NumberOfComponents=((Vector*)obj)->getNumberOfComponents();
Component= new TComponent[NumberOfComponents];
for (unsigned int i=0;i<NumberOfComponents;i++)
{
	Component[i].IsValue=((Vector*)obj)->isComponentValue(i+1);
	if (Component[i].IsValue)
		{Component[i].Value=new double(*(((Vector*)obj)->getComponentPointer(i+1)));}
	else{
		Component[i].Value=((Vector*)obj)->getComponentPointer(i+1);//if the component is a variable it pointed to the same variable as the original vector vec
	}
}
}

bool Vector::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 (unsigned int i=0;i<NumberOfComponents;i++)
{
	if (i) stream<<",";
	if (Component[i].IsValue)
	{
		stream<<(int)(*Component[i].Value);
	}else{
		stream<<'x';
		if (Component[i].Value)
			{stream<<(unsigned int)(*Component[i].Value);}
	}
}
stream<<')';
return true;
}

bool Vector::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
{
//restore values
char c;
unsigned int comp=0;//the aktuel component
long l=0;
bool neg=false;
in>>c;
if (c=='(')
{
	while (!(c==')'))
	{
		comp++;
		in>>c;
		l=0;
		if (c=='x')//if a variable follow
		{
			in>>c;
			while (!((c==',')||(c==')')))//read variable index
			{
				l=l*10+charToInt(c);
				in>>c;
			}
			for (std::list<double*>::iterator itr=varl.begin();itr!=varl.end();itr++)
				//search for the variable with this value/index
			{
				if (l==(long)(**itr))//if it is the rigth variable
				{
					setComponentPointer(comp,(*itr));//insert it
					setIsComponentValue(comp,false);//the component is no value
					break;
				}
			}
		}else{//if no variable follow
			if (c=='-') {neg=true;in>>c;}
			while (!((c==',')||(c==')')))//read value
			{
				l=l*10+charToInt(c);
				in>>c;
			}
			if (neg)
			{
				l=-l;
				neg=false;
			}
			setComponentPointer(comp,(new double(l)));//insert it
			setIsComponentValue(comp,true);//the component is no value
		}
	}
	//NumberOfComponents should be equal comp
	if (comp) {NumberOfComponents=comp;}
	return true;
}
return false;
}




