//
// Copyright (c) 2009 Froduald Kabanza and the Université de Sherbrooke.
// Use of this software is permitted for non-commercial research purposes, and
// it may be copied or applied only for that use. All copies must include this
// copyright message.
// 
// This is a research prototype that has not gone through intensive tests and
// is delivered as is. It may still contain bugs. Froduald Kabanza and the
// Université de Sherbrooke disclaim any responsibility for damage that may be
// caused by using it.
//
// Please note that some files were inspired in part by the PDDL4J library:
// http://www.math-info.univ-paris5.fr/~pellier/software/software.php 
//
// Implementation: Simon Chamberland
// Project Manager: Froduald Kabanza
//

#include "stdafx.h"
#include "SimpleGroundAction.h"
#include "../Exp/UnaryFunctions.h"

using namespace planning;

SimpleGroundAction::SimpleGroundAction(const SimpleAction* simpleAction, const Bindings* bindings)
  : m_arguments(boost::transform_iterator<LookupVariableBinding, SimpleAction::argument_iterator>(simpleAction->argumentsBegin(), bindings), 
                boost::transform_iterator<LookupVariableBinding, SimpleAction::argument_iterator>(simpleAction->argumentsEnd(), bindings)), 
    m_simpleAction(simpleAction),
    m_precondition(simpleAction->getPrecondition()->apply(bindings)),
    m_effect(simpleAction->getEffect()->apply(bindings))
{
  m_precondition->acquire(this);
  m_effect->acquire(this);
}

SimpleGroundAction::~SimpleGroundAction()
{
  m_precondition->release(this);
  m_effect->release(this);
}

bool SimpleGroundAction::isApplicable(const IClosedWorld* world) const
{
  return m_precondition->evaluate(world, Bindings::emptyBindings());
}

const IEffect* SimpleGroundAction::getStartEffect() const
{
  return m_effect;
}

void SimpleGroundAction::getDelayedEffects(const IClosedWorld* evaluationWorld, 
                                           std::vector<std::pair<double, const IEffect*>>& delayedEffects) const
{
}

//void SimpleGroundAction::evaluateAtStart(const IClosedWorld* world, ActionContext* context) const
//{
//  // Trivial
//}
//
//bool SimpleGroundAction::evaluateOverAll(const IClosedWorld* world, ActionContext* context) const
//{
//  // Trivial
//  return true;
//}
//
//bool SimpleGroundAction::evaluateAtEnd(const IClosedWorld* world, ActionContext* context) const
//{
//  // Trivial
//  return true;
//}

void SimpleGroundAction::_output(std::ostream& out) const
{
  out << "(" << m_simpleAction->getName();
  for (object_iterator it = m_arguments.begin();
       it != m_arguments.end();
       ++it)
  {
    out << " " << **it;
  }
  out << ")";
}