
// notes:
// -----------------------------------------------------------
// for fast things look here: http://musicdsp.org/archive.php?classid=5#115
// -----------------------------------------------------------
// the random () calls are based on misconceptions described here:
// http://www.azillionmonkeys.com/qed/random.html
// (Bad advice from C.L.C. FAQ)
// we should correct this -- 
// -----------------------------------------------------------


#ifndef _OF_MATH_H
#define _OF_MATH_H


#include "ofConstants.h"

int 		ofNextPow2 ( int a );
void 		ofSeedRandom();
void 		ofSeedRandom(int val);
float 		ofRandom(float val0, float val1);		// random (x - y)
float 		ofRandomf();							// random (-1 - 1)
float 		ofRandomuf();							// random (0 - 1) 

// Theo added ofPoint - do we put in ofTypes.h??
class ofPoint{

	public:
		ofPoint(float _x = 0, float _y = 0, float _z = 0){
			x = _x;
			y = _y;
			z = _z;
		}

		void set(ofPoint &p){
			x = p.x;
			y = p.y;
			z = p.z;
		}
		
		void set(float _x, float _y){
			x = _x;
			y = _y;
		}
		
		void set(float _x, float _y, float _z){
			x = _x;
			y = _y;
			z = _z;
		}		
				
		bool operator==(const ofPoint &p) { 
			return (x == p.x) && (y == p.y) && (z == p.z);
		}

		bool operator!=(const ofPoint &p) { 
			return (x != p.x) || (y != p.y) || (z != p.z);
		}
    
		ofPoint operator+(const ofPoint &p) const { 
			return ofPoint( x+p.x, y+p.y, z+p.z); 
		} 
    
		ofPoint& operator+=(const ofPoint& p) { 
			x += p.x;
			y += p.y;
			z += p.z;
			return *this; 
		} 
    
		ofPoint operator-(const ofPoint &p) const { 
			return ofPoint( x-p.x, y-p.y, z-p.z ); 
		} 
		
		ofPoint& operator-=(const ofPoint &p) { 
			x -= p.x;
			y -= p.y;
			z -= p.z;
			return *this; 
		} 

		ofPoint operator-() const { 
			return ofPoint( -x, -y, -z ); 
		}
		
		ofPoint operator*(const ofPoint &p) const { 
			return ofPoint( x*p.x, y*p.y, z*p.z ); 
		} 
			
		ofPoint& operator*=(const ofPoint &p) { 
			x *= p.x;
			y *= p.y;
			z *= p.z;
			return *this; 
		} 

		ofPoint operator*(const float f) const { 
			return ofPoint( x*f, y*f, z*f );
		} 
		
		ofPoint& operator*=(const float f) { 
			x *= f;
			y *= f;
			z *= f;
			return *this; 
		} 
		
		ofPoint operator/(const ofPoint &p) const { 
			return ofPoint( x/p.x, y/p.y, z/p.z );
		} 
		
		ofPoint& operator/=(const ofPoint &p) { 
			x /= p.x;
			y /= p.y;
			z /= p.z;
			return *this; 
		} 

		ofPoint operator/(const float f) const { 
			return ofPoint( x/f, y/f, z/f );
		} 

		ofPoint& operator/=(const float f) { 
			x /= f;
			y /= f;
			z /= f;
			return *this; 
		}

	float x; 
	float y;
	float z;
};


#endif
