note
	description: "[
		The Sequence of Play (SOP) in s {VITP_GAME},
		which describes the order of steps in the game and tracks
		which `player' is currently performing actions.
		]"
	author:    "Jimmy J. Johnson"
	date:      "11/11/23"
	copyright: "Copyright (c) 2023, Jimmy J. Johnson"
	license:   "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"

class
	VITP_SEQUENCE_OF_PLAY

inherit

	VITP_ITEM
--	GAME_STEP
--		rename
--			start as step_start,
--			forth as step_forth,
--			is_before as step_is_before,
--			is_after as step_is_after,
--			is_off as step_is_off,
--			index as step_index
		redefine
			make
--			player
		end

create
	make,
	make_nine_turn

feature {NONE} -- Initialization

	make (a_game: VITP_GAME)
			-- Create an instance of an eight-turn game.
			-- (2nd edition rules)
		do
			Precursor {VITP_ITEM} (a_game)
			create turns.make (0)
			create path.make (0)
			turns.extend (create {TURN_1}.make (game))
			turns.extend (create {TURN_2}.make (game))
--			extend (create {VITP_TURN}.make (game))
--			extend (create {VITP_TURN}.make (game))
--			extend (create {VITP_TURN}.make (game))
--			extend (create {VITP_TURN}.make (game))
--			extend (create {VITP_TURN}.make (game))
--			extend (create {VITP_TURN}.make (game))
		ensure then
			correct_turn_count: turns.count = 2
		end

	make_nine_turn (a_game: VITP_GAME)
			-- Create an instance of a nine-turn game.
		do
			make (a_game)
			turns.extend (create {TURN_9}.make (game))
		end

feature -- Access

	name: STRING = "Sequence of Play"
			-- The displayable name of Current

	turn: INTEGER
			-- The number of the current turn in the sequence of play
		do
				-- Search through the `path' for a {TURN_STEP}
			from path.start
			until Result > 0 or else path.after
			loop
				if attached {VITP_TURN} path.item.node as t then
					Result := t.turn
				end
				path.forth
			end
			Result := Result.max (1)
		end

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

	full_name: STRING
			-- The string representation of this step.
		require
			not_off: not is_off
		do
			Result := ""
			from path.start
			until path.exhausted
			loop
				Result := Result + path.item.node.name
				if not path.islast then
					Result := Result + ", "
				end
				path.forth
			end
		end

feature -- Status report

	is_japanese_player: BOOLEAN
			-- Convenience feature
		do
			Result := step.player = {NATIONALITY_CONSTANTS}.Japanese
		end

	is_allied_player: BOOLEAN
			-- Convenience feature
		do
			Result := step.player = {NATIONALITY_CONSTANTS}.Allied
		end

	is_step_executable: BOOLEAN
			-- Does the current step have a command that can be
			-- automatically executed?
		do
			Result := step.is_executable
		end

	is_step_completed: BOOLEAN
			-- Is the current step in a state that allow the player
			-- to advance to the next step?
		do
			Result := step.is_completed
		end

	is_reinforcement_step: BOOLEAN
			-- Is the current step on placing reinforcements?
		do
			Result := attached {JAPANESE_REINFORCEMENT_STEP} step or
					attached {ALLIED_REINFORCEMENT_STEP} step
		end

	is_patrolling_step: BOOLEAN
			-- Is the game at the patrolling step
		do
			Result := attached {JAPANESE_MOVE_PATROLLERS_STEP} step or
					attached {ALLIED_MOVE_PATROLLERS_STEP} step
		end

	is_raiding_step: BOOLEAN
			-- Is the game at the raiding step
		do
			io.put_string (generating_type.name + ".is_raiding_step:  fix me %N")
		end

	is_moving_amphibious_step: BOOLEAN
			-- Is the game at a place where amphibious units can move?
		do
io.put_string (generating_type.name + ".is_moving_amphibious_step:  fix me! %N")

		end

	is_moving_submarine_step: BOOLEAN
			-- Is the game at a step where the submarine can move?
		do
io.put_string (generating_type.name + ".is_moving_submarine_step:  fix me! %N")

		end

feature -- Basic operations

	execute_step_actions
			-- Perform the actions associated with the current step
		require
			is_step_executable: is_step_executable
		do
			step.execute
		end

feature -- Status report

	is_before: BOOLEAN
			-- Is the cursor before Current?
		do
			Result := path.is_empty
		end

	is_after: BOOLEAN
			-- Is the cursor after Current?
		do
			Result := step = turns.last and then step.index > step.count
		end

	is_off: BOOLEAN
			-- Is the cursor before of after?
		do
			Result := is_before or is_after
		end

feature -- Basic operations

	show_path
			-- Display the current path for testing
		do
			from path.start
			until path.exhausted
			loop
				print (path.item.node.name + ":" + path.item.index.out)
				if not path.after then
					print (", ")
				end
				path.forth
			end
			print ("%N")
		end

	start
			-- Move to the first sub-`step' or `is_after'
		local
			tab: VITP_TABLE [ATTACK_UNIT]
			u: ATTACK_UNIT
		do
			from turns.start
			until turns.after
			loop
				turns.item.start
				turns.forth
			end
 			turns.start
			path.wipe_out
			path.extend (turns.first, 1)
			if can_go_down then
				go_down
			end
				-- Put the game in correct starting state
			tab := game.all_attack_units
			from tab.start
			until tab.after
			loop
				u := tab.item_for_iteration
				if u.nationality = {NATIONALITY_CONSTANTS}.Japanese then
					u.set_location (game.Japanese_oa_chart)
				else
					if u.arrival_turn = 1 then
						u.set_location (game.Allied_starting_forces_chart)
					else
						u.set_location (game.Allied_oa_chart)
					end
				end
				tab.forth
			end
		end

	forth
			-- Move to the next step
		require
			not_after: not is_after
		local
			i: INTEGER
			n: like step
		do
			i := index + 1
			n := step

			n.forth
			if n.is_after then
				if can_go_up then
					go_up
				end
			elseif can_go_down then
				go_down
			elseif can_go_right then
				go_right
			else
				check
					is_after: is_after
						-- Because no other direction to go
				end
			end
		end


feature {NONE} -- Implementation

	turns: ARRAYED_LIST [VITP_TURN]
			-- The turns in Current

	path: ARRAYED_LIST [TUPLE [node: like step; index: like index]]
			-- The node-and-index TUPLES through which this `iterator' has taken
			-- to reach a leaf.

	step: GAME_STEP
			-- The node at the end of the current `path'
		do
			Result := path.last.node
		end

	index: INTEGER
			-- The index into the array in `node' to get the next node
			-- (i.e. the index of the edge out of `node')
		do
			Result := path.last.index
		end

	go_up
			--
		require
			not_after: not is_after
			can_go_up: can_go_up
		local
			n: like step
			i: INTEGER
		do
			path.remove_i_th (path.count)
			path.go_i_th (path.count)
--			path.replace ([step, index + 1])
				-- Next line keeps the `step's internal `index' correct
			step.forth
			path.replace ([step, step.index])
			if can_go_down then
				go_down
			else
				go_up
			end
		end

	go_down
			--
		require
			not_after: not is_after
			can_go_down: can_go_down
		local
			n: like step
		do
				-- Keep going down to leaf
			from
			until step.is_empty
			loop
				n := step.i_th (index)
				path.extend ([n, 1])
				if can_go_down then
					go_down
				end
			end
		end

	go_right
			--
		require
			not_after: not is_after
			can_go_right: can_go_right
		do
print ("go_right  ")
		end

	can_go_up: BOOLEAN
			-- Is there a parent node to move up to?
		do
			Result := step.has_parent
		end

	can_go_down: BOOLEAN
			-- Is there a child node at the `index' of current `node'
		local
			s: GAME_STEP
		do
--			Result := index <= step.count
--			s := path.last.node
--			Result :=  not (s.is_off or s.item.is_completed)
			Result := not step.is_off
		end

	can_go_right: BOOLEAN
			-- Is there a sibling branch to the right of this index?
end
