/*!
 * \file BoundingBox.cpp
 * \brief
 * \author Gapchich Vladislav
 * \date 23/10/11
 */

#include "vislearning/cbaselib/BoundingBox.h"

using namespace OBJREC;
using namespace std;
using namespace NICE;

//! A constructor
BoundingBox::BoundingBox()
{
	top_left_.x = -1;
	top_left_.y = -1;
	bottom_right_.x = -1;
	bottom_right_.y = -1;
	id_ = -1;
    unique_id_ = -1;
}

// A copy-constructor
BoundingBox::BoundingBox(const BoundingBox &copy)
{
	top_left_ = copy.topLeft();
	bottom_right_ = copy.bottomRight();
	id_ = copy.id();
    unique_id_ = copy.unique_id_;
}

//! A desctructor
BoundingBox::BoundingBox::~BoundingBox()
{
	
}

//! Sets top left coordinate of the bounding box
/*!
 * /param[in] aTopLeft should not contain negative data 
 */
void 
BoundingBox::setTopLeft(const CoordT< int > &aTopLeft)
{
	if (aTopLeft.x < 0 || aTopLeft.y < 0) {
		return;
		/* NOTREACHED */
	}
	
	top_left_ = aTopLeft;
}

//! overloaded
/*!
 * \see setTopLeft(const CoordT< int > &aTopLeft)
 */
void 
BoundingBox::setTopLeft(const int &x, const int &y)
{
	if (x < 0 || y < 0) {
		return;
		/* NOTREACHED */
	}
	
	CoordT< int > topLeft(x, y);
	top_left_ = topLeft;
}

//! Sets bottom right coordinate of the bounding box
/*!
 * /param[in] aBottomRight should not contain negative data 
 */
void 
BoundingBox::setBottomRight(const CoordT< int > &aBottomRight)
{
	if (aBottomRight.x < 0 || aBottomRight.y < 0) {
		return;
		/* NOTREACHED */
	}
	
	bottom_right_ = aBottomRight;	
}

//! overloaded
/*!
 * \see setBottomRight(const CoordT< int > &aBottomRight)
 */
void 
BoundingBox::setBottomRight(const int &x, const int &y)
{
	if (x < 0 || y < 0) {
		return;
		/* NOTREACHED */
	}
	
	CoordT< int > bottomRight(x, y);
	bottom_right_ = bottomRight;
}

//!
void
BoundingBox::setWidth(const int &aWidth)
{
	if (aWidth < 0) {
		return;
		/* NOTREACHED */
	}
	
	bottom_right_.x = top_left_.x + aWidth;
}

//!
void
BoundingBox::setHeight(const int &aHeight)
{
	if (aHeight < 0) {
		return;
		/* NOTREACHED */
	}
	
	bottom_right_.y = top_left_.y + aHeight;
}

//! Sets a category ID(label ID) for the bounding box 
/*!
 * /param[in] anID should not be less than zero 
 */
void 
BoundingBox::setID(const int &anID)
{
	if (anID < 0) {
		return;
		/* NOTREACHED */
	}
	id_ = anID;
}

//! returns top left coordinate of the bounding box
CoordT< int > 
BoundingBox::topLeft() const
{
	return top_left_;
}

//! returns bottom right coordinate of the bounding box
CoordT< int > 
BoundingBox::bottomRight() const
{
	return bottom_right_;
}

//!
int
BoundingBox::width()
{
	if (top_left_.x < bottom_right_.x)
		return bottom_right_.x - top_left_.x;
	else
		return -1;
}

//!
int
BoundingBox::height()
{
	if (top_left_.y < bottom_right_.y)
		return bottom_right_.y - top_left_.y;
	else
		return -1;
}

//! returns a category ID of the bounding box
int 
BoundingBox::id() const
{ 
	return id_;
}

//! Checks whether bounding box is valid or not
/*!
 * Member checks if top left and bottom right coordinates are really 
 * so, if category id and coordinates are positive
 * 
 * returns true on success.
 */
bool 
BoundingBox::isValid() const
{
	if (id_ < 0 || 
		top_left_.x < 0 ||
		top_left_.y < 0 ||
		bottom_right_.x < 0 ||
		bottom_right_.y < 0 ||
		bottom_right_.y <= top_left_.y ||
		top_left_.x >= bottom_right_.x)
	{
		return false;
		/* NOTREACHED */
	}
	
	return true;
}

//! swaps top left and bottom right coordinates if they are mixed
void
BoundingBox::validate()
{
	if (bottom_right_.y < top_left_.y ||
		top_left_.x < bottom_right_.x)
	{
		CoordT< int > buffer = top_left_;
		top_left_ = bottom_right_;
		bottom_right_ = buffer;
	}
}

/*
 * 
 */