// -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; -*-
////////////////////////////////////////////////////////////////////
//
// $Id: target.cpp 816 2011-09-10 13:19:07Z Sebastian Kupferschmid $
//
////////////////////////////////////////////////////////////////////

#include "guard.h"
#include "location.h"
#include "process.h"
#include "state.h"
#include "target.h"

#include "common/helper.h"
#include "common/message.h"

#include <cassert>
#include <ostream>

using namespace std;

Target::Target() : 
    ConstraintContainer(Expression::TARGET),
    locConstraints(),
    intConstraints()
{}

varset_t Target::readVars() const {
    varset_t result = locConstraints.readVars();
    result += intConstraints.readVars();
    return result;
}

varset_t Target::writeVars() const {
    varset_t result = locConstraints.writeVars();
    result += intConstraints.writeVars();
    return result;
}

void Target::addLocationConstraint(LocationConstraint* lc) {
    locConstraints.add(lc);
}

void Target::addIntConstraint(IntConstraint* ic) {
    intConstraints.add(ic);
}

void Target::eraseConstraint(string varname, vector<const Constraint*>& removed_target_constraints) {
    bool changed = true;
    while (changed) {
	changed = false;
	for (uint32_t i = 0; i < locConstraints.size() && !changed; i++) {
	    if (locConstraints[i]->loc->proc->name == varname) {
		removed_target_constraints.push_back(locConstraints[i]);
		locConstraints.erase(i);
		changed = true;
	    }
	}
    }
    changed = true;
    while (changed) {
	changed = false;
	for (uint32_t i = 0; i < intConstraints.size() && !changed; i++)
	    if (intConstraints[i]->lhs->name == varname) {
		removed_target_constraints.push_back(intConstraints[i]);
		intConstraints.erase(i);
		changed = true;
	    }
    }
}

void Target::addClockConstraint(ClockConstraint*) {
    error() << "clock constraints are NOT allowed in targets" << endl;
}

ostream& Target::display(std::ostream& o) const {
    if (locConstraints.empty()) {
	return o << intConstraints;
    } else {
	return o << locConstraints << " " << intConstraints;
    }
}

