#pragma once
#include "McDbCurve.h"
class McDbEllipseImp;

// -------------------------------------------------------------------------
// Summary:
// 		此类表示AutoCAD中的椭圆\椭圆弧实体。它包含了创建、修改了获取椭圆\椭圆弧属性的方法
// Remarks:
// 		例如:绘制椭圆，和椭圆弧代码
// 		<code>
// 			LONG MxDrawXDrawFun::AddToCurrentSpace(McDbEntity* newEnt)
// 			{
// 				MrxDbgUtils::addToCurrentSpace(newEnt,m_pDatabase);
// 				MakeProp(newEnt);
// 
// 				McDbObjectId id = newEnt->objectId();
// 				newEnt->close();
// 
// 				return (LONG)(id.asOldId() );
// 			}
// 
// 			LONG MxDrawXDrawFun::DrawEllipse(mxreal dCenterX, mxreal dCenterY, 
// 											 mxreal dMajorAxisX, mxreal dMajorAxisY,
// 											 mxreal dRadiusRatio)
// 			{
// 				if(MxT::IsZero(m_dLineWidth))
// 				{
// 					McGePoint3d  center(dCenterX,dCenterY,0.0);
// 					McGeVector3d majorAxis(dMajorAxisX,dMajorAxisY,0.0);
// 					McDbEllipse* pEllipse = new McDbEllipse(center,McGeVector3d::kZAxis,majorAxis,dRadiusRatio);
// 					return AddToCurrentSpace(pEllipse);
// 				}
// 				else
// 				{
// 					// 有宽的椭圆暂不能支持，将来只有能通过一个带有宽度的圆的块引用来实现。 
// 					// ...
// 
// 					// 这里暂当着没有宽度来处理。
// 
// 					McGePoint3d  center(dCenterX,dCenterY,0.0);
// 					McGeVector3d majorAxis(dMajorAxisX,dMajorAxisY,0.0);
// 					McDbEllipse* pEllipse = new McDbEllipse(center,McGeVector3d::kZAxis,majorAxis,dRadiusRatio);
// 					return AddToCurrentSpace(pEllipse);
// 
// 				}
// 			}
// 
// 			LONG MxDrawXDrawFun::DrawEllipseArc(mxreal dCenterX, mxreal dCenterY, mxreal dMajorAxisX, 
// 												mxreal dMajorAxisY, mxreal dRadiusRatio, mxreal dStartAng, mxreal dEndAng)
// 			{
// 				// 有宽的椭圆暂不能支持，将来只有能通过一个带有宽度的圆的块引用来实现。 
// 				// ...
// 
// 				// 这里暂当着没有宽度来处理。
// 				McGePoint3d  center(dCenterX,dCenterY,0.0);
// 				McGeVector3d majorAxis(dMajorAxisX,dMajorAxisY,0.0);
// 
// 				McDbEllipse* pEllipse = new McDbEllipse(center,McGeVector3d::kZAxis,majorAxis,
// 					dRadiusRatio,dStartAng,dEndAng);
// 				return AddToCurrentSpace(pEllipse);
// 			}
// 		</code>
// -------------------------------------------------------------------------
class ARXDLL McDbEllipse : public  McDbCurve
{
public:
	// -------------------------------------------------------------------------
	// Summary:
	// 		构造函数
	// -------------------------------------------------------------------------
	McDbEllipse(void);

	// -------------------------------------------------------------------------
	// Summary:
	// 		构造函数
	// Parameters:
	//		center            -		椭圆的圆心
	//		unitNormal        -		暂没有使用
	//		majorAxis         -		椭圆的主轴向量
	//		radiusRation      -		椭圆的副轴长与主轴长的比值
	//		startAngle        -		椭圆弧开点位置顺时针转到主轴的角度
	//		endAngle          -		椭圆弧结束点位置顺时针转到主轴的角度
	// -------------------------------------------------------------------------
	McDbEllipse(const McGePoint3d&  center,
		const McGeVector3d& unitNormal,
		const McGeVector3d& majorAxis,
		mxreal              radiusRatio,
		mxreal              startAngle = 0.0,
		mxreal              endAngle   = 6.283185307179586476925286766559000);

	// -------------------------------------------------------------------------
	// Summary:
	// 		析构函数
	// -------------------------------------------------------------------------
	virtual ~McDbEllipse();

	// -------------------------------------------------------------------------
	// Summary:
	// 		申明类型信息
	// -------------------------------------------------------------------------
	MCDB_DECLARE_MEMBERS(McDbEllipse);

	// -------------------------------------------------------------------------
	// Summary:
	// 		椭圆的中心点
	// -------------------------------------------------------------------------
	McGePoint3d center() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置椭圆的中心点
	// Parameters:
	// 		center	-	椭圆的中心点 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setCenter(const McGePoint3d& center);
	

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回椭圆的主轴向量
	// -------------------------------------------------------------------------
	McGeVector3d majorAxis() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回椭圆的副轴向量
	// -------------------------------------------------------------------------
	McGeVector3d minorAxis() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置椭圆的副轴长度与主轴长度的比值
	// -------------------------------------------------------------------------
	mxreal radiusRatio() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置椭圆的副轴长度与主轴长度的比值
	// Parameters:
	// 		ratio	-	副轴长度与主轴长度的比值 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setRadiusRatio(mxreal ratio);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回椭圆弧的开始角度
	// -------------------------------------------------------------------------
	mxreal startAngle() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置椭圆弧的开始角度
	// Parameters:
	// 		startAngle	-	椭圆弧的开始角度 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setStartAngle(mxreal startAngle);    

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回椭圆弧的结束角度
	// -------------------------------------------------------------------------
	mxreal endAngle() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置椭圆弧的结束角度
	// Parameters:
	// 		endAngle	-	椭圆弧的结束角度 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setEndAngle(mxreal endAngle);


	//:Ignore

	bool isClosed() const;

	Mcad::ErrorStatus getArea(double& area) const  override;

	void setMajorAxis(const McGeVector3d& vec);
	void setMinorAxis(const McGeVector3d& vec);


	virtual Mcad::ErrorStatus getGripPoints(McGePoint3dArray&    gripPoints,
		McGeIntArray& osnapMasks, McGeIntArray& geomIds) const;

	virtual  Mcad::ErrorStatus moveGripPointsAt(
		const McGeIntArray& indices, const McGeVector3d& offset);

	virtual Mcad::ErrorStatus dwgOutFields(McDbDwgFiler* pFiler) const;
	virtual Mcad::ErrorStatus dwgInFields(McDbDwgFiler* pFiler);
	virtual Mdesk::Boolean worldDraw(McGiWorldDraw* mode);

	virtual Mcad::ErrorStatus   getGeomExtents(McDbExtents& extents, bool roughCalculation = true) const;




	virtual Mcad::ErrorStatus getStartParam(mxreal&) const;
	virtual Mcad::ErrorStatus getEndParam  (mxreal&) const;



	virtual Mcad::ErrorStatus getStartPoint(McGePoint3d&) const;
	virtual Mcad::ErrorStatus getEndPoint  (McGePoint3d&) const;

	virtual Mcad::ErrorStatus getPointAtParam(mxreal, McGePoint3d&) const;
	virtual Mcad::ErrorStatus getParamAtPoint(const McGePoint3d&, mxreal&)const;

	virtual Mcad::ErrorStatus getDistAtParam (mxreal param, mxreal& dist) const;
	virtual Mcad::ErrorStatus getParamAtDist (mxreal dist, mxreal& param) const;
	virtual Mcad::ErrorStatus getDistAtPoint (const McGePoint3d&, mxreal&)const;
	virtual Mcad::ErrorStatus getPointAtDist (mxreal, McGePoint3d&) const;

	virtual Mcad::ErrorStatus getFirstDeriv  (mxreal param,
		McGeVector3d& firstDeriv) const;
	virtual Mcad::ErrorStatus getFirstDeriv  (const McGePoint3d&,
		McGeVector3d& firstDeriv) const;

	virtual Mcad::ErrorStatus getClosestPointTo(const McGePoint3d& givenPnt,
		McGePoint3d& pointOnCurve,
		Mdesk::Boolean extend
		= Mdesk::kFalse) const;

	virtual Mcad::ErrorStatus getClosestPointTo(const McGePoint3d& givenPnt,
		const McGeVector3d& direction,
		McGePoint3d& pointOnCurve,
		Mdesk::Boolean extend
		= Mdesk::kFalse) const;

	virtual Mcad::ErrorStatus   getOsnapPoints(
		McDb::OsnapMode     osnapMode,
		int                 gsSelectionMark,
		const McGePoint3d&  pickPoint,
		const McGePoint3d&  lastPoint,
		const McGeMatrix3d& viewXform,
		McGePoint3dArray&   snapPoints,
		McDbIntArray&       geomIds) const;


	virtual Mcad::ErrorStatus   transformBy(const McGeMatrix3d& xform);

	virtual Mcad::ErrorStatus getOffsetCurves(mxreal offsetDist,
		McDbVoidPtrArray& offsetCurves) const;

	virtual Mcad::ErrorStatus getOffsetCurvesEx(mxreal offsetDist,
		McDbVoidPtrArray& offsetCurves,McGePoint3d ptOffsetRef) const;

	virtual Mcad::ErrorStatus getSplitCurves (const McGeDoubleArray& params,
		McDbVoidPtrArray& curveSegments) const;

	virtual Mcad::ErrorStatus getSplitCurves (const McGePoint3dArray& points,
		McDbVoidPtrArray& curveSegments) const;

	virtual Mcad::ErrorStatus Mirror(McGePoint3d mirrorPt1,McGePoint3d mirrorPt2);


	virtual Mcad::ErrorStatus getSamplePoints(
		double approxEps, McGePoint3dArray& pointArray,
		McGeDoubleArray& paramArray) const;

	void set(const McGePoint3d&  center, const McGeVector3d& majorAxis, double radiusRatio,
		double              startAngle,
		double              endAngle);

	inline McDbEllipseImp* getMcDbEllipsemp() const {
		return (McDbEllipseImp*)m_pImp;
	}
	//:End Ignore
};
