/*
QtWagon: a project about 3D objects.
Science and technology promotion license applied. Third party license automatically cascaded.
Zhikai Wang/ www.heteroclinic.net 2013
You can do anything with this file or any file(s) published as part QtWagon project, given this header is kept.
*/
#ifndef __MATHPOINT
#define __MATHPOINT
#include <iostream>
#include <iomanip>
#include <sstream>
#include "mathBasics.h"
//1. ? can friend operator inherited
//2. ?! point - point return vector. It should be in the space of vector not point
template <class T>
class mathPoint {
protected:
	T data[3];
private:

public:

	//void setData( T* ndp) {
	//	data[0] = ndata[0]; 	data[1] = ndata[1]; 	data[2] = ndata[2];
	//}
	mathPoint(const T ndata[]) {
		data[0] = ndata[0]; 	data[1] = ndata[1]; 	data[2] = ndata[2];
	}
	mathPoint(T nx = 0.0, T ny = 0.0, T nz= 0.0) {
		data[0] = nx; 	data[1] = ny; 	data[2] = nz;
	}
	//// copy constructor
	mathPoint(const mathPoint & nmp) {
		data[0] = nmp.getx(); 	data[1] = nmp.gety(); 	data[2] = nmp.getz();
	}
	// assignment operator
	mathPoint & operator=(const mathPoint& nmp) {
		if (this == &nmp) return *this;  // time-saving self-test
		data[0] = nmp.getx(); 	data[1] = nmp.gety(); 	data[2] = nmp.getz();
		return *this;                    // for daisy-chaining
	}
	// equality test operator
	bool operator==(const mathPoint& nmp) {
		return (getx()==nmp.getx())&&(gety()==nmp.gety())&& (getz()==nmp.getz());
	}
	virtual ~ mathPoint() {
	}
	template <class U> 
	friend std::ostream & operator << (std::ostream & os,const mathPoint<U> & mp);

	template <class U> 
	friend std::istream & operator >> (std::istream & is, mathPoint<U> & mp);


	T getx () const
	{
		return data[0];
	}
	T gety () const {
		return data[1];
	}
	T getz () const {
		return data[2];
	}
	T * getDataPointer() const{
		return (T *)data;
	}
};
template <class U> 
std::ostream & operator << (std::ostream & os,const mathPoint<U> & mp){
	// you must add the std:: otherwise QT will complain.
	os << std::setw(OUTPUTWIDTH)<<std::fixed<<std::scientific  <<std::setprecision(FLOATING_PRECISION)<< mp.getx() << std::setw(OUTPUTWIDTH)<<std::fixed<<std::scientific
		<<std::setprecision(FLOATING_PRECISION) <<mp.gety()<< std::setw(OUTPUTWIDTH)<<std::fixed<<std::scientific<<std::setprecision(FLOATING_PRECISION)<< mp.getz() <<std::endl;
	return os;
}
template <class U> 
std::istream & operator >> (std::istream & is, mathPoint<U> & mp){
		std::stringstream ss;
		std::string line;
		std::getline(is,line);
		ss.str(line);
		//U d1 = 0.0, d2 = 0.0, d3 = 0.0;
		ss>>mp.data[0]>>mp.data[1]>>mp.data[2];
		return is;
}
#endif