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

#include "edge.h"
#include "effect.h"
#include "guard.h"
#include "location.h"
#include "process.h"
#include "state.h"

#include <cassert>
#include <ostream>

using namespace std;

Edge::Edge(uint32_t idInProcess, uint32_t idInSystem) : 
    action(NULL),
    type(TAU),
    idInProcess(idInProcess),
    idInSystem(idInSystem), 
    src(NULL),
    dst(NULL),
    effect(NULL),
    guard(NULL)
{}

const Process* Edge::getProcess() const { 
    return src->proc; 
}

Process* Edge::getProcess() { 
    return src->proc; 
}

bool Edge::operator==(const Edge& other) const {
    if (getProcess() != other.getProcess()) {
	return false;
    }
    if (src != other.src || dst != other.dst) {
	return false;
    }
    if (type != other.type) {
	return false;
    } 
    
    if (action != NULL && other.action == NULL) {
	return false;
    }
    if (action == NULL && other.action != NULL) {
	return false;
    }
    if (action && other.action && *action != *other.action) {
	return false;
    }
    if (*effect != *other.effect) {
    	return false;
    }
    if (*guard != *other.guard) {
	return false;
    }
    return true;
}

Edge::~Edge() {
    delete action;
    delete guard;
    delete effect;   
}

void Edge::setAction(Action* action) {    
    if (!action) {
	type = TAU;
    }
    else if (action->isBang) {
	type = BANG; 
    } else {
	type = QUE;
    }
    this->action = action;
}

ostream& Edge::display(ostream& o) const {
    assert(guard);
    o << src->name << " -> " << dst->name << " { ";
    if (!guard->empty()) {
	o << *guard << "; ";
    }
    if (action) {
	o << "sync " << *action << ";";
    } 
    if (!effect->empty()) {
	o << *effect << ";";
    }
    return o << " }"; 
}
