indexing
	namespace: "candidate"
	cluster: "collection"
	description: "Bidirectional iterator with preorder traversal of tree structures"
	original_author: "Justin Finnerty"
	original_date: "August 2005"
	current_date: "$Date: 2005/09/03 03:08:27 $"
	current_author: "$Author: finnerty $"
	revision: "$Revision: 2.3 $"
	--  $Log: tree_cursor.e,v $
	--  Revision 2.3  2005/09/03 03:08:27  finnerty
	--  Updated to conform to cursors/containers in the GOBO library and
	--  test programs compile with SE and VE.
	--
	--  Revision 2.2  2005/09/03 01:39:46  finnerty
	--  Updated to conform to cursors/containers in the GOBO library
	--
	--  Revision 2.1  2005/09/03 00:51:06  finnerty
	--  renamed tree_cursor to tree_cursor
	--
	--  Revision 2.0  2005/08/26 23:19:46  finnerty
	--  == alpha version ==
	--
	--  Revision 1.1  2005/08/06 12:29:04  finnerty
	--  Iterator for traversing trees in preorder.
	--
class TREE_CURSOR[T_NODE->TREE_NODE]
	-- Bidirectional iterator with preorder traversal of tree structures.
inherit
	BILINEAR_CURSOR[T_NODE]

creation {ANY}
	-- Create an iterator
	make

feature {ANY}
	-- Access
	item: T_NODE
			-- Collection's object at the current position.

	container: T_NODE
			-- Tree collection's root object

feature {ANY}
	-- Status report
	is_first: BOOLEAN is
        -- Is cursor on first item?
		do
			Result := item = container
		end

	is_last: BOOLEAN is
        -- Is cursor on last item? NOTE: This method involves a tree
        -- traversal.
		do
			Result := item = container.last
		end

	before, after, off: BOOLEAN is
			-- True moved passed end in either direction.
		do
			Result := (item = Void)
		ensure then
			Result implies item = Void
		end

	same_position (an_other: like Current): BOOLEAN is
			-- Is current cursor at same position as other?
		do
			Result := an_other.item = item
		end

feature {ANY}
	-- Cursor movement
	back is		
			-- Move iterator backward one.
		local
			l_node: T_NODE
		do
			-- Check to see if at end. 
			if not item.has_parent then
				item := Void
			else
				-- Step cursor
				if item.parent.first_child /= item then
					from
						l_node := item.parent.first_child
					until
						l_node.next_sibling = item
					loop
						l_node := l_node.next_sibling
					end
					item := l_node
					-- Move to bottom of directory with children
					from
					until
						not item.has_children
					loop
						item := item.last_child
					end
				else
					-- Move up the parent tree
					item := item.parent
				end
			end
		end

	finish is
			-- Reset iterator to finish (last) position.
		do
			item := container.last
		end

	forth is
			-- Move iterator forward one.
		do
			-- Step cursor
			if item.has_children then
				-- Move into directory with children
				item := item.first_child
			else
				-- Move up the parent tree and then to sibling
				from
				until
					not item.has_parent or else
					(item.has_sibling and item /= item.parent.last_child)
				loop
					item := item.parent
				end
				if
					item.has_parent and then
					(item.has_sibling and item /= item.parent.last_child)
				 then
					item := item.next_sibling
				else
					item := Void
				end
			end
		end

	go_after, go_before is
			-- Reset iterator to finish (last) position.
		do
			item := Void
		end

	go_to (an_other: like Current) is
		do
			item := an_other.item
		end

	search_forth (a_value: T_NODE) is
		do
			from
			until
				item = a_value or else
				off
			loop
				forth
			end
			if off then
				finish
			end
		end

	search_back (a_value: T_NODE) is
		do
			from
			until
				item = a_value or else
				item = container
			loop
				back
			end
		end

	start is
			-- Reset iterator to start position.
		do
			item := container
		ensure then
			item = container
			not off
			-- after `back', `off' is True
		end

feature {NONE}
	-- creation implementation
	make(a_start_point: T_NODE) is
			-- Make with the given starting point
		require
			a_start_point /= Void
		do
			item := a_start_point
			container := a_start_point.root
		end
invariant
	container /= Void
end -- class TREE_CURSOR

