// ManhattenDistance.hpp
//
//     Created on: 15. 03. 2018
//         Author: Jan Uhlik
//    Modified by:
//
// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library

#ifndef ALIB2_MANHATTENDISTANCE_HPP
#define ALIB2_MANHATTENDISTANCE_HPP

#include <cmath>
#include <alib/pair>
#include <functional>

namespace graph {

namespace heuristic {

class ManhattenDistance {
// ---------------------------------------------------------------------------------------------------------------------

 public:

  template<typename TCoordinate>
  static TCoordinate manhattenDistance(const ext::pair<TCoordinate, TCoordinate> &goal,
                                       const ext::pair<TCoordinate, TCoordinate> &node);

// ---------------------------------------------------------------------------------------------------------------------

  template<typename TCoordinate>
  static
  std::function<TCoordinate(const ext::pair<TCoordinate, TCoordinate> &,
                            const ext::pair<TCoordinate, TCoordinate> &)> manhattenDistanceFunction();

// ---------------------------------------------------------------------------------------------------------------------

};

// =====================================================================================================================

template<typename TCoordinate>
TCoordinate ManhattenDistance::manhattenDistance(const ext::pair<TCoordinate, TCoordinate> &goal,
                                                 const ext::pair<TCoordinate, TCoordinate> &node) {
  return std::abs(node.first - goal.first) + std::abs(node.second - goal.second);
}

// ---------------------------------------------------------------------------------------------------------------------

template<typename TCoordinate>
std::function<TCoordinate(const ext::pair<TCoordinate, TCoordinate> &,
                          const ext::pair<TCoordinate, TCoordinate> &)> ManhattenDistance::manhattenDistanceFunction() {
  return (TCoordinate (*)(const ext::pair<TCoordinate, TCoordinate> &,
                          const ext::pair<TCoordinate, TCoordinate> &)) manhattenDistance;
}

// ---------------------------------------------------------------------------------------------------------------------

} // namespace heuristic

} // namespace graph

#endif //ALIB2_MANHATTENDISTANCE_HPP
