note
	description: "[
		Top abstraction describing a point in the sequence of
		play (SOP) in {VITP_GAME}, possibly containing sub-steps to be
		to be visited in order by {VITP_SEQUENCE_OF_PLAY}.  This class
		describes a tree [and tree nodes] and the `iterator', of
		type {VITP_SEQEUENCE_OF_PLAY} iterates over that tree.
		]"
	author: "Jimmy J. Johnson"


deferred class
	GAME_STEP

feature {NONE} -- Initialization

	make (a_game: VITP_GAME)
			-- Create an instance
		do
			create steps.make (0)
			game := a_game
			is_sequential := true
		ensure
			game_assigned: game = a_game
		end

feature -- Access

	name: STRING
			-- The name of this state
		deferred
		end

	game: VITP_GAME
			-- The game in which this state applies.

	player: like {NATIONALITY_CONSTANTS}.Japanese
			-- The player to which this step applies
		do
			Result := {NATIONALITY_CONSTANTS}.either
		end

	iterator: VITP_SEQUENCE_OF_PLAY
			-- A new iterator for traversing Current and
			-- any sub-steps.
			-- Note: `start' and `forth' from this class traverse
			-- the sub-steps of Current only; the tree of steps is
			-- traversed by the `iterator'.
		do
			Create Result.make (game)
		end

	parent: GAME_STEP
			-- The parent step that holds this step
			-- Only one parent allowed.  (See `extend' and `set_parent'.)
--		require
--			has_parent: has_parent
		do
			if attached parent_imp as p then
				Result := p
			else
				Result := Current
			end
		ensure
			no_parent_implication: not has_parent implies Result = Current
			has_parent_implication: has_parent implies Result /= Current
		end

	leaf_step: GAME_STEP
			-- The uncompleted step of the bottom (i.e. a leaf) of
			-- the tree, or Current if all sub-states `is_complete'.
		do
			if steps.before or steps.after then
				Result := Current
			else
				Result := steps.item.leaf_step
			end
		ensure
			is_before_implication: steps.before implies Result = Current
			is_after_implication: steps.after implies Result = Current
			implication: not (steps.after or steps.before) implies Result = steps.item.leaf_step
		end

feature -- Status report

	is_empty: BOOLEAN
			-- Does Current not contain any sub-states?
		do
			Result := steps.is_empty
		end

	is_sequential: BOOLEAN
			-- Should the `iterator' visit sub-steps in order?

	is_concurrent: BOOLEAN
			-- Should the `iterator' visit sub-steps at the same time?

	is_alternating: BOOLEAN
			-- Should the `iterator' visit sub-steps by alternating
			-- between the Japanese `player' and the Allied `player'?

	is_choice: BOOLEAN
			-- Should the `iterator' visit at least one sub-step

--	is_optional: BOOLEAN
--			-- Should the `iterator' visit 		

feature -- Query

	has_parent: BOOLEAN
			-- Does Current have a parent step?
		do
			Result := attached parent_imp
		end

	has (a_step: GAME_STEP): BOOLEAN
			-- Does Current contain `a_step' as a sub-`steps'?
		do
			Result := steps.has (a_step)
		end

feature -- Basic operations

	show
			-- Display Current for testing
		do
			recursive_show (0)
		end

	recursive_show (a_depth: INTEGER)
			-- Used by show to indent base on level in tree
		local
			i: INTEGER
			c: ARRAYED_LIST_CURSOR
		do
			from i := 1
			until i > a_depth
			loop
				print ("   ")
				i := i + 1
			end
			print ("{" + generating_type.name + "} " + name + "%N")
			if not steps.is_empty then
				c := steps.cursor
				from steps.start
				until steps.after
				loop
					steps.item.recursive_show (a_depth + 1)
					steps.forth
				end
				steps.go_to (c)
			end
		end

	extend (a_step: GAME_STEP)
			-- Make `a_step' a sub-`step' of Current
		require
			not_current: a_step /= Current
			only_current_as_parent: not a_step.has_parent or else
										a_step.parent = Current
			not_already_in_Current: not has (a_step)
		do
			steps.extend (a_step)
			if not a_step.has_parent then
				a_step.set_parent (Current)
			else
				check
					correct_parent: a_step.parent = Current
						-- because of precondition
				end
			end
		ensure
			has_step: has (a_step)
			correct_parent: a_step.parent = Current
		end

feature -- Cursor movement

	start
			-- Move to the first sub-step or `is_after' for Current
			-- and all sub-steps recursively.

		do
				-- Recursively call start on all sub-steps
			from steps.start
			until steps.after
			loop
				steps.item.start
				steps.forth
			end
				-- Set the cursor for Current's `steps' array
			if is_empty then
				steps.finish
				check
					is_before: is_before
						-- because {ARRAYED_LIST}.finish implies "before_if_empty"
				end
			else
				steps.start
				check
					at_start: index = 1
						-- because {ARRAYED_LIST}.start implies "at_first"
				end
			end
		ensure
			is_empty_implication: is_empty implies is_before
			not_empty_implication: not is_empty implies index = 1
		end

	forth
			-- Move to the next sub-step of Current
			-- Note: `start' and `forth' from this class traverse
			-- the sub-steps of Current only; the tree of steps is
			-- traversed by the `iterator'.
		require
			not_after: not is_after
--			is_traversable: is_traversable
		do
			steps.forth
		end

	index: INTEGER
			-- The index of the pointer to the current sub-step
		do
			Result := steps.index
		end

	is_after: BOOLEAN
			-- Is the cursor past this step's last sub-step?
		do
			Result := steps.after
		end

	is_before: BOOLEAN
			-- Is the cursor before this step's first sub-step?
		do
			Result := steps.before
		end

	is_off: BOOLEAN
			-- Is the cursor `is_after' or `is_before'?
		do
			Result := steps.off
		end

	is_completed: BOOLEAN
			-- Are all actions to be accomplished in this
			-- step finished?
		do
--			if is_empty then
--				Result := true
--			else
				Result := not is_empty and then steps.last.is_completed
--			end
		ensure then
--			definition: Result = is_empty or else
--					 (not is_empty and then steps.last.is_completed)
		end

	is_executable: BOOLEAN
			-- Does this step have actions that can be
			-- automatically executed?
		do
		end

	execute
			-- Perform automatic actions such as moving reinforcements
			-- from the SOP Chart to the game board.
		require
			is_executable: is_executable
		do
		end

--	is_traversable: BOOLEAN
--			-- Can the cursor move to the next step in Curren?
--		do
--			Result := is_completed
--		end

feature {GAME_STEP} -- Implementation

	set_parent (a_step: GAME_STEP)
			-- Set `parent'
		require
			not_current: a_step /= Current
			not_has_parent: not has_parent
		do
			parent_imp := a_step
		ensure
			has_parent: has_parent
			correct_parent: parent = a_step
		end

feature {VITP_SEQUENCE_OF_PLAY}

	count: INTEGER
			-- The number of `steps' in Current
		do
			Result := steps.count
		end

	i_th (a_index: INTEGER): GAME_STEP
			-- The `i_th' step in Current
		require
			valid_index: steps.valid_cursor_index (a_index)
		do
			Result := steps.i_th (a_index)
		end

	go_i_th (a_index: INTEGER)
			-- Go to `a_index'th step
		require
			valid_index: steps.valid_cursor_index (a_index)
		do
			steps.go_i_th (a_index)
		end

	steps: ARRAYED_LIST [GAME_STEP]
			-- Sub-steps of Current

feature {NONE} -- Implementation

	parent_imp: detachable GAME_STEP
			-- The parent step, if any, containing Current

invariant

end
