#ifndef _UNARY_FUNCTIONS_H
#define _UNARY_FUNCTIONS_H

#include "Bindings.h"

namespace planning
{
  class IClosedWorld;

  template <class EvaluableExpression>
  class EvaluateExpression : public std::unary_function<const EvaluableExpression*,
                                                        typename EvaluableExpression::evaluated_type>
  {
  public:
    EvaluateExpression(const IClosedWorld* world, const Bindings* bindings)
      : m_world(world), m_bindings(bindings)
    {
    }

    typename EvaluableExpression::evaluated_type operator()(const EvaluableExpression* expression) const
    {
      return expression->evaluate(m_world, m_bindings);
    }

  private:
    const IClosedWorld* m_world;
    const Bindings* m_bindings;
  };

  class LookupVariableBinding : public std::unary_function<const ObjectParameterVariable*, const Object*>
  {
  public:
    LookupVariableBinding(const Bindings* bindings)
      : m_bindings(bindings)
    {}

    const Object* operator()(const ObjectParameterVariable* var) const
    {
      return m_bindings->getBinding(var);
    }

  private:
    const Bindings* m_bindings;
  };

  template <class Expression>
  class ApplyBindings : public std::unary_function<const Expression*, const Expression*>
  {
  public:
    ApplyBindings(const Bindings* bindings)
      : m_bindings(bindings)
    {}

    const Expression* operator()(const Expression* exp) const
    {
      return exp->apply(m_bindings);
    }

  private:
    const Bindings* m_bindings;
  };
}

#endif