#ifndef __UtilRect_h
#define __UtilRect_h

#include "UtilArc.h"	// For GetArcPolygon.


extern void FFGetInvalidRect (	CRectVector& rtInvalid,
								const CRect& rtSrc,
								CRect rtValid);


extern void FFGetRectPolygon (	DBLPointVector& vmmptPoint,
								const DBLPoint& mmptCenter,
								mmetol mmLx, mmetol mmLy,
								mmetol mmShiftX,
								angle dRotate,
								const DBLPoint& mmptRotateCenter);

extern void FFGetRectBezier (	FCMmPolyBezier& polyBezier,
								const DBLPoint& mmptCenter,
								mmetol mmLx,
								mmetol mmLy,
								mmetol mmShiftX,
								angle dRotate,
								const DBLPoint& mmptRotateCenter);

extern void FFGetRoundRectBezier (	FCMmPolyBezier& polyBezier,
									const DBLPoint& mmptCenter,
									mmetol mmLx,
									mmetol mmLy,
									mmetol mmRoundX,
									mmetol mmRoundY,
									mmetol mmShiftX,
									angle dRotate,
									const DBLPoint& mmptRotateCenter);

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	GetRoundRectPolygon
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iKhAiCkKiKnLiCkCiLoJiMgAiCmMiDhMiDiKiDfDiDjDiCpAiOfKiPgPiClHiCoJiBeCiKePjAnKiClHiCoJiLoJiMgAiBeBiOgMiLpHiCmMiKnLiCnN_xHqqkZx_
			_xZkqqHx_iCpAiMgAjAkMiClHiCoJiJhOiCmJiKePjAnKiClHiCoJiLoJiMgAiCmMjFjNiBeBiNiCiClDiCpAjHfOiCkGiCoHiCoKiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	vPoint	:_xZkqqHx_jIeBiMiLjApMiCmMiNmAjFfHjEhKjHpBiCpAiOpLiCnPiCoJiDgPiDgCiDhEiDeA_xHqqkZx_
 *			dCX		:_xZkqqHx_jCiGjAfDjDfPiCmM_xHqqkZx_X_xZkqqHx_iNmAjFfH_xHqqkZx_
 *			dCY		:_xZkqqHx_jCiGjAfDjDfPiCmM_xHqqkZx_Y_xZkqqHx_iNmAjFfH_xHqqkZx_
 *			dLX		:X_xZkqqHx_iOlCjElMiMgB_xHqqkZx_
 *			dLY		:Y_xZkqqHx_iOlCjElMiMgB_xHqqkZx_
 *			dRoundX	:_xZkqqHx_iKhAiCmMiCfDjFkKiCmMiCfAiJhOiCmMjElMiMgBiBgJiChHjFpLiMpMiBgKiBeC_xHqqkZx_
 *			dRoundY	:_xZkqqHx_iKhAiCmMiCfDjFkKiCmMiCfAiJhOiCmMjElMiMgBiBgJiChIjFpLiMpMiBgKiBeC_xHqqkZx_
 *			dSftX	:X_xZkqqHx_jFpLiMpMiCnGiCmMiDfGiDhEiDgHjFmPiMgAiCmMjBoFiCkLiClD_xHqqkZx_
 *			dRotate	:_xZkqqHx_iJpBjDfNjFmPiMgAiCmMiKhAjDhI_xHqqkZx_
 *			dRotX	:_xZkqqHx_iJpBjDfNjFmPiMgAiCmMiJpBjDfNiOlCiCmM_xHqqkZx_X_xZkqqHx_iNmAjFfH_xHqqkZx_
 *			dRotX	:_xZkqqHx_iJpBjDfNjFmPiMgAiCmMiJpBjDfNiOlCiCmM_xHqqkZx_Y_xZkqqHx_iNmAjFfH_xHqqkZx_
 *			dElemLen :_xZkqqHx_jClIjDfPiKnEiCmMiLjHjHkDiCpAiOhHjCoIiBeCjGnKiImAjCpGjDhIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	99.06.21 Fukushiro M. POINTVECT_xZkqqHx_iCpAjDlBjDpMiBeC_xHqqkZx_
 *			almost0(dRoundX) || almost0(dRoundY)_xZkqqHx_iCmJjBmOiJjOiBeC_xHqqkZx_
 *************************************************************************/
template<class POINTVECT>
void GetRoundRectPolygon (POINTVECT& vPoint, double dCX, double dCY,
						double dLX, double dLY, double dRoundX, double dRoundY,
						double dSftX, double dRotate, double dRotX, double dRotY,
						double dElemLen)
{
	vPoint.clear();
	double dLeft	= dCX - dLX;
	double dTop		= dCY - dLY;
	double dRight	= dCX + dLX;
	double dBottom	= dCY + dLY;

	DBLPointVector	vdArcPoint;
	if (almost0(dRoundX) || almost0(dRoundY))
	//----- _xZkqqHx_iKhAiKnLiCkKjGlDiCkCiPoKiNiHiBgJjBkGiClPjFiBjCmKiCmMiLoJiMgAiCmMiPoKiNiHiBgK_xHqqkZx_-----
	{
		vdArcPoint.push_back(DBLPoint(0,0));
	} else
	//----- _xZkqqHx_iKhAiKnLiCkKjHeMiCoJiPoKiNiH_xHqqkZx_ -----
	{
		// _xZkqqHx_iLoJiMgAiCmMjCfLiCpAiBeBiKhAiKnLiCmMjBoFiCkLiClDjFkKiPgLiPkMiBeC_xHqqkZx_
		dLeft	+= dRoundX;
		dTop	+= dRoundY;
		dRight	-= dRoundX;
		dBottom	-= dRoundY;
		// _xZkqqHx_iKhAiKnLiCmMiDhMiDiKiDfDiDjDiBgJ_xHqqkZx_1/4_xZkqqHx_iBgKiCpAiMhGiOfKiBeC_xHqqkZx_
		::GetArcPolygon(vdArcPoint, 0.0, 0.0, dRoundX, dRoundY, 0.0, 0.5, 3, dElemLen);
	}

	long lC;

	POINTVECT::iterator iP;
	if (dSftX == 0.0 && dRotate == 0.0)
	{
		//----- _xZkqqHx_iJeFiJlKiCmMiKhAiKnLjFjEjFkKiDhMiDiKiDfDiDjDiCpAiMhGiOfK_xHqqkZx_ -----
		for (lC = 0; lC < vdArcPoint.size(); lC++)
		{
			iP = vPoint.insert(vPoint.end());
			RSUB((*iP).x, dRight + vdArcPoint[lC].x);
			RSUB((*iP).y, dBottom + vdArcPoint[lC].y);
		}
		//----- _xZkqqHx_iNlGiJlKiCmMiKhAiKnLjFjEjFkKiDhMiDiKiDfDiDjDiCpAiMhGiOfK_xHqqkZx_ -----
		for (lC = vdArcPoint.size() - 1; 0 <= lC; lC--)
		{
			iP = vPoint.insert(vPoint.end());
			RSUB((*iP).x, dLeft - vdArcPoint[lC].x);
			RSUB((*iP).y, dBottom + vdArcPoint[lC].y);
		}
		//----- _xZkqqHx_iNlGiPoDiCmMiKhAiKnLjFjEjFkKiDhMiDiKiDfDiDjDiCpAiMhGiOfK_xHqqkZx_ -----
		for (lC = 0; lC < vdArcPoint.size(); lC++)
		{
			iP = vPoint.insert(vPoint.end());
			RSUB((*iP).x, dLeft - vdArcPoint[lC].x);
			RSUB((*iP).y, dTop - vdArcPoint[lC].y);
		}
		//----- _xZkqqHx_iJeFiPoDiCmMiKhAiKnLjFjEjFkKiDhMiDiKiDfDiDjDiCpAiMhGiOfK_xHqqkZx_ -----
		for (lC = vdArcPoint.size() - 1; 0 <= lC; lC--)
		{
			iP = vPoint.insert(vPoint.end());
			RSUB((*iP).x, dRight + vdArcPoint[lC].x);
			RSUB((*iP).y, dTop - vdArcPoint[lC].y);
		}
		vPoint.push_back(vPoint.front());
	} else {
		// Y_xZkqqHx_iOlCjCfAiImKiLjHjHkDiCkAiClNiCoIiCmM_xHqqkZx_X_xZkqqHx_jFpLiMpMiDfGiDhEiDgHjHmKiCpAiMhGiOfKiBeC_xHqqkZx_
		dSftX	/= dLY;
		double	dX, dY;
		const double dSinR = sin(dRotate * M_PI);
		const double dCosR = cos(dRotate * M_PI);

		//----- _xZkqqHx_iJeFiJlKiCmMiKhAiKnLjFjEjFkKiDhMiDiKiDfDiDjDiCpAiMhGiOfK_xHqqkZx_ -----
		for (lC = 0; lC < vdArcPoint.size(); lC++)
		{
			dX = dRight + vdArcPoint[lC].x;
			dY = dBottom + vdArcPoint[lC].y;
			dX += dSftX * (dY - dCY) - dRotX;
			dY -= dRotY;
			iP = vPoint.insert(vPoint.end());
			RSUB((*iP).x, dRotX + dCosR * dX - dSinR * dY);
			RSUB((*iP).y, dRotY + dSinR * dX + dCosR * dY);
		}
		//----- _xZkqqHx_iNlGiJlKiCmMiKhAiKnLjFjEjFkKiDhMiDiKiDfDiDjDiCpAiMhGiOfK_xHqqkZx_ -----
		for (lC = vdArcPoint.size() - 1; 0 <= lC; lC--)
		{
			dX = dLeft - vdArcPoint[lC].x;
			dY = dBottom + vdArcPoint[lC].y;
			dX += dSftX * (dY - dCY) - dRotX;
			dY -= dRotY;
			iP = vPoint.insert(vPoint.end());
			RSUB((*iP).x, dRotX + dCosR * dX - dSinR * dY);
			RSUB((*iP).y, dRotY + dSinR * dX + dCosR * dY);
		}
		//----- _xZkqqHx_iNlGiPoDiCmMiKhAiKnLjFjEjFkKiDhMiDiKiDfDiDjDiCpAiMhGiOfK_xHqqkZx_ -----
		for (lC = 0; lC < vdArcPoint.size(); lC++)
		{
			dX = dLeft - vdArcPoint[lC].x;
			dY = dTop - vdArcPoint[lC].y;
			dX += dSftX * (dY - dCY) - dRotX;
			dY -= dRotY;
			iP = vPoint.insert(vPoint.end());
			RSUB((*iP).x, dRotX + dCosR * dX - dSinR * dY);
			RSUB((*iP).y, dRotY + dSinR * dX + dCosR * dY);
		}
		//----- _xZkqqHx_iJeFiPoDiCmMiKhAiKnLjFjEjFkKiDhMiDiKiDfDiDjDiCpAiMhGiOfK_xHqqkZx_ -----
		for (lC = vdArcPoint.size() - 1; 0 <= lC; lC--)
		{
			dX = dRight + vdArcPoint[lC].x;
			dY = dTop - vdArcPoint[lC].y;
			dX += dSftX * (dY - dCY) - dRotX;
			dY -= dRotY;
			iP = vPoint.insert(vPoint.end());
			RSUB((*iP).x, dRotX + dCosR * dX - dSinR * dY);
			RSUB((*iP).y, dRotY + dSinR * dX + dCosR * dY);
		}
		vPoint.push_back(vPoint.front());
	}
} // GetRoundRectPolygon.

#endif//__UtilRect_h
