/* Tuple.h
 *
 * Interface definition for the Tuple class, which is a 3D vector with standard
 * vector operations.
 */

#ifndef TUPLE_H_INCLUDED
#define TUPLE_H_INCLUDED 1

#include <iostream>

class Tuple
{
private:
	// Member variables
	double x_;
	double y_;
	double z_;

public:
	// Constructors/Destructor
	Tuple();
	Tuple(const double x, const double y, const double z);
	Tuple(const Tuple& toCopy);
	virtual ~Tuple();

	// Operators
	Tuple&		operator =	(const Tuple& toCopy);
	const bool	operator ==	(const Tuple& toCompare) const;
	const bool	operator !=	(const Tuple& toCompare) const;
	const Tuple	operator +	(const Tuple& toAdd) const;
	Tuple&		operator +=	(const Tuple& toAdd);
	const Tuple	operator -	() const;
	const Tuple	operator -	(const Tuple& toSub) const;
	Tuple&		operator -=	(const Tuple& toSub);
	Tuple&		operator *=	(double scaleFactor);		// unary scalar mult
	Tuple&		operator /=	(double scaleFactor);		// unary scalar div
	double&         operator []     (int index);

	// Accessors
	const double&	x() const				{return x_;}
	const double&	y() const				{return y_;}
	const double&	z() const				{return z_;}
	void			setX(const double x)	{x_ = x;}
	void			setY(const double y)	{y_ = y;}
	void			setZ(const double z)	{z_ = z;}

	// Vector Operations
	const double	dot(const Tuple& toDot) const;		// dot product
	const Tuple		cross(const Tuple& toCross) const;	// cross product
	const Tuple		norm() const;						// normalize
	const double	length() const;						// compute length
};

// More Operators
const Tuple		operator *	(const Tuple& toMultiply, const double& scaleFactor);
const Tuple		operator *	(const double& scaleFactor, const Tuple& toMultiply);
const Tuple		operator /	(const Tuple& toDivide, const double& scaleFactor);
std::ostream&	operator <<	(std::ostream &out_file, const Tuple& theTuple);

#endif // TUPLE_H_INCLUDED
