note
	description: "[
		Command for moving groups of ships from the turn card to the board.
		]"
	author: "Jimmy J. Johnson"

class
	REINFORCE_COMMAND

inherit

	VITP_COMMAND
		redefine
			text,
			execute,
			undo,
			is_executable
		end

create
	make

feature {NONE} -- Initialization

	make (a_game: VITP_GAME)
			-- Create an instance
		do
			default_create
			create moves.make
			create repositions.make
			create joins.make
			create rebasings.make
			vitp_game := a_game
			affected_objects.extend (a_game)
		end

feature -- Access

	vitp_game: VITP_GAME
			-- The game in which this command executes.

	text: STRING
			-- Description of the command
		do
			Result := "Reinforce"
		end

feature -- Basic operations

	execute
			-- Perform the action
			-- Multiple ships come on as a task force, multiple LBA come
			-- on together, as do multiple amphibious units.
		local
			sop: VITP_SEQUENCE_OF_PLAY
		do
			Precursor {VITP_COMMAND}
				-- Get the ships
			sop := vitp_game.sequence_of_play
			if sop.player = {NATIONALITY_CONSTANTS}.japanese then
				place_units (vitp_game.arriving_japanese_ships (sop.turn))
				place_units (vitp_game.arriving_japanese_air_units (sop.turn))
				place_units (vitp_game.arriving_japanese_amphibious_units (sop.turn))
				place_units (vitp_game.arriving_japanese_submarines (sop.turn))
			else
				place_units (vitp_game.arriving_allied_ships (sop.turn))
				place_units (vitp_game.arriving_allied_air_units (sop.turn))
				place_units (vitp_game.arriving_allied_amphibious_units (sop.turn))
				place_units (vitp_game.arriving_allied_submarines (sop.turn))
			end
		end

	undo
			-- Reverse the effects of executing the command
		do
			Precursor {VITP_COMMAND}
			from joins.start
			until joins.after
			loop
				joins.item.undo
				joins.forth
			end
			from repositions.start
			until repositions.after
			loop
				repositions.item.undo
				repositions.forth
			end
			from moves.start
			until moves.after
			loop
				moves.item.undo
				moves.forth
			end
		end

feature -- Status report

	is_executable: BOOLEAN
			-- Can the command be executed?
		local
			sop: VITP_SEQUENCE_OF_PLAY
		do
			sop := vitp_game.sequence_of_play
			Result := Precursor {VITP_COMMAND} and
						sop.is_reinforcement_step
		end

	moves: LINKED_LIST [MOVE_COMMAND]
			-- List of commands that move all the reinforcements

	repositions: LINKED_LIST [REPOSITION_COMMAND]
			-- List of commands that change the position of the reinforcements

	rebasings: LINKED_LIST [REBASE_COMMAND]
			-- List of commands that change the `home_port' of the reinforcement

	joins: LINKED_LIST [JOIN_TASK_FORCE_COMMAND]
			-- List of commands that cause units to form a task force

feature {NONE} -- Implementation


	place_units (a_group: VITP_TABLE [ATTACK_UNIT])
			-- Get `a_group' [i.e. a unit type] and place in game
		require
			group_exists: a_group /= Void
		local
			sop: VITP_SEQUENCE_OF_PLAY
			u, u2: ATTACK_UNIT
			tab: VITP_TABLE [ATTACK_UNIT]
			move_com: MOVE_COMMAND
			pos_com: REPOSITION_COMMAND
			rebase_com: REBASE_COMMAND
			join_com: JOIN_TASK_FORCE_COMMAND
			ht: HASH_TABLE [LINKED_LIST [ATTACK_UNIT], LOCATION]	-- units entering given location
			u_list: LINKED_LIST [ATTACK_UNIT]
		do
			sop := vitp_game.sequence_of_play
			create ht.make (100)
			tab := vitp_game.turn_x_units (sop.turn, a_group)
			from tab.start
			until tab.after
			loop
				u := tab.item_for_iteration
				create move_com.make (u, u.arrival_location)
				create pos_com.make (u, u.arrival_position)
				create rebase_com.make (u, u.arrival_port)
				moves.extend (move_com)
				repositions.extend (pos_com)
				rebasings.extend (rebase_com)
				move_com.execute
				pos_com.execute
				rebase_com.execute
				if ht.has (u.arrival_location) then
					check attached {LINKED_LIST [ATTACK_UNIT]} ht.item (u.arrival_location) as otl_list then
						u2 := otl_list.first
						create join_com.make (u, u2, false)
						joins.extend (join_com)
						join_com.execute
					end
				else
					create u_list.make
					u_list.extend (u)
					ht.extend (u_list, u.arrival_location)
				end
				tab.forth
			end
		end

end
