/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/* ***************************************************** */
/********************************************************************/
// planar.h
// declaraion for planar checker
#if !defined( __PLANAR_H__)
#define __PLANAR_H__
#include "mg/Straight.h"
#include "mg/Plane.h"
#include "Calc/curve.h"  // for is_planar()

namespace mgcalc{
	///@name const values for struct MGCurvePlanarInfo.
	// See struct MGCurvePlanarInfo::mask.
	//@{
	const unsigned int CPI_CHECK_ONLY   = 0x01;
	const unsigned int CPI_PLANAR       = 0x02;
	const unsigned int CPI_3D           = 0x04;
	const unsigned int CPI_STRAIGHT     = 0x08;
	const unsigned int CPI_POINT        = 0x10;
	const unsigned int CPI_PLANE        = 0x20;
	//@}

	/// class MGCurvePlanarInfo
	///
	/// Retrieves information about flatness of a curve.
	class MGCurvePlanarInfo{
	public:
		/// construction
		explicit MGCurvePlanarInfo(const MGCurve& c)
			: m_mask(0x0), m_curve(c){}

		/// Calculates planarity.
		bool calculate(unsigned int mask);

		/// Returns whether the curve is 3-D or not.
		bool is_3D() const{
			return (m_mask & CPI_3D) != 0;
		}

		/// Returns whether the curve is strictly planar (2-D curve) or not.
		bool is_planar() const{
			return (m_mask & CPI_PLANAR) != 0;
		}

		/// Returns whether the curve is a point(0-D) or not.
		bool is_point() const{
			return (m_mask & CPI_POINT) != 0;
		}

		/// Returns whether the curve is straight(1-D) or not.
		bool is_straight() const{
			return (m_mask & CPI_STRAIGHT) != 0;
		}

		/// Returns the straight line if the curve is straight.
		const MGStraight& straight() const{
			ASSERT(is_straight());
			ASSERT(!(m_mask & CPI_CHECK_ONLY));
			return m_sl;
		}

		/// Returns the plane if the curve is planar.
		const MGPlane& plane() const{
			ASSERT(!is_straight());
			ASSERT(!is_point());
			ASSERT(!(m_mask & CPI_CHECK_ONLY));
			return m_pl;
		}

		/// Returns the position if the curve is a point.
		const MGPosition& position() const{
			ASSERT(is_point());
			ASSERT(!(m_mask & CPI_CHECK_ONLY));
			return m_pos;
		}

	// data members
	private:
		unsigned int   m_mask;
			// Set of flags that indicate which members contain valid information. 
			// This member must be specified in calling calculate().
			// This can be one or more of the following values:
			// CPI_CHECK_ONLY   calculate() does not modify neither m_sl, m_pl, or m_pos.
			// CPI_PLANAR     [m_curve] is planar, neither straight nor point.
			// CPI_3D         [m_curve] is a 3-D curve.
			// CPI_STRAIGHT     [m_sl] is valid.
			// CPI_POINT    [m_pos] is valid.
			// CPI_PLANE    [m_pl] is valid.

		const MGCurve& m_curve;
		MGStraight     m_sl;
		MGPlane        m_pl;
		MGPosition     m_pos;
	};

} // mgcalc

#endif //__PLANAR_H__
