/**
 *  @class Plane
 *
 *  @Date: Created by Ray Zhang on 28/07/14.
 *
 *  @Description
 *  Define a plane, defined by a point and the normal from the point.
 */

#ifndef __UTILS_PLANE__
#define __UTILS_PLANE__

#include "Ray.h"

class Plane
{
public:

  enum Side
  {
    SIDE_NONE,
    SIDE_FRONT,
    SIDE_BACK
  };

  /**
   *  Constructor.
   *
   *  @param point
   *  A point through which the plane passes.
   *
   *  @param normal
   *  The normal of the plane.
   *
   */
  Plane(const RKVector& point, const RKVector& normal);

  /**
   *  Constructor, creates a plane from three points on the plane.
   *
   *  @param p1
   *  First point on the plane
   *
   *  @param p2
   *  Second point on the plane
   *
   *  @param p3
   *  Third point on the plane
   *
   */
  Plane(const RKVector& p1, const RKVector& p2, const RKVector& p3);

  /**
   *  Calculate the intersection point between a ray and an infinite plane.
   *
   *  @param lineBegin, lineDirection
   *  The origin and direction of the ray. The direction is assumed to be normalised.
   *
   *  @param outIntersection
   *  A pointer through which to return the intersection point.
   *
   *  @return
   *  true  - if an intersection was found.
   *  false - if no intersection was found (the ray and the line must be parallel).
   */
  bool Intersection(const RKVector& lineBegin, const RKVector& lineDirectionNormalised, RKVector* outIntersection) const;
  bool Intersection(const Ray& ray, RKVector* outIntersection) const;

  /**
   * Calculate which side a point falls on
   *
   * @param test_position
   *   The point to be tested
   *
   * @return
   *   The side of the plane that the point falls on.
   */
  Side GetSide(const RKVector& test_position) const;

private:
  RKVector m_point;  ///< A point through which the plane passes.
  RKVector m_normal; ///< The normal direction to the plane.
};

#endif // __UTILS_PLANE__
