#include "noderep.h"
#include "network.h"
#include "dfnode.h"
#include "cgidbg.h"
#include "yacintfc.h"

// void TestAlloc(const char * msg=0);


const char * const NodeReplacement::validate_compare_replace =
	"ValCmpRep" ;
const char * const NodeReplacement::validate_output_replace =
	"ValeOutRep" ;

// The node replacement node is generally a temproary node that should
// be deleted on exit because the network is restored to its original sate.

NodeReplacement::~NodeReplacement()
{
/*
 *	if (replacement_node) LogOut << "NodeReplacement::dtor about to delete:\n`" <<
 *  		replacement_node->GetName() << "'.\n" ;
 */
 
	delete replacement_node ;
	replacement_node = 0 ;
}

void NodeReplacement::dump()
{
	TheLog << " c at " << (void *) current_node << ", r at " <<
		(void *) replacement_node << "\n" ;
	TheLog << "c = `" <<
		( current_node ?  current_node->GetName() : "NULL NODE" ) << "', r = `"
		<< ( replacement_node ?  replacement_node->GetName() : "NULL NODE" )
		<< "'.\n" ;
}

void NodeReplacement::replace(ProcessNet& net)
{
	net.ReplaceNode(*current_node,*replacement_node);
}

void NodeReplacement::relay(NodeReplacementList& nodes_to_replace)
{
	NodeReplacementListIterator Next(nodes_to_replace);
    NodeReplacement * rep ;
    while  (rep = Next()) if (replacement_node == rep->current_node) {
		rep->current_node = 0 ;
		delete replacement_node ;
		replacement_node = rep->replacement_node ;
		rep->replacement_node = 0 ;
		break ;
	}

	if (!rep) State.Error("cannot find replacement for `",
		replacement_node->GetName(), "'");
}

void NodeReplacement::restore(ProcessNet& net)
{
	// LogOut << "NodeReplacement::restore\n" ;
	net.ReplaceNode(*replacement_node,*current_node);
	// LogOut << "NodeReplacement::restore exit\n" ;
}

NodeReplacementList::~NodeReplacementList()
{
	NodeReplacement * rep ;
	while (rep = Get()) {
		if (the_no_delete_flag) rep->no_delete();
		// LogOut << "no_delete_flag = " << the_no_delete_flag << "\n" ;
		// LogOut << (void *) rep << "\n" ;
		delete rep ;
	}
}

void NodeReplacementList::dump()
{
	TheLog << "NodeReplacementList::dump for `" << the_net.GetName() <<
		"', target = `" << the_target_name << "', no_del = " <<
		the_no_delete_flag << "\n" ;
	NodeReplacementListIterator Next(*this);
    NodeReplacement * rep ;
    while  (rep = Next()) {
		TheLog << (void *) rep << "\n" ;
		rep->dump();
	}
}

void NodeReplacementList::relay(NodeReplacementList& nodes_to_replace)
{
	NodeReplacementListIterator Next(*this);
    NodeReplacement * rep ;
    while  (rep = Next()) rep->relay(nodes_to_replace);
}

void NodeReplacementList::replace()
{
	NodeReplacementListIterator Next(*this);
	NodeReplacement * rep ;
	while  (rep = Next()) rep->replace(the_net);
}

void NodeReplacementList::restore()
{
	NodeReplacementListIterator Next(*this);
	NodeReplacement * rep ;
	while  (rep = Next()) rep->restore(the_net);
}

