#pragma once
#include "McGePoint2d.h"
#include "McArray.h"
#include "McGeBoundBlock2d.h"

#include "McGePoint3d.h"
#include "McGeVector3d.h"

class McGeInterval;
class MgeCurve;
class MgeCurve3d;
// -------------------------------------------------------------------------
// Summary:
// 		几何曲线类型
// -------------------------------------------------------------------------
class MXGEDLL McGeCurve2d
{
public:
	McGeCurve2d(const McGeCurve2d& scr);
	virtual McGeBoundBlock2d  orthoBoundBlock() const;

	void     getSamplePoints(
		double approxEps, McGePoint2dArray& pointArray,
		McGeDoubleArray& paramArray) const;

	void     getSamplePoints(
		double approxEps, std::vector<McGePoint2d>& aryPt) const;

	void getSamplePoints(
		double fromParam,
		double toParam,
		double approxEps,
		McGePoint2dArray& pointArray,
		McGeDoubleArray* pParamArray = NULL) const;


	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线的几何计算参数
	// -------------------------------------------------------------------------
	void           getInterval(McGeInterval& intrvl) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		给一个参数位置，计算曲线上的点
	// Parameters:
	// 		param	-	曲线参数
	//		pOk		-	返回是否成功计算
	// Returns:
	// 		返回计算的点
	// -------------------------------------------------------------------------
	McGePoint2d    evalPoint(double param,bool* pOk = NULL) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		计算曲线上一点处的曲线参数
	// Parameters:
	// 		pnt		-	曲线上的一点
	//		tol		-	计算精度
	//		pOk		-	是否计算成功
	// Returns:
	// 		返回计算的参数
	// -------------------------------------------------------------------------
	double         paramOf(const McGePoint2d& pnt,
		const McGeTol& tol = McGeContext::gTol,bool* pOk = NULL) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		计算曲线上的一点到曲线开始点的曲线长度
	// Parameters:
	// 		pnt -	曲线上的一点
	// Returns:
	// 		返回曲线长
	// -------------------------------------------------------------------------
	double         distanceTo(const McGePoint2d& pnt,
		const McGeTol& = McGeContext::gTol,bool* pOk = NULL) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		计算曲线参数所在位置到曲线开始点的曲线长度
	// Parameters:
	// 		dParam - 曲线参数
	// Returns:
	// 		返回曲线长
	// -------------------------------------------------------------------------
	double         distanceOfParam(double dParam,bool* pOk = NULL) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		由曲线长返回曲线参数
	// Parameters:
	// 		dDis - 曲线长
	// Returns:
	// 		返回曲线参数
	// -------------------------------------------------------------------------
	double         paramOfDis(double dDis,bool* pOk = NULL ) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		计算曲线参数所代表的位置在曲线上的一阶导数
	// Parameters:
	// 		param -	曲线参数
	// Returns:
	// 		返回曲线上的一阶导数
	// -------------------------------------------------------------------------
	McGeVector2d   getFirstDeriv  (double param,bool* pOk = NULL) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		计算曲线周围的一点到曲线上的最近点
	// Parameters:
	// 		pnt - 曲线周围的一点
	// Returns:
	// 		返回最近点
	// -------------------------------------------------------------------------
	McGePoint2d closestPointTo(const McGePoint2d& pnt,
		const McGeTol& tol = McGeContext::gTol,bool* pOk = NULL) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线的开始点
	// Parameters:
	// 		startPoint	-	曲线的开始点
	// -------------------------------------------------------------------------
	Mdesk::Boolean hasStartPoint(McGePoint2d& startPoint) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线的结束点
	// Parameters:
	// 		endPoint	-	曲线的结束点
	// -------------------------------------------------------------------------
	Mdesk::Boolean hasEndPoint  (McGePoint2d& endPoint) const;

	virtual McGeCurve2d&    transformBy(const McGeMatrix2d& xfm);

	//:Ignore
	Mdesk::Boolean isOn(const McGePoint2d& pnt,
		const McGeTol& tol = McGeContext::gTol) const;


	bool area(double startParam, double endParam, double& value, const McGeTol& tol = McGeContext::gTol) const;

	//:End Ignore
	virtual ~McGeCurve2d();
	virtual MgeCurve* cloneImpObject() const = 0;
protected:
	McGeCurve2d(void);
public:
	MgeCurve* m_pImp;
};


class MXGEDLL McGeCurve3d
{
public:
	McGeCurve3d(const McGeCurve3d& scr);
	virtual ~McGeCurve3d();
	virtual MgeCurve3d* cloneImpObject() const = 0;

	void getInterval(
		McGeInterval& interval) const;


	void getSamplePoints(
		double fromParam,
		double toParam,
		double approxEps,
		McGePoint3dArray& pointArray,
		McGeDoubleArray* pParamArray = NULL) const;


protected:
	McGeCurve3d(void);

public:
	MgeCurve3d* m_pImp;
};

class MXGEDLL McGeTool
{
public:
	static bool circularArcProc(const McGePoint3d& center,
		double radius,
		const McGeVector3d& normal,
		const McGeVector3d& startVector,
		double sweepAngle, double dVTol, McGePoint3dArray& point);

	static  double paramFromAngle(
		double angle,
		double radiusRatio);
		
#ifdef MXDRAW_DEBUG
	static void Test();
#endif
};
