note
	description: "[
		Widget to reprensent the "island" ports in VITP.
		Island ports are drawn with a circle and usually has an arrow
		pointing the the `mainland'
		]"
	author: "Jimmy J. Johnson"

deferred class
	ISLAND_PORT_WIDGET

inherit

	PORT_WIDGET
		redefine
			create_interface_objects,
--			initialize,
			build_widgets,
			set_fonts_and_colors,
			position_widgets,
--			defining_figure,
			paint
		end

feature {NONE} -- Initialization

	create_interface_objects
			-- Create the attributes
		do
			Precursor {PORT_WIDGET}
			create arrow_world
			create outer_circle
			create inner_circle
			create outer_arrow
			create inner_arrow
			create masking_box
			create bogus_arrow	-- to be removed later
			extend (outer_circle)
			extend (inner_circle)
			extend (arrow_world)
				-- The `arrow_world' contains the arrows and box
				-- (see `build_circle')
		end

	build_widgets
			-- Now that widgets were created in `create_interface_objects'
			-- and added to Current in `extend_widgets', build up the
			-- widgets by adding internal structure to each widget.
		do
			Precursor {PORT_WIDGET}
			build_circle
		end

	set_fonts_and_colors
			-- Set the default fonts for any text widgets and set
			-- the default colors for any contained widgets.
		do
			Precursor {PORT_WIDGET}
			dot.set_foreground_color (Cyan)
		end

	position_widgets
			-- Move Current and contained widgets to correct
			-- location and set their their sizes
		do
			Precursor {PORT_WIDGET}
				-- Because Current is built big and scaled down,
				-- the font ends up being too small.  Therefore,
				-- the size of the font must be scaled back up to
				-- make it appear the same size as the text on
				-- non-island ports.
			scale_widget (Current, 0.25)
			scale_widget (text_group, 4.0)
--			scale_widget (marker, 4.0)
--			scale_widget (anchor, 4.0)
				-- Center the widgets on x and y.
			text_group.set_x_y (inner_circle.x, inner_circle.y)
			anchor.set_x_y (inner_circle.x, inner_circle.y)
			marker.set_x_y (inner_circle.x, inner_circle.y)
--				-- Green widgets have smaller markers
--			if not is_red then
--				scale_widget (marker, 0.06)
--			end
			if is_red then
				scale_widget (marker, 0.32)
				anchor.scale (0.27)
			else
				scale_widget (marker, 0.25)
			end
		end

--	set_widget_order
--			-- Ensure the widgets are ordered properly
--			-- (i.e. whose on top?)
--		do
--			Precursor {LOCATION_WIDGET}
--		end

	frozen build_circle
			-- Create the circle that represents the port
		do
				-- build the circle big; scale it later
--			rad := 50
				-- Build two circles (and four arrows), placing a
				-- smaller figure inside another corresponding one
				-- to give the appearance of a green/red circle
				-- inside a white circle.
			outer_circle.set_radius1 (50)
			outer_circle.set_radius2 (50)
			inner_circle.set_radius1 (47)
			inner_circle.set_radius2 (47)
				-- center the smaller circle on the larger

				-- Because we may want to rotate the circle, we build it with a
				-- symetrical (arrow going oposite directions) and perform the
				-- rotation on this.  After the rotation the extraneous arrow
				-- is removed.
			arrow_world.extend (outer_arrow)
			arrow_world.extend (inner_arrow)
			arrow_world.extend (masking_box)
			arrow_world.extend (bogus_arrow)
				-- start at point of arrow
			outer_arrow.extend_point (create {EV_COORDINATE}.make (66, 0))
			outer_arrow.extend_point (create {EV_COORDINATE}.make (47, 40))
			outer_arrow.extend_point (create {EV_COORDINATE}.make (47, -40))
			inner_arrow.extend_point (create {EV_COORDINATE}.make (63, 0))
			inner_arrow.extend_point (create {EV_COORDINATE}.make (50, 27))
			inner_arrow.extend_point (create {EV_COORDINATE}.make (50, -27))
			masking_box.extend_point (create {EV_COORDINATE}.make (0, -15))
			masking_box.extend_point (create {EV_COORDINATE}.make (52, -15))
			masking_box.extend_point (create {EV_COORDINATE}.make (52, 15))
			masking_box.extend_point (create {EV_COORDINATE}.make (0, 15))
					-- reflect `outer_arrow' for the `bogus_arrow_1'
			bogus_arrow.extend_point (create {EV_COORDINATE}.make (-66, 0))
			bogus_arrow.extend_point (create {EV_COORDINATE}.make (-47, 40))
			bogus_arrow.extend_point (create {EV_COORDINATE}.make (-47, -40))
				-- rotate the arrow only
			rotate_arrow
			arrow_world.prune_all (bogus_arrow)
				-- Move all the pieces so the center of the circle is more in line
				-- with the way the rest of the game pieces are defined
--			create t.make_zero
--			t.translate (66, 66)
--			outer_circle.transform (t)
--			inner_circle.transform (t)
--			outer_arrow.transform (t)
--			inner_arrow.transform (t)
--			masking_box.transform (t)
--			bogus_arrow.transform (t)
		ensure
			has_circles: has (arrow_world)
			has_outer_circle: has (outer_circle)
			has_inner_circle: has (inner_circle)
		end

--	defining_figure: EV_MODEL
--			-- The figure to be used to determine if other figures
--			-- overlap this one or for capturing mouse events
--		do
--			Result := outer_circle
--		end

feature -- Basic operations

	paint
			-- Color the widgets
		local
			c, cw: EV_COLOR
		do
			Precursor {PORT_WIDGET}
			cw := adjusted_color (White)
			c := adjusted_color (land_color)
			outer_circle.set_background_color (cw)
			outer_circle.set_foreground_color (cw)
			outer_arrow.set_background_color (cw)
			outer_arrow.set_foreground_color (cw)
			inner_circle.set_background_color (c)
			inner_circle.set_foreground_color (c)
			inner_arrow.set_background_color (c)
			inner_arrow.set_foreground_color (c)
			masking_box.set_background_color (c)
			masking_box.set_foreground_color (c)
		end

feature {NONE} -- Implementation

	frozen center_on (ax, ay: INTEGER)
			-- Translate Current so that the `dot' is at position (`ax', `ay')
		local
			t: EV_MODEL_TRANSFORMATION
		do
			create t.make_zero
			t.translate (ax - inner_circle.x, ay - inner_circle.y)
			transform (t)
		end

	frozen hide_arrow
			-- Remove the arrow from Current
		do
			outer_arrow.hide
			inner_arrow.hide
			masking_box.hide
		end

	frozen rotate_arrow
			-- Rotate only the arrow; the circle does not rotate correctly
		do
				-- This rotates around (0, 0), because this is called
				-- before the completed port widget is translated.
--			rotate_widget (outer_arrow, rotation_amount)
--			rotate_widget (inner_arrow, rotation_amount)
--			rotate_widget (masking_box, rotation_amount)
			rotate_widget (arrow_world, rotation_amount)
		end

	rotation_amount: REAL_64
			-- The number of degrees to rotate the `circle' in order to make the
			-- arrow point the correct dirction
		do
			Result := 0
		end

	arrow_world: EV_MODEL_WORLD
			-- Holds the circles and arrows as a group, so
			-- rotations will be relative to center at [0,0].

	outer_circle: EV_MODEL_ELLIPSE
			-- The larger (white) circle representing the `port'

	inner_circle: EV_MODEL_ELLIPSE
			-- The smaller (red/green) circle representing the `port'

	outer_arrow: EV_MODEL_POLYGON
			-- The larger (white) triangle that make an arrow coming out of the `circle'

	inner_arrow: EV_MODEL_POLYGON
			-- The smaller (red/green) triangle that is inside the `outer_triangle'

	masking_box: EV_MODEL_POLYGON
			-- A rectangle that is the same color as the `inner_circle', used to
			-- visually connect the `inner_arrow' to the `inner_circle'.

	bogus_arrow: EV_MODEL_POLYGON
			-- Arrow built on opposite side of circle from
			-- `outer_arrow' in order to keep the `dot' in
			-- the middle of the circle.  It is removed after
			-- the `arrow' is rotated and the `dot' is built.

end
