#ifndef __DBLRect_h
#define __DBLRect_h

// _xZkqqHx_iImIiJlKiCmFiCmNiBeB_xHqqkZx_real _xZkqqHx_iCkKiOgHiCkGiCmIiCkCiBeC_xHqqkZx_typedef_xZkqqHx_iImIjBePiCmMiClNiCnPiBeC_xHqqkZx_

/**********************************************************************
 *                            DBLRect
 **********************************************************************/

//;----- <EXPORT TO SDK> -----;

struct DBLRECT
{
	double	left;
	double	top;
	double	right;
	double	bottom;
}; // struct DBLRECT.

class DBLRect : public DBLRECT
{
public:
	DBLRect ();
	DBLRect (double dL, double dT, double dR, double dB);
	DBLRect (const DBLPoint& mmptLT, const DBLPoint& mmptRB);
	DBLRect (const DBLRECT& mmrt);
	DBLRect (const RECT& rt);
	void SetRect (double dL, double dT, double dR, double dB);
	void SetRect (const DBLPoint& mmptLT, const DBLPoint& mmptRB);
	double Width () const;
	double Height () const;
	BOOL IsRectEmpty () const;
	BOOL IsRectNull () const;
	BOOL PtInRect (const DBLPoint& mmpt) const;
	BOOL RectInRect (const DBLRect& mmrt) const;
	void operator = (const DBLRECT& mmrt);
	void operator = (const RECT& rt);
	BOOL operator == (const DBLRECT& mmrt);
	BOOL operator == (const RECT& rt);
	void operator += (double d);
	void operator -= (double d);
	void operator *= (double d);
	void operator /= (double d);
	void operator += (const DBLPoint& mmpt);
	void operator -= (const DBLPoint& mmpt);
	void operator *= (const DBLPoint& mmpt);
	void operator |= (const DBLRect& mmrt);
	void operator &= (const DBLRect& mmrt);
	void Extend (double d);
	void Extend (double mmX, double mmY);
	void Reduce (double d);
	DBLRect ExtendRect (double d) const;
	DBLRect ExtendRect (double mmX, double mmY) const;
	DBLRect ReduceRect (double d) const;
	DBLRect ReduceRect (double mmX, double mmY) const;
	DBLPoint CenterPoint () const;
	void Get4Polygon (DBLPoint mmpta[]) const;
	void Get5Polygon (DBLPoint mmpta[]) const;
	void Get5Bezier (DBLPoint mmpta[]) const;
	void NormalizeRect ();
	DBLPoint GetLeftTop () const;
	DBLPoint GetRightBottom () const;
	DBLPoint GetRightTop () const;
	DBLPoint GetLeftBottom () const;

//----- 05.11.11 Fukushiro M. _xZkqqHx_iNoNiPjMiOgO_xHqqkZx_ ()-----
//public:
//	double	left;
//	double	top;
//	double	right;
//	double	bottom;
//----- 05.11.11 Fukushiro M. _xZkqqHx_iNoNiPjMiPeJ_xHqqkZx_ ()-----
}; // class DBLRect.

inline DBLRect operator - (const DBLRect& rect);

inline BOOL operator == (const DBLRect& drt1, const DBLRect& drt2);
inline BOOL operator != (const DBLRect& drt1, const DBLRect& drt2);
inline BOOL operator < (const DBLRect& mmrt1, const DBLRect& mmrt2);
inline BOOL operator < (const DBLRECT& mmrt1, const DBLRECT& mmrt2);
inline DBLRect operator - (const DBLRect& rect, const DBLRect& rect1);
inline DBLRect operator & (const DBLRect& drt1, const DBLRect& drt2);

inline DBLRect operator + (const DBLRect& rt, const DBLPoint& pt);
inline DBLRect operator + (const DBLPoint& pt, const DBLRect& rt);
inline DBLRect operator - (const DBLRect& rt, const DBLPoint& pt);
inline DBLRect operator - (const DBLPoint& pt, const DBLRect& rt);
inline DBLRect operator * (const DBLRect& rt, const DBLPoint& pt);
inline DBLRect operator * (const DBLPoint& pt, const DBLRect& rt);
inline DBLRect operator * (const DBLRect& rt, double d);
inline DBLRect operator * (double d, const DBLRect& rt);

inline DBLRect operator / (const DBLRect& rt, const DBLPoint& pt);
inline DBLRect operator / (const DBLPoint& pt, const DBLRect& rt);

//extern DBLRect operator & (const DBLRect& drt1, const RECT& rt2);
//extern DBLRect operator & (const RECT& rt1, const DBLRect& drt2);

inline BOOL almosteq (const DBLRect& drt1, const DBLRect& drt2);

/**********************************************************************
 *                            Impliment
 **********************************************************************/

inline DBLRect::DBLRect () {}

inline DBLRect::DBLRect (double dL, double dT, double dR, double dB)
{
	left	= dL;
	top		= dT;
	right	= dR;
	bottom	= dB;
} // DBLRect::DBLRect.

inline DBLRect::DBLRect (const DBLPoint& mmptLT, const DBLPoint& mmptRB)
{
	left	= mmptLT.x;
	top		= mmptLT.y;
	right	= mmptRB.x;
	bottom	= mmptRB.y;
} // DBLRect::DBLRect.

inline DBLRect::DBLRect (const DBLRECT& mmrt)
{
	left	= mmrt.left;
	top		= mmrt.top;
	right	= mmrt.right;
	bottom	= mmrt.bottom;
} // DBLRect::DBLRect.

inline DBLRect::DBLRect (const RECT& rt)
{
	left	= rt.left;
	top		= rt.top;
	right	= rt.right;
	bottom	= rt.bottom;
} // DBLRect::DBLRect.

inline void DBLRect::SetRect (double dL, double dT, double dR, double dB)
{
	left	= dL;
	top		= dT;
	right	= dR;
	bottom	= dB;
} // DBLRect::SetRect.

inline void DBLRect::SetRect (const DBLPoint& mmptLT, const DBLPoint& mmptRB)
{
	left	= mmptLT.x;
	top		= mmptLT.y;
	right	= mmptRB.x;
	bottom	= mmptRB.y;
} // DBLRect::SetRect.


inline double DBLRect::Width () const
{
	return right - left;
} // DBLRect::Width.

inline double DBLRect::Height () const
{
	return bottom - top;
} // DBLRect::Height.

inline BOOL DBLRect::IsRectEmpty () const
{
	return (left == right) || (top == bottom);
} // DBLRect::IsRectEmpty.

inline BOOL DBLRect::IsRectNull () const
{
	return (left == 0) && (top == 0) && (right == 0) && (bottom == 0);
} // DBLRect::IsRectNull.

inline BOOL DBLRect::PtInRect (const DBLPoint& mmpt) const
{
	if (mmpt.x < left || right  < mmpt.x) return FALSE;
	if (mmpt.y < top  || bottom < mmpt.y) return FALSE;
	return TRUE;
} // DBLRect::PtInRect.

inline BOOL DBLRect::RectInRect (const DBLRect& mmrt) const
{
	if ((left <= mmrt.left && mmrt.right <= right) &&
		(top <= mmrt.top && mmrt.bottom <= bottom)) return TRUE;
	return FALSE;
} // DBLRect::RectInRect.

inline void DBLRect::operator = (const DBLRECT& mmrt)
{
	left	= mmrt.left;
	top		= mmrt.top;
	right	= mmrt.right;
	bottom	= mmrt.bottom;
} // DBLRect::operator.

inline void DBLRect::operator = (const RECT& rt)
{
	left	= rt.left;
	top		= rt.top;
	right	= rt.right;
	bottom	= rt.bottom;
} // DBLRect::operator.

inline BOOL DBLRect::operator == (const DBLRECT& mmrt)
{
	return	(left == mmrt.left) &&
			(top == mmrt.top) &&
			(right == mmrt.right) &&
			(bottom == mmrt.bottom);
} // DBLRect::operator.

inline BOOL DBLRect::operator == (const RECT& rt)
{
	return (left == double(rt.left)) && (top == double(rt.top)) &&
			(right == double(rt.right)) && (bottom == double(rt.bottom));
} // DBLRect::operator.

inline void DBLRect::operator += (double d)
{
	left	+= d;
	top		+= d;
	right	+= d;
	bottom	+= d;
} // DBLRect::operator.

inline void DBLRect::operator -= (double d)
{
	left	-= d;
	top		-= d;
	right	-= d;
	bottom	-= d;
} // DBLRect::operator.

inline void DBLRect::operator *= (double d)
{
	left	*= d;
	top		*= d;
	right	*= d;
	bottom	*= d;
} // DBLRect::operator.

inline void DBLRect::operator /= (double d)
{
	left	/= d;
	top		/= d;
	right	/= d;
	bottom	/= d;
} // DBLRect::operator.

inline void DBLRect::operator += (const DBLPoint& mmpt)
{
	left	+= mmpt.x;
	top		+= mmpt.y;
	right	+= mmpt.x;
	bottom	+= mmpt.y;
} // DBLRect::operator.

inline void DBLRect::operator -= (const DBLPoint& mmpt)
{
	left	-= mmpt.x;
	top		-= mmpt.y;
	right	-= mmpt.x;
	bottom	-= mmpt.y;
} // DBLRect::operator -=.

inline void DBLRect::operator *= (const DBLPoint& mmpt)
{
	left	*= mmpt.x;
	top		*= mmpt.y;
	right	*= mmpt.x;
	bottom	*= mmpt.y;
} // DBLRect::operator -=.

inline void DBLRect::operator |= (const DBLRect& mmrt)
{
	if (IsRectEmpty())
	{
		left	= mmrt.left;
		top		= mmrt.top;
		right	= mmrt.right;
		bottom	= mmrt.bottom;
	} else
	{
		if (mmrt.left < left) left = mmrt.left;
		if (mmrt.top < top) top = mmrt.top;
		if (right < mmrt.right) right = mmrt.right;
		if (bottom < mmrt.bottom) bottom = mmrt.bottom;
	}
} // DBLRect::operator |=.

inline void DBLRect::operator &= (const DBLRect& mmrt)
{
	if (!LinearOverlap(left, right, left, right, mmrt.left, mmrt.right) ||
		!LinearOverlap(top, bottom, top, bottom, mmrt.top, mmrt.bottom))
		SetRect(0,0,0,0);
} // DBLRect::operator &=.

inline void DBLRect::Extend (double d)
{
	left	-= d;
	top		-= d;
	right	+= d;
	bottom	+= d;
} // DBLRect::Extend.

inline void DBLRect::Extend (double mmX, double mmY)
{
	left	-= mmX;
	top		-= mmY;
	right	+= mmX;
	bottom	+= mmY;
} // DBLRect::Extend.

inline void DBLRect::Reduce (double d)
{
	left	+= d;
	top		+= d;
	right	-= d;
	bottom	-= d;
} // DBLRect::Reduce.

inline DBLRect DBLRect::ExtendRect (double d) const
{
	return DBLRect(left - d, top - d, right + d, bottom + d);
} // DBLRect::ExtendRect.

inline DBLRect DBLRect::ExtendRect (double mmX, double mmY) const
{
	return DBLRect(left - mmX, top - mmY, right + mmX, bottom + mmY);
} // DBLRect::ExtendRect.

inline DBLRect DBLRect::ReduceRect (double d) const
{
	return DBLRect(left + d, top + d, right - d, bottom - d);
} // DBLRect::ReduceRect.

inline DBLRect DBLRect::ReduceRect (double mmX, double mmY) const
{
	return DBLRect(left + mmX, top + mmY, right - mmX, bottom - mmY);
} // DBLRect::ReduceRect.

inline DBLPoint DBLRect::CenterPoint () const
{
	return DBLPoint((left + right) / 2.0, (top + bottom) / 2.0);
} // DBLRect::CenterPoint.

inline void DBLRect::Get4Polygon (DBLPoint mmpta[]) const
{
	mmpta[0].SetPoint(left, top);
	mmpta[1].SetPoint(right, top);
	mmpta[2].SetPoint(right, bottom);
	mmpta[3].SetPoint(left, bottom);
} // DBLRect::Get4Polygon.

inline void DBLRect::Get5Polygon (DBLPoint mmpta[]) const
{
	mmpta[0].SetPoint(left, top);
	mmpta[1].SetPoint(right, top);
	mmpta[2].SetPoint(right, bottom);
	mmpta[3].SetPoint(left, bottom);
	mmpta[4].SetPoint(left, top);
} // DBLRect::Get5Polygon.

inline void DBLRect::Get5Bezier (DBLPoint mmpta[]) const
{
	mmpta[0].SetPoint(left, top);		// A.
	mmpta[1].SetPoint(left, top);		// B.
	mmpta[2].SetPoint(right, top);		// C.
	mmpta[3].SetPoint(right, top);		// A.
	mmpta[4].SetPoint(right, top);		// B.
	mmpta[5].SetPoint(right, bottom);	// C.
	mmpta[6].SetPoint(right, bottom);	// A.
	mmpta[7].SetPoint(right, bottom);	// B.
	mmpta[8].SetPoint(left, bottom);	// C.
	mmpta[9].SetPoint(left, bottom);	// A.
	mmpta[10].SetPoint(left, bottom);	// B.
	mmpta[11].SetPoint(left, top);		// C.
	mmpta[12].SetPoint(left, top);		// D.
} // DBLRect::Get5Bezier.

inline void DBLRect::NormalizeRect ()
{
	double	tmp;
	if (right < left)
	{
		tmp		= left;
		left	= right;
		right	= tmp;
	}
	if (bottom < top)
	{
		tmp		= top;
		top		= bottom;
		bottom	= tmp;
	}
} // DBLRect::NormalizeRect.

inline DBLPoint DBLRect::GetLeftTop () const
{
	return DBLPoint(left, top);
} // DBLRect::GetLeftTop.

inline DBLPoint DBLRect::GetRightBottom () const
{
	return DBLPoint(right, bottom);
} // DBLRect::GetRightBottom.

inline DBLPoint DBLRect::GetRightTop () const
{
	return DBLPoint(right, top);
} // DBLRect::GetRightTop.

inline DBLPoint DBLRect::GetLeftBottom () const
{
	return DBLPoint(left, bottom);
} // DBLRect::GetLeftBottom.

inline DBLRect operator - (const DBLRect& rect)
{
	return DBLRect(-rect.left, -rect.top, -rect.right, -rect.bottom);
} // operator - (const.

inline BOOL operator == (const DBLRect& drt1, const DBLRect& drt2)
{
	return (drt1.left == drt2.left) && (drt1.top == drt2.top) &&
			(drt1.right == drt2.right) && (drt1.bottom == drt2.bottom);
} // operator == (const.

inline BOOL operator != (const DBLRect& drt1, const DBLRect& drt2)
{
	return	(drt1.left   != drt2.left) ||
			(drt1.top    != drt2.top) ||
			(drt1.right  != drt2.right) ||
			(drt1.bottom != drt2.bottom);
} // operator != (const.

inline BOOL operator < (const DBLRect& mmrt1, const DBLRect& mmrt2)
{
	if (mmrt1.left < mmrt2.left) return TRUE;
	if (mmrt1.left > mmrt2.left) return FALSE;
	if (mmrt1.top < mmrt2.top) return TRUE;
	if (mmrt1.top > mmrt2.top) return FALSE;
	if (mmrt1.right < mmrt2.right) return TRUE;
	if (mmrt1.right > mmrt2.right) return FALSE;
	return (mmrt1.bottom < mmrt2.bottom);
} // operator <.

inline BOOL operator < (const DBLRECT& mmrt1, const DBLRECT& mmrt2)
{
	if (mmrt1.left < mmrt2.left) return TRUE;
	if (mmrt1.left > mmrt2.left) return FALSE;
	if (mmrt1.top < mmrt2.top) return TRUE;
	if (mmrt1.top > mmrt2.top) return FALSE;
	if (mmrt1.right < mmrt2.right) return TRUE;
	if (mmrt1.right > mmrt2.right) return FALSE;
	return (mmrt1.bottom < mmrt2.bottom);
} // operator <.

inline DBLRect operator - (const DBLRect& rect, const DBLRect& rect1)
{
	return DBLRect(rect.left - rect1.left, rect.top - rect1.top,
				rect.right - rect1.right, rect.bottom - rect1.bottom);
} // operator - (const.

inline DBLRect operator & (const DBLRect& drt1, const DBLRect& drt2)
{
	DBLRect	drtR;
	if (!LinearOverlap(drtR.left, drtR.right,
				drt1.left, drt1.right, drt2.left, drt2.right))
		return DBLRect(0,0,0,0);
	if (!LinearOverlap(drtR.top, drtR.bottom,
				drt1.top, drt1.bottom, drt2.top, drt2.bottom))
		return DBLRect(0,0,0,0);
	return drtR;
} // operator & (const.

inline DBLRect operator + (const DBLRect& rt, const DBLPoint& pt)
{
	return DBLRect(	rt.left		+ pt.x,
					rt.top		+ pt.y,
					rt.right	+ pt.x,
					rt.bottom	+ pt.y);
} // operator + (const.

inline DBLRect operator + (const DBLPoint& pt, const DBLRect& rt)
{
	return DBLRect(	rt.left		+ pt.x,
					rt.top		+ pt.y,
					rt.right	+ pt.x,
					rt.bottom	+ pt.y);
} // operator + (const.

inline DBLRect operator - (const DBLRect& rt, const DBLPoint& pt)
{
	return DBLRect(	rt.left		- pt.x,
					rt.top		- pt.y,
					rt.right	- pt.x,
					rt.bottom	- pt.y);
} // operator - (const.

inline DBLRect operator - (const DBLPoint& pt, const DBLRect& rt)
{
	return DBLRect(	pt.x - rt.left,
					pt.y - rt.top,
					pt.x - rt.right,
					pt.y - rt.bottom);
} // operator - (const.

inline DBLRect operator * (const DBLRect& rt, const DBLPoint& pt)
{
	return DBLRect(	rt.left		* pt.x,
					rt.top		* pt.y,
					rt.right	* pt.x,
					rt.bottom	* pt.y);
} // operator * (const.

inline DBLRect operator * (const DBLPoint& pt, const DBLRect& rt)
{
	return DBLRect(	pt.x * rt.left,
					pt.y * rt.top,
					pt.x * rt.right,
					pt.y * rt.bottom);
} // operator * (const.

inline DBLRect operator * (const DBLRect& rt, double d)
{
	return DBLRect(	d * rt.left,
					d * rt.top,
					d * rt.right,
					d * rt.bottom);
} // operator * (const.

inline DBLRect operator * (double d, const DBLRect& rt)
{
	return DBLRect(	d * rt.left,
					d * rt.top,
					d * rt.right,
					d * rt.bottom);
} // operator * (double.

inline DBLRect operator / (const DBLRect& rt, const DBLPoint& pt)
{
	return DBLRect(	rt.left		/ pt.x,
					rt.top		/ pt.y,
					rt.right	/ pt.x,
					rt.bottom	/ pt.y);
} // operator / (const.

inline DBLRect operator / (const DBLPoint& pt, const DBLRect& rt)
{
	return DBLRect(	pt.x / rt.left,
					pt.y / rt.top,
					pt.x / rt.right,
					pt.y / rt.bottom);
} // operator / (const.

//----- 00.06.30 Fukushiro M. _xZkqqHx_iNoNiPjMiOgO_xHqqkZx_ ()-----
//#if 0
//inline DBLRect operator & (const DBLRect& drt1, const RECT& rt2)
//{
//	DBLRect	drt2 = rt2;
//	return drt1 & drt2;
//}
//
//inline DBLRect operator & (const RECT& rt1, const DBLRect& drt2)
//{
//	DBLRect	drt1 = rt1;
//	return drt1 & drt2;
//}
//#endif//0
//----- 00.06.30 Fukushiro M. _xZkqqHx_iNoNiPjMiPeJ_xHqqkZx_ ()-----

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	almosteq
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	DBLRect_xZkqqHx_iMfOiCmMiCfBjCgMiCkKiCnJiCmGiCpBiCmHjDjJiClFiCkCiCkJiCmHiCkEiCkJiCpAjFnEiClHiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	drt1, drt2	:_xZkqqHx_jEoEiKhCiClHiCoJiCfBjCgMiCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iCnJiCmGiCpBiCmHjDjJiClFiCkCiPoKiNiHiCmN_xHqqkZx_ TRUE_xZkqqHx_iBeBjDjJiClFiCkNiCmIiCkCiPoKiNiHiCmN_xHqqkZx_ FALSE _xZkqqHx_iCpAjFnEiClHiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	01.08.20 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
inline BOOL almosteq (const DBLRect& drt1, const DBLRect& drt2)
{
	return	almosteq(drt1.left, drt2.left) &&
			almosteq(drt1.top, drt2.top) &&
			almosteq(drt1.right, drt2.right) &&
			almosteq(drt1.bottom, drt2.bottom);
} // almosteq (const DBLRect& drt1, const DBLRect& drt1).

//;----- </EXPORT TO SDK> -----;

#endif//__DBLRect_h
