note
	description: "[
		Root class for widgets in VITP where `item' represents some {VITP_ITEM}.
		This also has features for aligning a widget with another.
		]"
	author: "Jimmy J. Johnson"

deferred class
	VITP_WIDGET

inherit

--	EV_WIDGET

	JJ_MODEL_WORLD_VIEW
				-- See newgroup message 20398.  Concrete descendants must
				-- re-implement `new_filled_list' (from ARRAYED_LIST) as:
--					new_filled_list (n: INTEGER): like Current
--							-- New list with `n' elements.
--						do
--							create Result.make (n)
--						end
--		undefine
--			new_filled_list
		redefine
			create_interface_objects,
			initialize,
			set_target,
			set_dimming_level,
			target_imp,
			add_actions,
			new_filled_list
				-- Let's try redefining with an empty body; this feature
				-- may be inapplicable anyway.
--		select
--			default_create
		end

--	DIMABLE
--		rename
--			default_create as initialize_dimable
--		redefine
--			set_dimming_level
--		end

	FONT_AND_COLOR_CONSTANTS
		export
			{NONE}
				all
		undefine
			default_create
		end

feature {NONE} -- Initialization

	create_interface_objects
			-- Initialize attributes
		require else
			not_initialized: not is_initialized
		local
			i: INTEGER
			c: EV_COORDINATE
		do
			accept_cursor := Default_accept_cursor
			deny_cursor := Default_accept_cursor
			foreground_color := Black
			create font
			create text_group
			create name_mt
			create dot
			Precursor {JJ_MODEL_WORLD_VIEW}
		end

	frozen initialize
			-- Set up the widgets in Current.
		require else
			not_initialized: not is_initialized
		do
--			set_font (Default_font)
--			initialize_defining_figure
			extend_widgets
			build_widgets
			set_fonts_and_colors
			position_widgets
			set_widget_order
--			add_actions
			dot.set_line_width (10)
				-- The Precursor from {VIEW} calls `add_actions'
			Precursor {JJ_MODEL_WORLD_VIEW}
			set_pebble (target)
			is_initialized := True
		end

	extend_widgets
			-- Put widgets into Current.  This cannot be done
			-- in `create_interface_object', because cannot call
			-- `extend' feature until all objects [in descendants]
			-- are also created.
		do
			extend (dot)
			extend (text_group)
			text_group.extend (name_mt)
				-- Cannot put `jj_defining_figure' in yet, because
				-- descendants may not have finished creation and
				-- `jj_defining_figure' is self-initializing.
--			extend (jj_defining_figure)
		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
		end

	set_fonts_and_colors
			-- Set the default fonts for any text widgets and set
			-- the default colors for any contained widgets.
		do
		end

	position_widgets
			-- Move Current and contained widgets to correct
			-- location and set their sizes
		require
			not_initialized: not is_initialized
		do
				-- Center text on Current
			text_group.set_x_y (x, y)
		end

	set_widget_order
			-- Ensure the widgets are ordered properly
			-- (i.e. whose on top?)
		do
			bring_to_front (text_group)
			bring_to_front (dot)
				-- Next line is okay, I think
			extend (jj_defining_figure)
			bring_to_front (jj_defining_figure)
		end

	add_actions
			-- Add actions to Current
		do
			check not is_view_initialized then
--				pointer_enter_actions.extend (agent on_pointer_enter)
--				pointer_leave_actions.extend (agent on_pointer_leave)
--				pointer_motion_actions.extend (agent on_pointer_motion)
--				pointer_button_press_actions.extend (agent on_button_pressed)
--				pointer_double_press_actions.extend (agent on_pointer_double_pressed)
--				pointer_button_release_actions.extend (agent on_button_released)
--				pointer_motion_actions.extend (agent on_pointer_motion)
--				pointer_enter_actions.extend (agent on_pointer_enter)
--				pointer_leave_actions.extend (agent on_pointer_leave)
			end
			Precursor {JJ_MODEL_WORLD_VIEW}
		end

--	build_bounding_figure
--			-- Add points to the `jj_bounding_figure'.
--			-- The default builds a polygon from the `bounding_box'.
--		require
--			not_initialized: not is_initialized
--		local
--			bb: like bounding_box
--		do
--			jj_bounding_figure.set_point_count (4)
--			bb := bounding_box
--			jj_bounding_figure.set_i_th_point_position (1, bb.lower_left.x, bb.lower_left.y)
--			jj_bounding_figure.set_i_th_point_position (2, bb.upper_left.x, bb.upper_left.y)
--			jj_bounding_figure.set_i_th_point_position (3, bb.upper_right.x, bb.upper_right.y)
--			jj_bounding_figure.set_i_th_point_position (4, bb.lower_right.x, bb.lower_right.y)
--			bring_to_front (jj_bounding_figure)
--			jj_bounding_figure.hide
--			jj_bounding_figure.enable_closed
--		ensure
--			has_enough_points: jj_bounding_figure.point_count >= 1
--			has_bounding_figure: has (jj_bounding_figure)
--		end

	set_initialized
			-- Make `is_initialized'
		do
			is_initialized := true
		end

feature -- Access

	game: VITP_GAME
			-- The game for which this widget provides an interface.
		do
			Result := target.game
		end

	foreground_color: EV_COLOR
			-- Can be used to `paint' contained widgets

--	background_color: EV_COLOR
--			-- Can be used to `paint' contained widgets.
-- defined in EV_MODEL_WORLD

	font: EV_FONT
			-- The base font from which the size, weight, etc
			-- of the fonts for any texts in Current can be based.

	dot: EV_MODEL_DOT
			-- A point on Current used for positioning child widgets

	jj_defining_figure: EV_MODEL_CLOSED
			-- A shape to mark the boundary of Current, used
			-- to determine if widgets overlap or depart an area.
		attribute
			create {EV_MODEL_RECTANGLE} Result.make_with_points (bounding_box.upper_left, bounding_box.lower_right)
			Result.set_line_width (5)
		end

	midpoint: EV_COORDINATE
			-- The point that is the center of the `jj_bounding_figure'
			-- relative to Current's containing group
		local
			p: EV_COORDINATE
			mid: EV_COORDINATE
		do
			p := point_relative
			mid := points_middle (min_values, max_values)
			create Result.make_precise (p.x + mid.x, p.y + mid.y)
		end

feature -- Element change

	set_target (a_item: like target)
			-- Associate `a_item' with Current.
		local
			s, s1, s2: STRING
			pos: INTEGER
		do
			Precursor {JJ_MODEL_WORLD_VIEW} (a_item)
				-- Set text, handling a couple of {PORT} names specially
			if target = game.Pearl_harbor or
				target = game.Johnston_island or
				target = game.New_hebrides or
				target = game.dutch_harbor or
				target = game.Andaman_islands then
						-- split into two lines
				s := target.name
				pos := s.index_of (' ', 1)
				s1 := s.substring (1, pos - 1)
				s2 := s.substring (pos + 1, s.count)
					-- Add spaces to better center text on circles
				if target = game.pearl_harbor or target = game.dutch_harbor then
					s1 := " " + s1
				elseif target = game.johnston_island then
					s2 := "  " + s2
				elseif target = game.new_hebrides then
					s1 := "   " + s1
				elseif target = game.andaman_islands then
					s2 := " " + s2
				end
				name_mt.set_text (s1 + "%N" + s2)
			else
				name_mt.set_text (target.name)
			end
				-- Set the color of and draw the contained widgets
			paint
		end

	set_foreground_color (a_color: EV_COLOR)
			-- Change the color in which the text is drawn
		require
			color_exists: a_color /= Void
		do
			foreground_color := a_color
			paint
		end

--	set_font (a_font: EV_FONT)
--			-- Change the appearance of the `font' from which
--			-- the fonts (height, weight, etc.) of any text
--			-- widgets in Current can be based.
--		do
--			font := a_font
--			name_mt.set_font (font)
--		end

feature -- Basic operations

	set_dimming_level (a_level: INTEGER)
			-- Change the `dimming_level'
		do
			Precursor {JJ_MODEL_WORLD_VIEW} (a_level)
			from start
			until exhausted
			loop
				if attached {VITP_WIDGET} item as v then
--					io.put_string ("   VITP_WIDGET.set_dimming_level - widget is a {" + v.generating_type + "} %N" )
					v.set_dimming_level (a_level)
				end
				forth
			end
			paint
		end

	paint
			-- Set the color of items in this widget and hide/show figures
		do
			if is_defining_figure_shown then
				jj_defining_figure.show
			else
				jj_defining_figure.hide
			end
			name_mt.set_foreground_color (adjusted_color (foreground_color))
		end

--	center_on (a_x, a_y: INTEGER_32)
--			-- Move Current so its center point is on (a_x, a_y).
--		local
--			bb: EV_RECTANGLE
--		do
--			bb := bounding_box
--			set_x_y (a_x - (bb.x + bb.width // 2), a_y - (bb.y + bb.height // 2))
--		end

	center_on_point (a_point: EV_COORDINATE)
			-- Transform Current so its center point is on `a_point'
		require
			point_exists: a_point /= Void
		local
			t: EV_MODEL_TRANSFORMATION
			ax, ay: REAL_64
			bb: EV_RECTANGLE
		do
			bb := bounding_box
			ax := a_point.x_precise - (bb.x + bb.width / 2)
			ay := a_point.y_precise - (bb.y + bb.height / 2)
			create t.make_id
			t.translate (ax, ay)
			transform (t)
		end

	center_on_dot (a_dot: EV_MODEL_DOT)
			-- Place the center of `a_widget' on `a_dot'
		require
			dot_exists: a_dot /= Void
		local
			bb: EV_RECTANGLE
			cx, cy: REAL_64
			dif_x, dif_y: REAL_64
			t: EV_MODEL_TRANSFORMATION
		do
			bb := bounding_box
			cx := bb.width / 2
			cy := bb.height / 2
			dif_x := (bb.x + cx) - a_dot.point.x_precise
			dif_y := (bb.y + cy) - a_dot.point.y_precise
--			dif_x := (bb.x + cx) - dot.point_x
--			dif_y := (bb.y + cy) - dot.point_y
			create t.make_zero
			t.translate (-dif_x, -dif_y)
			transform (t)
		end

	center_on_origin
			-- Place the center of the widget at (0,0)
		local
			t: EV_MODEL_TRANSFORMATION
			ax, ay: REAL_64
			bb: EV_RECTANGLE
		do
			bb := bounding_box
			ax := bb.x + bb.width / 2
			ay := bb.y + bb.height / 2
			create t.make_id
			t.translate (-ax, -ay)
			transform (t)
		end

	center_widget_on_dot (a_widget: EV_MODEL; a_dot: EV_MODEL_DOT)
			-- Place the center of `a_widget' on `a_dot'
		local
			bb: EV_RECTANGLE
			cx, cy: REAL_64
			dif_x, dif_y: REAL_64
			t: EV_MODEL_TRANSFORMATION
		do
			bb := a_widget.bounding_box
			cx := bb.width / 2
			cy := bb.height / 2
			dif_x := (bb.x + cx) - dot.point.x_precise
			dif_y := (bb.y + cy) - dot.point.y_precise
			create t.make_zero
			t.translate (-dif_x, -dif_y)
			a_widget.transform (t)
		end

	center_widget_on_other (a_widget: EV_MODEL; a_other: EV_MODEL)
			-- Place the center of `a_widget' on `a_other'
		local
			bb, bb_other: EV_RECTANGLE
			bb_center_x, bb_center_y: REAL_64
			bb_other_center_x, bb_other_center_y: REAL_64
			cx, cy: REAL_64
			dif_x, dif_y: REAL_64
			t: EV_MODEL_TRANSFORMATION
		do
			bb := a_widget.bounding_box
			bb_other := a_other.bounding_box
			bb_center_x := bb.left + bb.width / 2
			bb_center_y := bb.top + bb.height / 2
			bb_other_center_x := bb_other.left + bb_other.width / 2
			bb_other_center_y := bb_other.top + bb_other.height / 2
			dif_x := bb_other_center_x - bb_center_x
			dif_y := bb_other_center_y - bb_center_y

--			cx := bb.width / 2
--			cy := bb.height / 2
--			dif_x := (bb.x + cx) - dot.point.x_precise
--			dif_y := (bb.y + cy) - dot.point.y_precise
--			dif_x := (bb.x + cx) - a_other.point_array.item (0).x_precise
--			dif_y := (bb.x + cx) - a_other.point_array.item (0).x_precise
			create t.make_zero
			t.translate (dif_x, dif_y)
			a_widget.transform (t)
				-- Check for identical centers
			bb := a_widget.bounding_box
			bb_other := a_other.bounding_box
			bb_center_x := bb.left + bb.width / 2
			bb_center_y := bb.top + bb.height / 2
			bb_other_center_x := bb_other.left + bb_other.width / 2
			bb_other_center_y := bb_other.top + bb_other.height / 2
			dif_x := bb_other_center_x - bb_center_x
			dif_y := bb_other_center_y - bb_center_y
		end

	translate_widget (a_widget: EV_MODEL; a_x, a_y: INTEGER_32)
			-- Move `a_widget' in x and y directions.
		local
			t: EV_MODEL_TRANSFORMATION
		do
			create t.make_zero
			t.translate (a_x, a_y)
--			a_widget.transform (t)
			a_widget.set_x_y (a_widget.x + a_x, a_widget.y + a_y)
		end

	rotate_widget (a_widget: EV_MODEL; a_degrees: REAL_64)
			-- Rotate `a_widget' `a_degrees' clockwise.
		local
			rad: REAL_64
		do
			rad := degrees_to_radians (a_degrees)
			a_widget.rotate (rad)
		end

	scale_widget (a_widget: EV_MODEL; a_scale: REAL_64)
			-- Resize `a_widget' by `a_scale' factor.
		do
			a_widget.scale (a_scale)
		end

	align_midpoints (a_other: VITP_WIDGET)
			-- Move Current so its `midpoint' is over the `midpoint' of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			po: EV_COORDINATE
		do
			po := points_offset (midpoint, a_other.midpoint)
			create t.make_zero
			t.translate (po.x_precise, po.y_precise)
			transform (t)
		end

	align_midpoints_with_offset (a_other: VITP_WIDGET; a_x_offset, a_y_offset: REAL_64)
			-- Move Current so its `midpoint' is offset from the `midpoint'
			-- of `a_other' by the offsets (as percentages of the size of
			-- Current in that direction).
		local
			t: EV_MODEL_TRANSFORMATION
			s: EV_COORDINATE
			xx, yy: REAL_64
		do
			s := a_other.size_values
			align_midpoints (a_other)
			xx := s.x_precise * a_x_offset
			yy := s.y_precise * a_y_offset
			create t.make_zero
			t.translate (xx, yy)
			transform (t)
		end

	align_vertical (a_other: VITP_WIDGET)
			-- Move Current horizontally until it's `midpoint.x' is aligned
			-- with the `midpoint.x' of `a_other'.
		local
			t: EV_MODEL_TRANSFORMATION
			po: EV_COORDINATE
		do
			po := points_offset (midpoint, a_other.midpoint)
			create t.make_zero
			t.translate (po.x_precise, 0.0)
			transform (t)
		end

	align_horizontal (a_other: VITP_WIDGET)
			-- Move Current vertically until it's `midpoint.y' is aligned
			-- with the `midpoint.y' of `a_other'.
		local
			t: EV_MODEL_TRANSFORMATION
			po: EV_COORDINATE
		do
			po := points_offset (midpoint, a_other.midpoint)
			create t.make_zero
			t.translate (0.0, po.y_precise)
			transform (t)
		end

	align_lefts (a_other: VITP_WIDGET)
			-- Move Current so its left side is aligned with
			-- the left side of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			c, o: REAL_64				-- current's value; other's value
		do
			c := min_values.x
			o := a_other.min_values.x
			create t.make_zero
			t.translate (o - c, 0.0)
			transform (t)
		end

	align_rights (a_other: VITP_WIDGET)
			-- Move Current so its right side is aligned with
			-- the right side of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			c, o: REAL_64
		do
			c := max_values.x
			o := a_other.max_values.x
			create t.make_zero
			t.translate (o - c, 0.0)
			transform (t)
		end

	align_tops (a_other: VITP_WIDGET)
			-- Move Current so its top side is aligned with
			-- the top side of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			c, o: REAL_64
		do
			c := max_values.y
			o := a_other.max_values.y
			create t.make_zero
			t.translate (0.0, o - c)
			transform (t)
		end

	align_bottoms (a_other: VITP_WIDGET)
			-- Move Current so its bottom side is aligned with
			-- the bottom side of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			c, o: REAL_64
		do
			c := min_values.y
			o := a_other.min_values.y
			create t.make_zero
			t.translate (o - c, 0.0)
			transform (t)
		end

	align_left_to_others_right (a_other: VITP_WIDGET)
			-- Move Current so its left side is aligned with the
			-- left side of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			o, c: REAL_64
		do
			c := min_values.x
			o := a_other.max_values.x
			create t.make_zero
			t.translate (o - c, 0.0)
			transform (t)
		end

	align_right_to_others_left (a_other: VITP_WIDGET)
			-- Move Current so its right side is aligned with the
			-- left side of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			c, o: REAL_64
		do
			c := max_values.x
			o := a_other.min_values.x
			create t.make_zero
			t.translate (o - c, 0.0)
			transform (t)
		end

	align_top_to_others_bottom (a_other: VITP_WIDGET)
			-- Move Current so its top side is aligned with the
			-- bottom side of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			c, o: REAL_64
		do
			c := min_values.y
			o := a_other.max_values.y
			create t.make_zero
			t.translate (0.0, o - c)
			transform (t)
		end

	align_bottom_to_others_top (a_other: VITP_WIDGET)
			-- Move Current so its top side is aligned with the
			-- bottom side of `a_other'
		local
			t: EV_MODEL_TRANSFORMATION
			c, o: REAL_64
		do
			c := min_values.y
			o := a_other.max_values.y
			create t.make_zero
			t.translate (o - c, 0.0)
			transform (t)
		end

feature -- Actions

--	timer: TIME

--	on_pointer_enter
--			-- React to the mouse pointer entering Current
--		do
--			io.put_string ("VITP_WIDGET.on_enter  " + vitp_item.name + "%N")
--				-- Start timer; after delay with no movement show status dialog

--		end

--	on_pointer_leave
--			-- React to the mouse pointer leaving Current
--		do
--			io.put_string ("VITP_WIDGET.on_leave  " + vitp_item.name + "%N")

--		end

--	on_pointer_motion (ax, ay: INTEGER; ax_tilt, ay_tilt, apressure: DOUBLE;
--				a_screen_x, a_screen_y: INTEGER)
--			-- React to the mouse moving within Current
--		do
--			io.put_string ("VITP_WIDGET.on_move  " + vitp_item.name + "%N")

--		end

feature -- Status report

	is_initialized: BOOLEAN
			-- Has Curent been initialized?  (I.e. all all widgets built?)
			-- Used to prevent calling `initialize' more than once.

	is_defining_figure_shown: BOOLEAN
			-- Can be used by descendants to determine if the `jj_bounding_figure'
			-- should be visible or not.

feature -- Query

	contains_point (a_point: EV_COORDINATE): BOOLEAN
			-- Is `a_point' on or in Current's `jj_defining_figure'?
		local
			pts: SPECIAL [EV_COORDINATE]	-- for convenience
			i, j: INTEGER
		do
--			pts := jj_bounding_figure.point_array
--				-- Remember SPECIAL is zero-based
--			from
--				i := 0
--				j := pts.count - 1
--			until i > pts.count - 1
--			loop
--				if ( ((pts[i].y_precise >= a_point.y_precise) /= (pts[j].y_precise >= a_point.y_precise)) and
--					(a_point.x_precise <= (pts[j].x_precise - pts[i].x_precise) *
--						(a_point.y_precise - pts[i].y_precise) /
--						(pts[j].y_precise - pts[i].y_precise) + pts[i].x_precise) ) then
--					Result := not Result
--				end
--				j := i
--				i := i + 1
--			end
			Result := jj_defining_figure.position_on_figure (a_point.x, a_point.y)
		end

	overlaps (a_other: VITP_WIDGET): BOOLEAN
			-- Does Current occupy any space occupied by a_other
		local
			pts: SPECIAL [EV_COORDINATE]
			i: INTEGER
		do
			if Current /= a_other then
				pts := jj_defining_figure.point_array
					-- Remember SPECIAL is zero-based
				from i := 0
				until i > pts.count - 1 or Result
				loop
					Result := a_other.contains_point (pts[i])
					i := i + 1
				end
					-- Check the other way around
				if not Result then
					pts := a_other.jj_defining_figure.point_array
					from i := 0
					until i > pts.count - 1 or Result
					loop
						Result := contains_point (pts[i])
						i := i + 1
					end
				end
			end
		end

	touches (a_other: VITP_WIDGET): BOOLEAN
			-- Does Current touch `a_other'?
		do

		end

	is_touched_by (a_other: VITP_WIDGET): BOOLEAN
			-- Is Current touched by `a_other'?
		do

		end

	contains (a_other: VITP_WIDGET): BOOLEAN
			-- Does Current contain *all* of `a_other'?
		do

		end

	is_contained_by (a_other: VITP_WIDGET): BOOLEAN
			-- Is *all* of Current within `a_other'?
		do

		end

	diverges_from (a_other: VITP_WIDGET): BOOLEAN
			-- Does Current `intersects' `a_other' while having any
			-- point outside `a_other'
		do

		end

feature {NONE} -- Inapplicable

	new_filled_list (n: INTEGER): like Current
			-- Redefined to get past void-safety issues
		do
			check
				do_not_call: False then
					-- Because this was redefined to appease void-safety, nothing else.
			end
		end

feature -- Actions

	activate_drop_action
			-- Allow Current to react to the drop of a unit, moving
			-- that unit to the `location' in Current.
		do
			drop_actions.extend (drop_unit_agent)
		end

	deactivate_drop_action
			-- Remove the agent added by `activate_drop_actions
		do
			drop_actions.start
			drop_actions.prune (drop_unit_agent)
		end

	frozen drop_unit_agent: PROCEDURE [TUPLE [ATTACK_UNIT]]
			-- Create an agent out of `on_drop_unit' which will be added
			-- to Current when a pick is started and the Sequence of Play
			-- allows for the unit to be dropped here.
		once ("OBJECT")
			Result := agent on_drop_unit
		end

	on_drop_unit (a_unit: ATTACK_UNIT)
			-- Move `a_unit' to `locaiton'
		do
			print ("{LOCATION_WIDGET}.on_drop_unit:  dropped " + a_unit.name + "  on  " + target.name + "%N")
		end

feature {NONE} -- Implementation (actions)

	on_button_pressed (ax: INTEGER; ay: INTEGER; a_button: INTEGER; x_tilt: DOUBLE; y_tilt: DOUBLE;
								pressure: DOUBLE; a_screen_x: INTEGER; a_screen_y: INTEGER)
			-- Notify `board_world' that Current was clicked
			-- This allows the `board_world' to handle the click *and* to know the
			-- widget on which the click occurred.
		do
			io.put_string ("VITP_WIDGET.on_button_pressed   on  " + target.name + "%N")
--			if attached board_world as bw then
--				bw.on_notify_button_pressed (Current, ax, ay, a_button)
--			end
		end

--	on_pointer_double_pressed (ax: INTEGER; ay: INTEGER; a_button: INTEGER; x_tilt: DOUBLE; y_tilt: DOUBLE;
--								pressure: DOUBLE; a_screen_x: INTEGER; a_screen_y: INTEGER)
--			-- Notify `board_world' that Current was double-clicked
--			-- This allows the `board_world' to handle the click *and* to know the
--			-- widget on which the click occurred.
--		do
--			if attached board_world as bw then
--				bw.on_notify_button_double_pressed (Current, ax, ay, a_button)
--			end
--		end

--	on_button_released (ax: INTEGER; ay: INTEGER; a_button: INTEGER; x_tilt: DOUBLE; y_tilt: DOUBLE;
--								pressure: DOUBLE; a_screen_x: INTEGER; a_screen_y: INTEGER)
--			-- Notify `board_world' that `a_button' was released on it
--		do
--			if attached board_world as bw then
--				bw.on_notify_button_released (Current, ax, ay, a_button)
--			end
--		end

--	on_pointer_motion (ax: INTEGER; ay: INTEGER; x_tilt: DOUBLE; y_tilt: DOUBLE;
--								pressure: DOUBLE; a_screen_x: INTEGER; a_screen_y: INTEGER)
--			-- Notify `board_world' that mouse was moved on Current
--		local
--			c: EV_COORDINATE
--		do
--			if attached board_world as bw then
--				bw.on_notify_pointer_motion (Current, ax, ay)
--			end
--		end

--	on_pointer_enter
--			-- React to the mouse entering the `dot'
--		do
--			if attached board_world as bw then
--				bw.on_notify_pointer_enter (Current)
--			end
--		end

--	on_pointer_leave
--			-- React to mouse leaving Current
--		do
--			if attached board_world as bw then
--				bw.on_notify_pointer_leave (Current)
--			end
--		end

feature {VITP_WIDGET} -- Implementation

	vitp_world: detachable WIDGET_FACTORY
			-- The VITP {WIDGET_FACTORY} if any in which Current recursively resides
		do
			if attached {WIDGET_FACTORY} world as w then
				Result := w
			elseif attached {WIDGET_FACTORY} group as w then
				Result := w
			elseif attached {VITP_WIDGET} group as g then
				Result := g.vitp_world
			end
		end

	size_values: EV_COORDINATE
			-- The difference between the min_values and max_values.
			-- The "width" and "height" of the `jj_defining_figure' as a tuple.
		local
			po: EV_COORDINATE
		do
			po := points_offset (max_values, min_values)
			create Result.make_precise (po.x_precise.abs, po.y_precise.abs)
		end

	min_values: EV_COORDINATE
			-- The smallest values of both the x & y coordinates of all
			-- the points in `jj_bounding_figure'
		local
			i: INTEGER
			xx, yy: REAL_64
			c: EV_COORDINATE
			rect: EV_RECTANGLE
		do
--			create c
--			xx := {REAL_64}.Max_value
--			yy := {REAL_64}.Max_value
--			from i := 1
--			until i > jj_bounding_figure.point_count
--			loop
--				c.set_precise (jj_bounding_figure.i_th_point_x (i), jj_bounding_figure.i_th_point_y (i))
--				if c.x_precise < xx then
--					xx := c.x_precise
--				end
--				if c.y_precise < yy then
--					yy := c.y_precise
--				end
--				i := i + 1
--			end
--			create Result.make_precise (xx, yy)
			create Result.make_precise (bounding_box.left, bounding_box.top)
		end

	max_values: EV_COORDINATE
			-- The largest values of both the x & y coordinates of all
			-- the points in `jj_bounding_figure'
		local
			i: INTEGER
			xx, yy: REAL_64
			c: EV_COORDINATE
		do
			create c
--			xx := {REAL_64}.Min_value
--			yy := {REAL_64}.Min_value
--			from i := 1
--			until i > jj_bounding_figure.point_count
--			loop
--				c.set_precise (jj_bounding_figure.i_th_point_x (i), jj_bounding_figure.i_th_point_y (i))
--				if c.x_precise > xx then
--					xx := c.x_precise
--				end
--				if c.y_precise > yy then
--					yy := c.y_precise
--				end
--				i := i + 1
--			end
--			create Result.make_precise (xx, yy)
			create Result.make_precise	 (bounding_box.right, bounding_box.bottom)
		end

	points_middle (a_point, a_other_point: EV_COORDINATE): EV_COORDINATE
			-- The point midway between the two points
		local
			xx, yy: REAL_64
		do
			xx := (a_other_point.x_precise - a_point.x_precise) / 2
			yy := (a_other_point.y_precise - a_point.y_precise) / 2
			create Result.make_precise (xx, yy)
		end

	points_offset (a_point, a_other_point: EV_COORDINATE): EV_COORDINATE
			-- The offset of `a_other_point' from `a_point'
		local
			xx, yy: REAL_64
		do
			xx := a_other_point.x_precise - a_point.x_precise
			yy := a_other_point.y_precise - a_point.y_precise
			create Result.make_precise (xx, yy)
		end

feature {NONE} -- Implementation

	degrees_to_radians (degrees: DOUBLE): DOUBLE
			-- Convert degrees to radians.
			-- Helper function for convienence if need to rotate the widget.
		require
			degrees_big_enough: degrees >= -360
			degrees_small_enough: degrees <= 360
		do
			Result := degrees * Pi / 180
		ensure
--			definition: very_close (Result, degrees * (2 * Pi) / 360)
			result_in_range: Result >= -2 * Pi and Result <= 2 * Pi
		end

feature {VITP_WIDGET} -- Implementation

	name_mt: EV_MODEL_TEXT
			-- The name of the object in Current

	text_group: EV_MODEL_GROUP
			-- Hold any text widgets in Current so they can
			-- be positioned and resized as a group

	target_imp: detachable VITP_ITEM
			-- Detachable implementation of `target' for void safety

invariant

	not_empty: target_imp /= Void


end
