//
//	Copyright © 2005 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#include "StdAfx.h"
//#include "VWRectangle2D.h"

using namespace VWFC::Math;

VWRectangle2D::VWRectangle2D()
{
	m_bIsEmpty	= true;
}

VWRectangle2D::VWRectangle2D(const VWPoint2D& topleft, const VWPoint2D& botRight)
{
	this->SetRect( topleft, botRight );
}

VWRectangle2D::VWRectangle2D(const VWPoint2D& topleft, double cx, double cy)
{
	this->SetRect( topleft, cx, cy );
}

VWRectangle2D::VWRectangle2D(double left, double right, double top, double bottom)
{
	this->SetRect( left, right, top, bottom );
}

VWRectangle2D::VWRectangle2D(const VWRectangle2D& src)
{
	m_topLeft		= src.m_topLeft;
	m_bottomRight	= src.m_bottomRight;
	m_bIsEmpty		= false;
}

VWRectangle2D::~VWRectangle2D()
{
}

VWRectangle2D& VWRectangle2D::operator=(const VWRectangle2D& src)
{
	m_topLeft		= src.m_topLeft;
	m_bottomRight	= src.m_bottomRight;
	m_bIsEmpty		= src.m_bIsEmpty;
	return *this;
}

void VWRectangle2D::SetRect(const VWPoint2D& topleft, const VWPoint2D& botRight)
{
	m_topLeft		= topleft;
	m_bottomRight	= botRight;
	m_bIsEmpty		= false;
}

void VWRectangle2D::SetRect(const VWPoint2D& topleft, double cx, double cy)
{
	m_topLeft		= topleft;
	m_bottomRight.SetPoint( topleft.x + cx, topleft.y + cy );
	m_bIsEmpty		= false;
}

void VWRectangle2D::SetRect(double left, double right, double top, double bottom)
{
	m_topLeft.x			= left < right ? left : right;
	m_topLeft.y			= top > bottom ? top : bottom;

	m_bottomRight.x		= right > left ? right : left;
	m_bottomRight.y		= bottom < top ? bottom : top;
	m_bIsEmpty		= false;
}

VWPoint2D VWRectangle2D::GetTopLeft() const
{
	return m_topLeft;
}

VWPoint2D VWRectangle2D::GetBottomRight() const
{
	return m_bottomRight;
}

VWPoint2D VWRectangle2D::GetCenter() const
{
	return (m_topLeft + m_bottomRight) / 2;
}

double VWRectangle2D::GetLeft() const
{
	return m_topLeft.x;
}

double VWRectangle2D::GetRight() const
{
	return m_bottomRight.x;
}

double VWRectangle2D::GetTop() const
{
	return m_topLeft.y;
}

double VWRectangle2D::GetBottom() const
{
	return m_bottomRight.y;
}

double VWRectangle2D::GetWidth() const
{
	VWFC_ASSERT( m_bottomRight.x >= m_topLeft.x );
	return m_bottomRight.x - m_topLeft.x;
}

double VWRectangle2D::GetHeight() const
{
	VWFC_ASSERT( m_topLeft.y >= m_bottomRight.y );
	return m_topLeft.y - m_bottomRight.y;
}

bool VWRectangle2D::IsPtInside(double x, double y) const
{
	return
		m_topLeft.x <= x && x <= m_bottomRight.x &&
		m_bottomRight.y <= y && y <= m_topLeft.y;
}

bool VWRectangle2D::IsPtInside(const VWPoint2D& pt) const
{
	return this->IsPtInside( pt.x, pt.y );
}

bool VWRectangle2D::Intersect(const VWRectangle2D& rc) const
{
	bool	bIntersOnX1	=	(m_topLeft.x < rc.m_topLeft.x && rc.m_topLeft.x < m_bottomRight.x) ||
							(m_topLeft.x < rc.m_bottomRight.x && rc.m_bottomRight.x < m_bottomRight.x);
	bool	bIntersOnY1	=	(m_bottomRight.y < rc.m_topLeft.y && rc.m_topLeft.y < m_topLeft.y) ||
							(m_bottomRight.y < rc.m_bottomRight.y && rc.m_bottomRight.y < m_topLeft.y);

	bool	bIntersOnX2	=	(rc.m_topLeft.x < m_topLeft.x && m_topLeft.x < rc.m_bottomRight.x) ||
							(rc.m_topLeft.x < m_bottomRight.x && m_bottomRight.x < rc.m_bottomRight.x);
	bool	bIntersOnY2	=	(rc.m_bottomRight.y < m_topLeft.y && m_topLeft.y < rc.m_topLeft.y) ||
							(rc.m_bottomRight.y < m_bottomRight.y && m_bottomRight.y < rc.m_topLeft.y);

	return	(bIntersOnX1 && bIntersOnY1) ||
			(bIntersOnX2 && bIntersOnY2) ||
			(bIntersOnX1 && bIntersOnY2) ||
			(bIntersOnX2 && bIntersOnY1);
}

void VWRectangle2D::Unite(double x, double y)
{
	if ( m_bIsEmpty ) {
		m_topLeft.x			= x;
		m_topLeft.y			= y;
		m_bottomRight.x		= x;
		m_bottomRight.y		= y;
		m_bIsEmpty			= false;
	}
	else {
		if ( x < m_topLeft.x )		m_topLeft.x			= x;
		if ( y > m_topLeft.y )		m_topLeft.y			= y;
		if ( x > m_bottomRight.x )	m_bottomRight.x		= x;
		if ( y < m_bottomRight.y )	m_bottomRight.y		= y;
	}
}

void VWRectangle2D::Unite(const VWPoint2D& pt)
{
	this->Unite( pt.x, pt.y );
}

void VWRectangle2D::Unite(const VWPolygon2D& poly)
{
	size_t	len		= poly.GetVertexCount();
	for(size_t i=0; i<len; i++) {
		const VWPoint2D&	pt	= poly.GetVertexAt( i );
		this->Unite( pt.x, pt.y );
	}
}

void VWRectangle2D::Unite(const VWRectangle2D& rect)
{
	this->Unite( rect.m_topLeft.x, rect.m_topLeft.y );
	this->Unite( rect.m_bottomRight.x, rect.m_bottomRight.y );
}