/// @file node.cc
/// @author Joshua Petitt <petitj01@tartarus.uwa.edu.au>
/// @author Stefan Schmitt <sschmitt@ee.uwa.edu.au>
/// @version 1.0
/// @date 2003-07
/// 
/// Implements node.hh

#include "base/node.hh"

namespace EyeMind {

// Explicit instantiation.
template Array<Link, LINK_LIST_SIZE>;


Node& LinkOutputToNode(Link& l, Node& o)
{
	l.out = &o; // set output of Link
	o.inlinks + l;  // add to inlinks of Node
	
	return o; // make chaining possible (like stream)
}


Node& LinkInputToNode(Link& l, Node& i)
{
	l.in = &i; // set input of Link
	i.outlinks + l; // add to outlinks of Node

	return i; // make chaining possible (like stream)
}


Link& NodeOutputToLink(Node& n, Link& o)
{
	n.outlinks + o; // add to outlinks of Node 
	o.in = &n; // set input of Link

	return o; // make chaining possible (like stream)
}


Link& NodeInputToLink(Node& n, Link& i)
{
	n.inlinks + i; // add to inlinks of Node
	i.out = &n; // set output of Link

	return i; // make chaining possible (like stream)
}


Link* DisconnectNodes(Node& s, Node& t)
{
	Link* l;
	
	// iterate through source output Links
	s.outlinks.Begin();
	while ((l = s.outlinks++))
		if (l->out == &t) break; // check for link to target
		
	if (l) // link to target was found in source output Links
	{
		l->Null();
		t.inlinks-*l;
		return s.outlinks-*l;
	}

	return NULL;
}



Node& operator>>(Link& l, Node& o){ return LinkOutputToNode(l,o); }


Node& operator<<(Link& l, Node& i){ return LinkInputToNode(l,i); }


Link& operator>>(Node& n, Link& o){ return NodeOutputToLink(n,o); }


Link& operator<<(Node& n, Link& i){ return NodeInputToLink(n,i); }


Link* operator|(Node& s, Node& t){ return DisconnectNodes(s,t); }


}; // namespace EyeMind

