/**
 * \file Circle.cpp
 * \date 9.03.2004
 *
 * Interface for the general world object class
 */

#include "Common/World/Circle.h"
#include "Common/World/Vector.h"


/// \brief Vytvori kruh z pozicie stredu a polomeru
/// \param pos Stred kruhu
/// \param fRadius Polomer kruhu
Circle::Circle(const Point& pos, float fRadius )
{
	Set(pos, fRadius);
}

/// \brief Vytvori kruh na pozicii mimo ihriska a s nulovym polomerom
Circle::Circle()
{
	Set(Point(5000.0,5000.0), 0);
}

/// \brief Nastavi parametre kruhu
/// \param center Stred kruhu
/// \param fRadius Polomer kruhu
void Circle::Set(const Point& center, float fRadius )
{
  	SetCenter(center);
  	SetRadius(fRadius);
}

/// \brief Nastavi polomer kruhu
/// \param fRadius Polomer kruhu
void Circle::SetRadius(float fRadius)
{
	if( fRadius > 0 )
	{
    		radius = fRadius;
     	}
  	else
  	{
    		radius = 0.0;
  	}
}

/// \brief Nastavi stred kruhu
/// \param center Stred kruhu
void Circle::SetCenter(const Point& center)
{
  	posCenter = center;
}

/// \brief Vrati polomer kruhu
/// \return Polomer kruhu
float Circle::GetRadius() const
{
	return radius;
}

/// \brief Vrati stred kruhu
/// \return Stred kruhu
Point Circle::GetCenter() const
{
  	return posCenter;
}

/// \brief Urci ci bod lezi vnutri kruhu
/// \param pos Bod, ktory sa testuje ci je v kruhu
/// \return \li true ak je vnutri kruhu
///			\li false ak je na hrane a mimo kruhu
bool Circle::IsInside(const Point& pos) const
{
  	return ((posCenter-pos).GetLength() < radius) ;
}

/// \brief Urci ci bod lezi vnutri kvadrantu kruhu (polobluku)
/// \param pos Bod, ktory sa testuje
/// \param quadrant Quadrant
/// \return \li true ak je vnutri kruhu
///			\li false ak je na hrane a mimo kruhu
bool Circle::IsInQuadrant(const Point& pos, QUADRANT quadrant) const
{
	bool result = false;
	if (IsInside(pos)){
		switch (quadrant){
		case Q_ATTACK_UP:
			if (pos.GetX()>= posCenter.GetX()  &&
				pos.GetY()<  posCenter.GetY())
				result = true;
			break;
		case Q_ATTACK_DOWN:
			if (pos.GetX()>= posCenter.GetX()  &&
				pos.GetY()>  posCenter.GetY())
				result = true;
			break;
		case Q_DEFEND_UP:
			if (pos.GetX()< posCenter.GetX()  &&
				pos.GetY()<  posCenter.GetY())
				result = true;
			break;
		case Q_DEFEND_DOWN:
			if (pos.GetX()>= posCenter.GetX()  &&
				pos.GetY()>  posCenter.GetY())
				result = true;
			break;
		}
	}
	return result;
}

/// \brief Urci stred daneho kvadrantu
/// \param pos Stred kvadrantu (bod na obluku)
/// \param quadrant Quadrant
void Circle::GetQuadrantCenter(Point& pos, QUADRANT quadrant) const
{
	pos = posCenter;
	Point tmp=pos;
	Vector v;
	v.SetLength(radius);
	switch (quadrant){
	case Q_ATTACK_UP:
		v.SetAngle(Angle(-45));
		break;
	case Q_ATTACK_DOWN:
		v.SetAngle(Angle(45));
		break;
	case Q_DEFEND_UP:
		v.SetAngle(Angle(-135));
		break;
	case Q_DEFEND_DOWN:
		v.SetAngle(Angle(135));
		break;
		}
	pos = pos + v;
}

///	Testovanie
/*
#include <stdio.h>

void main()
{
	Point p;
	Circle c(Point(0.0,0.0), 10.0);
	c.GetQuadrantCenter(p, Q_ATTACK_UP);
	printf("\n%3.2f %3.2f", p.GetX(), p.GetY());
	c.GetQuadrantCenter(p, Q_ATTACK_DOWN);
	printf("\n%3.2f %3.2f", p.GetX(), p.GetY());
	c.GetQuadrantCenter(p, Q_DEFEND_UP);
	printf("\n%3.2f %3.2f", p.GetX(), p.GetY());
	c.GetQuadrantCenter(p, Q_DEFEND_DOWN);
	printf("\n%3.2f %3.2f", p.GetX(), p.GetY());
}

*/

/// \brief Vrati kvadrant, v ktorom je bod
/// \param pos Bod, pre ktory sa urcuje v ktorom kvadrante je
/// \return Vratu kvadrant v ktorom sa bod nachadza
QUADRANT Circle::GetPointQuadrant(Point pos)
{
	if (IsInQuadrant(pos, Q_ATTACK_UP))
		return Q_ATTACK_UP;
	if (IsInQuadrant(pos, Q_ATTACK_DOWN))
		return Q_ATTACK_DOWN;
	if (IsInQuadrant(pos, Q_DEFEND_UP))
		return Q_DEFEND_UP;
	//if (IsInQuadrant(pos, Q_DEFEND_DOWN))
	return Q_DEFEND_DOWN;
}


