#include "stdafx.h"
#include "SimplePathPrediction.h"

UnitRecord::PredictedPaths SimplePathPrediction::predictFuturePaths(const UnitRecord* unitRecord, int nbFramesAhead)
{
  //const size_t NB_PATHS_TO_GENERATE = 6;

  // TODO: would need to consider obstacles (and self influence)!

  UnitRecord::PredictedPaths predictedPaths;

  if (!unitRecord->getType().isBuilding())
  {
    ////Obtenir un rectangle
    //const unsigned int FPS = 30;
    //const double DIST_PER_FPS = getType().topSpeed() * FPS ;
    //unsigned int height = static_cast<unsigned int>(DIST_PER_FPS * 1.5)+1;
    //unsigned int width = static_cast<unsigned int>(DIST_PER_FPS)+1;

    //const BWAPI::Position TOP_LEFT(width / 2, height - (height / 2));
    //const BWAPI::Position BOTTOM_RIGHT(width / 2, height/2);

    //m_predictedPaths.resize(time);

    ////Generate a some random destinations within this range
    //for(gametime_t currentTime = 0; currentTime<time; ++currentTime)
    //{
    //  const PredictedPath& pos = getPredictedPaths(currentTime);
    //  PredictedPath p;

    //  for(PredictedPath::const_iterator itt = pos.begin(); itt != pos.end(); ++itt)
    //  {
    //    //Create a rectangle of possibility
    //    RectangularLocation loc( (*itt) - TOP_LEFT, (*itt) + BOTTOM_RIGHT);
    //   
    //    for(unsigned int j = 0; j < nbPos; ++j)
    //    {
    //      BWAPI::Position newPos(rand() % height + loc.getTopLeftCorner().x()
    //                            , rand() % width + loc.getTopLeftCorner().y());
    //   
    //      BWAPI::Position direction = (*itt) - newPos ;  
    //      float angle = std::atan2(static_cast<float>(direction.x()), static_cast<float>(direction.y()));

    //      double distance = getPosition().getDistance(newPos);

    //      p.push_back(BWAPI::Position(static_cast<int>(getPosition().x() + distance * std::cos(angle))
    //                                  ,static_cast<int>(getPosition().y() + distance * std::sin(angle))));
    //    }
    //  }
    //  setPredictedPaths(p, currentTime + 1);
    //}


    //
    // 50% probability of straight line ahead, 50% probability uniform from current position
    //

    const int currentFrame = BWAPI::Broodwar->getFrameCount();

    std::pair<UnitRecord::position_const_iterator, UnitRecord::position_const_iterator> lastPositions = unitRecord->getLastPositions();

    // Find previous reference position
    BWAPI::Position previousPos = BWAPI::Positions::None;
    if (lastPositions.first != lastPositions.second)
    {
      if (currentFrame != (lastPositions.second - 1)->first)
        previousPos = (lastPositions.second - 1)->second;
      else if (lastPositions.first != (lastPositions.second - 1))
        previousPos = (lastPositions.second - 2)->second;
    }
    if (previousPos != BWAPI::Positions::None)
    {
      const BWAPI::Position currentPos = unitRecord->getPosition();

      const double angle = atan2(static_cast<double>(currentPos.y() - previousPos.y()), 
                                 static_cast<double>(currentPos.x() - previousPos.x()));
      const double cosAngle = cos(angle);
      const double sinAngle = sin(angle);
      const double distancePerFrame = unitRecord->getType().topSpeed();

      predictedPaths.push_back(std::make_pair(0.5, UnitRecord::PredictedPath(unitRecord)));
      //predictedPaths.resize(1);
      //predictedPaths[0].first = 0.5;
      UnitRecord::PredictedPath& positions = predictedPaths[0].second;
      std::vector<std::pair<int, BWAPI::Position>>& positionsVector = positions.getPositions();
      positionsVector.resize(nbFramesAhead);
      for (int f = 1; f <= nbFramesAhead; ++f)
      {
        positionsVector[f - 1].first = currentFrame + f;
        positionsVector[f - 1].second = BWAPI::Position(static_cast<int>(currentPos.x() + cosAngle * distancePerFrame * f),
                                                        static_cast<int>(currentPos.y() + sinAngle * distancePerFrame * f));
      }
    }
  }
  return predictedPaths;
}