#include "CoordND.h"
#include <iostream>
#include <sstream>
#include <cmath>
#include <string>

using namespace std;

CoordND::CoordND()
{
	dims = 3;
	c = new float[dims];
	for (int i=0; i < dims; i++)
		c[i] = 0.0;
}

CoordND::CoordND (int ndims)
{
	dims = ndims;
	c = new float[dims];
	for (int i=0; i < dims; i++)
		c[i] = 0.0;
}

CoordND::CoordND (const CoordND& nd)
{
	dims = nd.dims;
	c = new float[dims];
	for (int i=0; i < dims; i++)
		c[i] = nd.c[i];
}

CoordND::CoordND (int ndims, float vals[])
{
	dims = ndims;
	c = new float[dims];
	for (int i=0; i < dims; i++)
		c[i] = vals[i];
}

CoordND::~CoordND()
{
	delete[] c;
}

int CoordND::getNumDimensions () const
{
	return dims;
}

void CoordND::setCoordinate (int i, float val)
{
	c[i] = val;
}

float CoordND::getCoordinate (int i) const
{
	return c[i];
}

CoordND CoordND::operator+ (const CoordND& other) const
{
	if (dims == other.dims)
	{
		float *vals = new float[dims];
		for (int i=0; i < dims; i++)
			vals[i] = c[i] + other.c[i];
		return CoordND (dims, vals);
	}
	else
		return CoordND();
}

CoordND CoordND::operator- (const CoordND& other) const
{
	if (dims == other.dims)
	{
		float *vals = new float[dims];
		for (int i=0; i < dims; i++)
			vals[i] = c[i] - other.c[i];
		return CoordND (dims, vals);
	}
	else
		return CoordND();
}

CoordND& CoordND::operator= (const CoordND& other)
{
	dims = other.dims;
	std::copy (other.c, other.c + other.dims, c);
	return *this;
}

ostream& operator<< (ostream &strm, const CoordND &nd)
{
	int dims = nd.getNumDimensions();
        strm << "( ";
	for (int i=0; i < dims-1; i++)
		strm << nd.c[i] << ", ";

	return strm << nd.c[dims-1] << " )";
}

string CoordND::to_string () const
{
        string out = "( ";
	for (int i=0; i < dims-1; i++)
		out += ToString(c[i]) + ", ";

	return out + ToString(c[dims-1]) + " )";
}

//=======================================================================
// This is a helper function, which produces a string for most any class type
//      i.e. for any class that supports operator<< overloading
template<class T>
string CoordND::ToString (const T& val) const
{
	stringstream strm;
	strm << val;
	return strm.str();
}

