/*
 *  psychlops_g_fundamental.h
 *  Psychlops Standard Library (Universal)
 *
 *  Last Modified 2005/10/05 by Kenchi HOSOKAWA
 *  (C) 2005 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
 */

#ifndef HEADER_PSYCHLOPS_GRAPHIC_FUNDAMENTAL
#define HEADER_PSYCHLOPS_GRAPHIC_FUNDAMENTAL



namespace Psychlops {

	class Rectangle;
	class Canvas;
	class Image;
	class Figure;


	class Point {
		friend class Figure;
		friend class Drawable;
		friend class Image;

		private:
		inline void setbypix(const double ix, const double iy, const double iz) { x = ix; y = iy; z = iz; }
		public:
		double x,y,z;
		inline Point() : x(0.0), y(0.0), z(0.0) {}
		inline Point(const double ix, const double iy, const double iz = 0) : x(ix), y(iy), z(iz) {}
		inline Point& set(const double ix, const double iy, const double iz = 0) { x = ix; y = iy; z = iz; return *this; }
		inline Point& shift(const double h, const double v, const double d = 0) { x+=h; y+=v; z+=d; return *this; }
		Point& centering();
		Point& centering(const Figure& fig);
		inline Point& centering(const double h, const double v, const double d = 0) { x=h; y=v; z=d; return *this; }
		inline Point& setX(const double val) { x = val; return *this; }
		inline Point& setY(const double val) { y = val; return *this; }
		inline Point& setZ(const double val) { z = val; return *this; }
		inline double getX() const { return x; }
		inline double getY() const { return y; }
		inline double getZ() const { return z; }
		inline Point dup();
		inline Point operator+(const Point& rhs) { return Point(x+rhs.x, y+rhs.y, z+rhs.z); }
		inline Point operator-(const Point& rhs) { return Point(x-rhs.x, y-rhs.y, z-rhs.z); }
		double length() const;
	};


}	/*	<- namespace Psychlops 	*/










namespace Psychlops {
	//  Listings of Classes in this file
	class Length;
	class Angle;

	//  Listings of Graphics standard classes
	class Color;
	class Point;
	class Rectangle;

	class Drawable;
	class Canvas;
	class Display;
	class Image;
	class Stroke;

	class Length {
		private:
		double px_;

		public:
		Length();
		Length(const int val);
		Length(const double val);
		Length(const Length &val);
		operator double() const;
		Length & operator =(const double val);
	};
	class LENGTH_ARCDEG {
	};
	extern LENGTH_ARCDEG arcdeg;
	Length operator *(double arcdeg, LENGTH_ARCDEG &unit);
	class LENGTH_PIXEL {
	};
	extern LENGTH_PIXEL pixel;
	Length operator *(double arcdeg, LENGTH_PIXEL &unit);



	class ANGLE_DEGREE {
	};
	extern ANGLE_DEGREE degree;
	Angle operator *(double degrees, ANGLE_DEGREE &unit);
	class ANGLE_RADIAN {
	};
	extern ANGLE_RADIAN radian;
	Angle operator *(double radian, ANGLE_RADIAN &unit);

	class Angle {
		protected:
		static const double PERIOD;
		static const double HALF_PERIOD;
		static const double SCALE_TO_DEGREE;
		double decadegree_;
		Angle(double decadegrees, int dummy);

		public:
		Angle();
		Angle(int degrees);
		Angle(const double degrees);
		Angle(const double degrees, ANGLE_DEGREE &unit);
		Angle(const double radians, ANGLE_RADIAN &unit);
		Angle(const Angle &init);
		operator double() const;
		Angle operator =(const double val);
		Angle operator +(Angle rhs) const;
		Angle operator -(Angle rhs) const;
		Angle & operator +=(Angle rhs);
		Angle & operator -=(Angle rhs);
		double clip() const;
		double at_degree() const;
		double at_radian() const;
		double sin() const;
		double cos() const;
		double tan() const;
		void set_as_degree(double degrees);
		void set_as_decadegree(double decadegree);
		void set_as_radian(double radians);
	};


}	/*	<- namespace Psycholops 	*/


#endif
