#include "DefenseArray.h"

DefenseArray::DefenseArray()
{
  clear();
}

DefenseArray::~DefenseArray()
{
}

void DefenseArray::clear()
{
  defensePoints.clear();
  parryWindowWidth=0;
  parryWindowHeight=0;
  windowWidth=0;
  windowHeight=0;
  movingLeft=true;
  travelSpeed=0;
  initialRadius=10;
}

//Parry window is the section the user can click on to deflect projectiles.
void DefenseArray::setParryWindowWidth(int wid)
{
  parryWindowWidth=wid;
}

int DefenseArray::getParryWindowWidth()
{
  return parryWindowWidth;
}

void DefenseArray::setParryWindowHeight(int hei)
{
  parryWindowHeight=hei;
}

int DefenseArray::getParryWindowHeight()
{
  return parryWindowHeight;
}

//assumes the Defense Points move from the right side to the left side.
void DefenseArray::setMovingLeft (bool muv)
{
  movingLeft=muv;
}

bool DefenseArray::getMovingLeft ()
{
  return movingLeft;
}

//window dimensions determine the bounds the DefensePoints can appear in. It also determines the distance the points can exceed to hit the player.
int DefenseArray::getWindowWidth ()
{
  return windowWidth;
}

void DefenseArray::setWindowWidth (int wid)
{
  if (wid <= 0)
    return;

  windowWidth=wid;
}

int DefenseArray::getWindowHeight ()
{
  return windowHeight;
}

void DefenseArray::setWindowHeight (int hei)
{
  if (hei <= 0)
    return;

  windowHeight=hei;
}

//travelSpeed is a global multiplier on the item speed.
FixedInt DefenseArray::getTravelSpeed ()
{
  return travelSpeed;
}

void DefenseArray::setTravelSpeed (FixedInt sped)
{
  travelSpeed=sped;
}

//add DefensePoints
void DefenseArray::addDefensePoint(DefensePoint & dp)
{
  dp.init(SDL_GetTicks());
  defensePoints.push_back(dp);
}

//retrieve locations of a Defense Array.
void DefenseArray::getDefensePointLocations(vector<int> & xLocations, vector<int> & yLocations, vector<int> & radii, vector<int>& indecies)
{
  xLocations.clear(); yLocations.clear(); radii.clear(); indecies.clear();

  //for each point, we apply time timeElapsed, then put its coordinates into the vectors.
  vector <DefensePoint> :: iterator dpIter, dpIterEnd;

  int xTemp, yTemp, index=0;
  FixedInt speedMult=1;

  dpIter=defensePoints.begin();
  dpIterEnd=defensePoints.end();
  index=0;
  while (dpIter!=dpIterEnd)
    {
      //If a DefensePoint shouldn't be on the field, go to the next one.
      if (!dpIter->setPosition(speedMult))
        {
          dpIter++;index++;
          continue;
        }
      xTemp=dpIter->getPositionX();
      yTemp=dpIter->getPositionY();
      //put xTemp and yTemp in a bounding box; 0 < x < windowWidth, 0 < y < windowHeight
      if (xTemp < 0)
        xTemp=0;
      if (xTemp > windowWidth)
        xTemp=windowWidth;

      if (yTemp < 0)
        yTemp=0;
      if (yTemp > windowHeight)
        yTemp=windowHeight;

      xLocations.push_back(xTemp);
      yLocations.push_back(yTemp);
      //radius: HP=1 the circle has radius initialRadius
      //Then we will make the area linearly scale up
      //if A(1) = x^2 * PI, A(t) = (sqrt(t) * x)^2 * PI
      //so radius(1) = x, radius(t) = sqrt(t) * x
      //WAIT integer rounding errors...
      //radius(t)=sqrt(t*x*x)
      radii.push_back(intSqrt(dpIter->getHP()*getInitialRadius()*getInitialRadius()));

      //push back the index this DefensePoint is.
      indecies.push_back(index);
      dpIter++;index++;
    }
}

//initialRadius settings
int DefenseArray::getInitialRadius ()
{
  return initialRadius;
}

void DefenseArray::setInitialRadius (int ir)
{
  initialRadius=ir;
}

//subtract HP from a DefensePoint. If its HP is 0, remove it.
//return 0 if the damage is taken but hp is positive.
//return 1 if the damage is taken but hp is negative and the point is removed.
//return -1 if the index is invalid.
int DefenseArray::removeHPFromDefensePoint (int index, int damage)
{
  if (index<0 || index>=int(defensePoints.size()))
    return -1;

  defensePoints[index].addHP(damage * -1);

  if (defensePoints[index].getHP()>0)
    return 0;

  removeDefensePoint(index);
  return 1;
}

bool DefenseArray::startReversingDefensePoint (int index, int activity)
{
  if (index<0 || index>=int(defensePoints.size()))
    return false;

  defensePoints[index].startReversing (SDL_GetTicks(), activity);
  return true;
}

//removes the DefensePoint.
void DefenseArray::removeDefensePoint(int index)
{
  if (index<0 || index>=int(defensePoints.size()))
    return;

  defensePoints.erase(defensePoints.begin()+index);
}

//gets the number of points in the array.
int DefenseArray::getNumberOfDefensePoints()
{
  return defensePoints.size();
}
