note
	description: "Eiffel Vision container, Cocoa implementation."
	author: "Daniel Furrer"
	keywords: "container"
	date: "$Date$"
	revision: "$Revision$"

deferred class
	EV_CONTAINER_IMP

inherit
	EV_CONTAINER_I
		undefine
			interface_item
		redefine
			interface,
			propagate_foreground_color,
			propagate_background_color
		end

	EV_WIDGET_IMP
		undefine
			ev_apply_new_size,
			minimum_width,
			minimum_height
		redefine
			initialize,
			interface,
			destroy
		end

	EV_SIZEABLE_CONTAINER_IMP
		redefine
			interface
		end

	PLATFORM

feature {NONE}

	initialize
			-- Show non window widgets.
			-- Initialize default options, colors and sizes.
		do
			create radio_group.make
			initialize_sizeable
			create remove_item_actions
			new_item_actions.extend (agent add_radio_button)
			remove_item_actions.extend (agent remove_radio_button)
			Precursor {EV_WIDGET_IMP}
		end

feature -- Access

	client_width: INTEGER
			-- Width of the client area of container.
			-- Redefined in children.
		do
			Result := width
		end

	client_height: INTEGER
			-- Height of the client area of container
			-- Redefined in children.
		do
			Result := height
		end

	background_pixmap: detachable EV_PIXMAP
			-- the background pixmap

	item_imp: detachable EV_WIDGET_IMP
			-- `item'.`implementation'.
		do
			if attached item as l_item then
				Result ?= l_item.implementation
			end
		end

feature -- Element change

	replace (v: like item)
			-- Replace `item' with `v'.
		deferred

		end

feature -- Status Setting

	connect_radio_grouping (a_container: EV_CONTAINER)
			-- Join radio grouping of `a_container' to `Current'.
		local
			l: like radio_group
			peer: detachable EV_CONTAINER_IMP
		do
			peer ?= a_container.implementation
			check peer /= Void then end
			l := peer.radio_group
			if l /= radio_group then
				from
					l.start
				until
					l.is_empty
				loop
					add_radio_button (l.item.attached_interface)
				end
				peer.set_radio_group (radio_group)
			end
		end

	unconnect_radio_grouping (a_container: EV_CONTAINER)
			-- Removed radio grouping of `a_container' from `Current'.
		local
			l: detachable like radio_group
			peer: detachable EV_CONTAINER_IMP
			r: detachable EV_RADIO_BUTTON_IMP
			original_selected_button: detachable EV_RADIO_BUTTON_IMP
		do
			peer ?= a_container.implementation
			check peer /= Void then end
			l := radio_group
			from
				l.start
			until
				l.off
			loop
				r ?= l.item
				check r /= Void then end
				if r.is_selected then
						-- Store originally selected button,
						-- for selection of necessary button at
						-- end of unmerge, as a button has to
						-- be selected in all groups.
					original_selected_button := r
				end
				if r.parent = a_container then
					if peer.radio_group = radio_group then
							-- Reset radio group, back to
							-- empty.
						peer.reset_radio_group
					end
						-- Remove radio button from radio group
						-- of `Current'.
					l.remove
						-- Link radio group of `r' to match that of `a_container'.
					r.internal_set_radio_group (peer.radio_group)
						-- Add `r' to radio group of `container'.
					peer.radio_group.extend (r)
				else
					l.forth
				end
			end
			if not l.is_empty then
				check
					had_original_selection: original_selected_button /= Void
				end
			end
				-- There was not necessarily a selected item, as
				-- the containers may not contain a radio button.
			if original_selected_button /= Void then
					-- We now select a radio button in the new group,
					-- that does not already have one selected.
				if original_selected_button.parent_imp = peer then
					if has_selected_radio_button then
						select_first_radio_button
					end
				elseif peer.has_radio_button then
					peer.select_first_radio_button
				end
			end
		end

	internal_set_background_pixmap (a_pixmap: EV_PIXMAP)
			-- Set the container background pixmap to `pixmap'.
		do
		end

	set_background_pixmap (a_pixmap: EV_PIXMAP)
			-- Set the container background pixmap to `pixmap'.
		do
		end

	bg_pixmap (p: POINTER): POINTER
		do
		end

	remove_background_pixmap
			-- Make background pixmap Void.
		do
		end

feature -- Basic operations

	propagate_foreground_color
			-- Propagate the current foreground color of the
			-- container to the children.
		do
			--precursor {EV_CONTAINER_PI}

		end

	propagate_background_color
			-- Propagate the current background color of the
			-- container to the children.
		do
			Precursor {EV_CONTAINER_I}
		end

feature -- Command

	destroy
			-- Render `Current' unusable.
		do
--			if interface.prunable then
--				interface.wipe_out
--			end
			Precursor {EV_WIDGET_IMP}
		end

feature -- Event handling

	remove_item_actions: EV_LITE_ACTION_SEQUENCE [TUPLE [EV_WIDGET]]
			-- Actions to be performed before an item is removed.

feature {EV_CONTAINER_IMP} -- Implementation

	radio_group: LINKED_LIST [EV_RADIO_BUTTON_IMP]
			-- Radio items in `Current'.
			-- `Current' shares reference with merged containers.

	is_merged (other: EV_CONTAINER): BOOLEAN
			-- Is `Current' merged with `other'?
		require
			other_not_void: other /= Void
		local
			c_imp: detachable EV_CONTAINER_IMP
		do
			c_imp ?= other.implementation
			check c_imp /= Void then end
			Result := c_imp.radio_group = radio_group
		end

	reset_radio_group
			-- Reset radio group to be an empty
			-- list.
		do
			create radio_group.make
		ensure
			radio_group_exists: radio_group /= Void
			radio_group_empty: radio_group.is_empty
		end


	set_radio_group (rg: like radio_group)
			-- Set `radio_group' by reference. (Merge)
		do
			radio_group := rg
		ensure
			radio_group_set: radio_group = rg
		end

	add_radio_button (w: EV_WIDGET)
			-- Called every time a widget is added to the container.
			--| If `w' is a radio button then we update associated
			--| radio buttons as necessary.
		require
			w_not_void: w /= Void
		do
			if attached {EV_RADIO_BUTTON_IMP} w.implementation as r then
				if not radio_group.is_empty then
					r.set_state ({NS_CELL}.off_state)
				end
				r.set_radio_group (radio_group)
			end
		end

	remove_radio_button (w: EV_WIDGET)
			-- Called every time a widget is removed from the container.
			--| If `w' is a radio button then we update  associated
			--| radio buttons as necessary.
		require
			w_not_void: w /= Void
		do
			if attached {EV_RADIO_BUTTON_IMP} w.implementation as r then
				r.remove_from_radio_group
				r.set_state ({NS_CELL}.on_state)
			end
		end

feature {EV_ANY, EV_ANY_I} -- Implementation

	interface: detachable EV_CONTAINER note option: stable attribute end;
			-- Provides a common user interface to platform dependent
			-- functionality implemented by `Current'

note
	copyright: "Copyright (c) 1984-2014, Eiffel Software and others"
	license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
	source: "[
			Eiffel Software
			5949 Hollister Ave., Goleta, CA 93117 USA
			Telephone 805-685-1006, Fax 805-685-6869
			Website http://www.eiffel.com
			Customer support http://support.eiffel.com
		]"
end -- class EV_CONTAINER_IMP