indexing
	namespace: "candidate"
	cluster: "collection"
	description: "This class represents a quadlink_node object. The %
	%linkable notions are up, down and left, right."
	original_author: "Justin Finnerty"
	original_date: "July 2005"
	current_date: "$Date: 2005/08/26 23:19:46 $"
	current_author: "$Author: finnerty $"
	revision: "$Revision: 2.0 $"
	-- $Log: quadlink_node.e,v $
	-- Revision 2.0  2005/08/26 23:19:46  finnerty
	-- == alpha version ==
	--
	-- Revision 1.3  2005/08/05 02:35:24  finnerty
	-- Fiddling to get cvs logging to work
	--
	-- Revision 1.2  2005/08/05 02:25:08  finnerty
	-- Updated documentation and changed access for all methods to {ANY}
	-- 
	-- Revision 1.1  2005/08/04 09:35:38  finnerty
	-- Bi-linkable type that is linkable in two directions (termed vertical and horizontal).
class QUADLINK_NODE
	-- A four-way linkable object.  The linkable notions are `up', `down',
	-- `left' and `right'.

feature {ANY}
	-- Link names

	up, down, left, right: like Current

feature {ANY}
	-- Test for link existance
	
	has_down: BOOLEAN is
			-- Is there a down link?
		do
			Result := (down /= Void)
		ensure
			Result implies down /= Void
			Check_constness: Current.is_equal(old Current)
		end

	has_left: BOOLEAN is
			-- Is there a left link?
		do
			Result := (left /= Void)
		ensure
			Result implies left /= Void
			Check_constness: Current.is_equal(old Current)
		end

	has_right: BOOLEAN is
			-- Is there a right link?
		do
			Result := (right /= Void)
		ensure
			Result implies right /= Void
			Check_constness: Current.is_equal(old Current)
		end

	has_up: BOOLEAN is
			-- Is there an up link?
		do
			Result := (up /= Void)
		ensure
			Result implies up /= Void
			Check_constness: Current.is_equal(old Current)
		end

feature {ANY}
	-- Insert into the linked-lists of nodes.
	
	put_down(a_node: like Current) is
			-- Put into list going up from `a_node'.
		require
			a_node /= Void -- a_node must not be void
			Not_in_list: not has_up
			Not_in_list: not has_down
		do
			down := a_node
			up := a_node.up
			if has_up then
				up.set_down(Current)
			end
			down.set_up(Current)
		ensure
			down = a_node
			a_node.up = Current
			up = old a_node.up
			has_up implies up.down = Current
		end

	put_left(a_node: like Current) is
			-- Put into list going right from `a_node'.
		require
			a_node /= Void -- a_node cannot be void
			Not_in_list: not has_left
			Not_in_list: not has_right
		do
			left := a_node
			right := a_node.right
			if has_right then
				right.set_left(Current)
			end
			left.set_right(Current)
		ensure
			left = a_node
			a_node.right = Current
			right = old a_node.right
			has_right implies right.left = Current 
		end

	put_right(a_node: like Current) is
			-- Put into list going left from `a_node'.
		require
			a_node /= Void -- a_node cannot be void and
			not has_left
			not has_right
		do
			right := a_node
			left := a_node.left
			if has_left then
				left.set_right(Current)
			end
			right.set_left(Current)
		ensure
			right = a_node
			a_node.left = Current
			left = old a_node.left
			has_left implies left.right = Current
		end

	put_up(a_node: like Current) is
			-- Put into list going down from `a_node'.
		require
			No_void_parent: a_node /= Void -- a_node must not be void
			Not_in_list: not has_up
			Not_in_list: not has_down
		do
			up := a_node
			down := a_node.down
			if has_down then
				down.set_up(Current)
			end
			up.set_down(Current)
		ensure
			up = a_node
			a_node.down = Current
			down = old a_node.down
			has_down implies down.up = Current
		end
	
feature {ANY}
	-- Set the value of a link
	
	set_down(a_node: like Current) is
			-- Set down to `a_node' 
		do
			down := a_node
		ensure
			down = a_node
		end
	
	set_left(a_node: like Current) is
			-- Set left `a_node'
		do
			left := a_node
		ensure
			left = a_node
		end

	set_right(a_node: like Current) is
			-- Set right `a_node'.
		do
			right := a_node
		ensure
			right = a_node
		end

	set_up(a_node: like Current) is
			-- Set up to `a_node'.
		do
			up := a_node
		ensure
			up = a_node
		end

feature {ANY}
	-- Remove from linked-lists of nodes

	remove_vertically is
			-- Remove from linked list in vertical direction
		do
			if has_down then
				down.set_up(up)
			end
			if has_up then
				up.set_down(down)
			end
			up := void
			down := Void
		ensure
			not has_up
			not has_down
			-- down = up = Void -- may be redefined in descendents
		end

	remove_horizontally is
			-- Remove from linked list in horizontal direction
		do
			if has_left then
				left.set_right(right)
			end
			if has_right then
				right.set_left(left)
			end
			right := Void
			left := Void
		ensure
			not has_right
			not has_left
			-- left = right = Void -- may be redefined in descendents
		end
end -- class QUADLINK_NODE
