
#ifndef __WFX_MATH_PLANE_H__
#define __WFX_MATH_PLANE_H__

#include <WFX/WFXIncludes.h>
#include <WFX/math/Vector3.h>

namespace WFX {

    namespace math {

        /**
         * a plane in 3D space
         * defined by Ax + By + Cz + D = 0
         */
        class Plane {
            public:
                /**
                 * sides of a plane
                 * The "positive side" of the plane is the half space to which the
                 * plane normal points. The "negative side" is the other half
                 * space. The flag "no side" indicates the plane itself.
                 */
                enum Side {
                    NO_SIDE,
                    POSITIVE_SIDE,
                    NEGATIVE_SIDE
                };

                /**
                 * Ctor/Dtor
                 */
                Plane() {
                    D = 0.0f;
                    Normal = Vector3::ZERO;
                }

                Plane(math::Vector3& n, Real d) {
                    Normal = n;
                    D = d;
                }
    
                /** sets the normal */
                void setNormal(Real x, Real y, Real z) {
                    Normal.X = x;
                    Normal.Y = y;
                    Normal.Z = z;
                }
                void setNormal(Vector3 n) {
                    Normal = n;
                }
                /** return normal */
                inline WFX::math::Vector3 getNormal() const {
                    return Normal;
                }
                /** sets the constant */
                inline void setConstant(Real r) {
                    D = r;
                }
                /** return constant */
                inline Real getConstant() const {
                    return D;
                }

                /** normalizes the plane */
                void normalize();
                
                /**
                 * returns which side the point is on
                 */
                Side side(const math::Vector3& p) const;
                /**
                 * returns the pseudedistance
                 * returns a positive value if the point is on the positive side of the plane,
                 * a negative value if the point is on the negative side of the plane
                 * and zero if the point lies on the plane
                 */
                Real distance(const math::Vector3& p) const;
                 
                
            protected:
                math::Vector3 Normal;
                Real D;
                
                
        };

    }

}


#endif //include guard


