// -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; -*-
////////////////////////////////////////////////////////////////////
//
// $Id: ffadd.cpp 810 2011-09-03 15:21:54Z Sebastian Kupferschmid $
//
////////////////////////////////////////////////////////////////////

#include "ff_heuristic/ffadd.h"
#include <cassert>

namespace ff {

    using namespace std;

    FFAddHeuristic::FFAddHeuristic(const Task* task, const Options* opts) :
	FFHeuristic(task, opts)
    {}

    void FFAddHeuristic::init() {
	PtrSet<Location>& reached = system->getReachedLocations();
	for (uint32_t i = 0; i < system->getNrLocations(); i++) {
	    Location* loc = system->getLocations()[i];
	    loc->init();
	    if (reached.isMember(loc)) {
		loc->setActivationLevel(0);
	    }
	}
  	const vector<IntegerConstraint*>& constraints = system->getConstraints();
	for (uint32_t i = 0; i < constraints.size(); i++) {
	    constraints[i]->init();
	}
	const vector<Edge*>& edges = system->getEdges();
	for (uint32_t i = 0; i < edges.size(); i++) {
	    edges[i]->init();
	} 
    }
    
    int32_t FFAddHeuristic::compute(const State* state) {
	if (FFHeuristic::compute(state) == INT_MAX) {
	    return INT_MAX;
	}
	
	int32_t result = 0;
	const IntegerGuard& guard = system->getGoal().getGuard();
	for (uint32_t i = 0; i < guard.size(); i++) {
	    assert(guard[i]->getActivationLevel() != -1);
	    result += guard[i]->getActivationLevel();
	}
	
	const vector<Location*>& locations = system->getGoal().getLocations();
	for (uint32_t i = 0; i < locations.size(); i++) {
	    assert(locations[i]->getActivationLevel() != -1);
	    result += locations[i]->getActivationLevel();
	}
		
	return result;
    }
}
