#include "MoveTransition.hpp"

MoveTransition::MoveTransition(AlterableObject* pAlterableObject, float fDeltaLeft,
  float fDeltaTop, float fDeltaBottom, bool bSlowInSlowOut, int iMoveSteps) {
  iType = MOVE_TRANSITION;
  bStarted = false;
  this->bSlowInSlowOut = bSlowInSlowOut;
  this->pAlterableObject = pAlterableObject;
  this->fDeltaLeft = fDeltaLeft;
  this->fDeltaTop = fDeltaTop;
  this->fDeltaBottom = fDeltaBottom;
  this->iMoveSteps = iMoveSteps;

  iStepsDone = 0;
}

MoveTransition::~MoveTransition() {
  while (vChildren.size() > 0) {
    std::vector<Transition*>::iterator it = vChildren.begin();

    if (it != vChildren.end()) {
      delete *it;
      vChildren.erase(it);
    }
  }

  while (vToBeDeleted.size() > 0) {
    std::vector<AlterableObject*>::iterator it = vToBeDeleted.begin();

    if (it != vToBeDeleted.end()) {
      delete *it;
      vToBeDeleted.erase(it);
    }
  }
}

void MoveTransition::Update() {
  if (!bStarted) {
    Start();
  }

  float fDeltaLeftAbsolute = abs(fDeltaLeft);
  float fDeltaTopAbsolute = abs(fDeltaTop);
  float fDeltaBottomAbsolute = abs(fDeltaBottom);
  float fLeftStep;
  float fTopStep;
  float fBottomStep;

  if (!bSlowInSlowOut) {
    fLeftStep = fDeltaLeftAbsolute / iMoveSteps;
    fTopStep = fDeltaTopAbsolute / iMoveSteps;
    fBottomStep = fDeltaBottomAbsolute / iMoveSteps;
  }
  else {
    //slow-in-slow-out
    if (iMoveSteps == 0) {
      fLeftStep = 0.0f;
      fTopStep = 0.0f;
      fBottomStep = 0.0f;
    }
    else if (iMoveSteps == 2) {
      fLeftStep = fDeltaLeftAbsolute / iMoveSteps;
      fTopStep = fDeltaTopAbsolute / iMoveSteps;
      fBottomStep = fDeltaBottomAbsolute / iMoveSteps;
    }
    else if (iStepsDone < iMoveSteps / 2) {
      fLeftStep = fDeltaLeftAbsolute * (iStepsDone + 1.0f) / (iMoveSteps + (iMoveSteps / 2.0f - 1.0f) * (iMoveSteps / 2.0f - 1.0f) - 1.0f);
      fTopStep = fDeltaTopAbsolute * (iStepsDone + 1.0f) / (iMoveSteps + (iMoveSteps / 2.0f - 1.0f) * (iMoveSteps / 2.0f - 1.0f) - 1.0f);
      fBottomStep = fDeltaBottomAbsolute * (iStepsDone + 1.0f) / (iMoveSteps + (iMoveSteps / 2.0f - 1.0f) * (iMoveSteps / 2.0f - 1.0f) - 1.0f);
    }
    else {
      fLeftStep = fDeltaLeftAbsolute * (iMoveSteps - iStepsDone - 1.0f) / (iMoveSteps + (iMoveSteps / 2.0f - 1.0f) * (iMoveSteps / 2.0f - 1.0f) - 1.0f);
      fTopStep = fDeltaTopAbsolute * (iMoveSteps - iStepsDone - 1.0f) / (iMoveSteps + (iMoveSteps / 2.0f - 1.0f) * (iMoveSteps / 2.0f - 1.0f) - 1.0f);
      fBottomStep = fDeltaBottomAbsolute * (iMoveSteps - iStepsDone - 1.0f) / (iMoveSteps + (iMoveSteps / 2.0f - 1.0f) * (iMoveSteps / 2.0f - 1.0f) - 1.0f);
    }
  }

  if (fDeltaLeft < 0.0f) {
    fLeftStep *= -1.0f;
  }

  if (fDeltaTop < 0.0f) {
    fTopStep *= -1.0f;
  }

  if (fDeltaBottom < 0.0f) {
    fBottomStep *= -1.0f;
  }

  pAlterableObject->ChangePosition(fLeftStep, fTopStep, fBottomStep);
  iStepsDone++;
}

bool MoveTransition::Complete() {
  if ((bStarted) && (iStepsDone >= iMoveSteps)) {
    return true;
  }
  else {
    return false;
  }
}