#include "graph.h"
#include "functionInst.h"

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// ------
// Class variable
// ------

variable::variable(string name_){
	name = name_;

	value = 0;
}

bool CompareVariableName(variable *a, variable *b){
	return a->name < b->name;
}

// ------
// Class registerV
// ------

registerV::registerV(variable *input_, variable *output_){
	input=input_;
	output=output_;

	value=0;
}

void registerV::SaveRegister(){
	value = input->value;
}

void registerV::NextClockEdge(){
	output->value = value;
}

// ------
// Class operation
// ------

operation::operation(unsigned int line_){
	fun = 0;
	line = line_;
}

/**
 * Copy an operation by changing pointer with newVar map
 * Used to copy a combinatorial graph when instanciating a function
 **/
operation::operation(operation *op, map<variable *, variable *> &newVar, unsigned int line_){
    fun = op->fun->Copy();
    line = line_;
    fun->SetOp(this);

    vector<variable *>::iterator it;

    // Copy inputs
    for(it=op->inputs.begin();it!=op->inputs.end();it++){
        variable *input = newVar[*it];
        inputs.push_back(input);
        input->ops.push_back(this);
    }

    // Copy outputs
    for(it=op->outputs.begin();it!=op->outputs.end();it++){
        outputs.push_back(newVar[*it]);
    }
}

operation::~operation(){
	if(fun){
		fun->op = 0;
		delete fun;	// We destroy fun but not the graph associated with fun
	}
}

void operation::AddInput(variable *input){
	inputs.push_back(input);
	input->ops.push_back(this);
}

void operation::AddOutput(variable *output){
	outputs.push_back(output);
}
