note
	description: "Joystick manager. Not tested. It is most probable that it does not work correctly"
	author: "Louis Marchand"
	date: "May 24, 2012"
	revision: "1.0.0.0"

class 
	GAME_JOYSTICK

inherit
	DISPOSABLE

	GAME_JOYSTICK_EVENTS
		rename
			make as make_events,
			id as index,
			stop as stop_events,
			run as run_events,
			is_running as is_events_running,
			clear as clear_events
		end

	GAME_LIBRARY_SHARED

create {GAME_LIBRARY_CONTROLLER}
	make

feature {NONE} -- Initialization

	make (a_open_index: INTEGER_32)
			-- Initialization for Current using a_open_index when open.
		do
			events_controller := Game_library.events_controller
			open_index := a_open_index
			is_removed := False
			make_events
		end
	
feature -- Access

	index: INTEGER_32
			-- Internal unique identifier of Current
		do
			if is_open then
				Result := instance_id
			else
				Result := -1
			end
		end

	is_removed: BOOLEAN
			-- Current has been removed

	name: STRING_8
			-- Return the Joystick Name.
		require
			not_removed: not is_removed
		local
			l_text_return: C_STRING
		do
			if is_open then
				create l_text_return.make_by_pointer ({GAME_SDL_EXTERNAL}.sdl_joystickname (item))
			else
				create l_text_return.make_by_pointer ({GAME_SDL_EXTERNAL}.sdl_joysticknameforindex (open_index))
			end
			Result := l_text_return.string
		end

	open
			-- Open Current (Allocate internal structure).
		require
			open_joystick_not_open: not is_open
		do
			clear_error
			item := {GAME_SDL_EXTERNAL}.sdl_joystickopen (open_index)
			manage_error_pointer (item, "Error while opening the Joystick.")
		ensure
			is_open_or_error: not has_error implies is_open
		end

	close
			-- Close Current (Free internal structure).
		require
			close_is_open: is_open
		do
			internal_close
		end

	is_open: BOOLEAN
			-- True if the joystick has been opened.
		do
			Result := (not item.is_default_pointer) and then {GAME_SDL_EXTERNAL}.sdl_joystickgetattached (item)
		end

	axes_count: INTEGER_32
			-- Get the number of axes on the joystick.
		require
			get_axes_number_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joysticknumaxes (item)
			manage_error_code (Result, "Error while querying the number of joystick axes.")
		end

	axes_number: INTEGER_32
		obsolete "Use `axes_count' instead"
			-- Get the number of axes on the joystick.
		require
			get_axes_number_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joysticknumaxes (item)
			manage_error_code (Result, "Error while querying the number of joystick axes.")
		end

	axis_value (a_axis_id: INTEGER_32): INTEGER_16
			-- Get the value of the axis identified by a_axis_id.
			-- Note that a_axis_id index start at 0
		require
			get_axis_value_opened: is_open
			not_removed: not is_removed
			get_axis_value_axis_id_valid: a_axis_id < axes_count
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_joystickgetaxis (item, a_axis_id)
		end

	balls_count: INTEGER_32
			-- Return the number of balls on the joystick.
		require
			get_balls_number_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joysticknumballs (item)
			manage_error_code (Result, "Error while querying the number of joystick balls.")
		end

	balls_number: INTEGER_32
		obsolete "Use `balls_count' instead"
			-- Return the number of balls on the joystick.
		require
			get_balls_number_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joysticknumballs (item)
			manage_error_code (Result, "Error while querying the number of joystick balls.")
		end

	ball_change (a_ball_id: INTEGER_32): TUPLE [x_relative: INTEGER_32; y_relative: INTEGER_32]
			-- Return the state of the ball identified by a_ball_id (relative to the last read).
			-- Note that a_ball_id index start at 0
		require
			get_ball_value_opened: is_open
			get_ball_value_ball_id_valid: a_ball_id < axes_count
			not_removed: not is_removed
		local
			l_dx, l_dy, l_error: INTEGER_32
		do
			clear_error
			{GAME_SDL_EXTERNAL}.sdl_joystickupdate
			l_error := {GAME_SDL_EXTERNAL}.sdl_joystickgetball (item, a_ball_id, $l_dx.to_pointer, $l_dy.to_pointer)
			Result := [l_dx, l_dy]
			manage_error_code (l_error, "Error while querying the state change of joystick ball.")
		end

	buttons_count: INTEGER_32
			-- Return the number of buttons on the joystick.
		require
			get_buttons_number_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joysticknumbuttons (item)
			manage_error_code (Result, "Error while querying the number of joystick buttons.")
		end

	buttons_number: INTEGER_32
		obsolete "Use `buttons_count' instead"
			-- Return the number of buttons on the joystick.
		require
			get_buttons_number_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joysticknumbuttons (item)
			manage_error_code (Result, "Error while querying the number of joystick buttons.")
		end

	is_button_pressed (a_button_id: INTEGER_32): BOOLEAN
			-- True if the button identified by a_button_id is pressed, False otherwise
			-- Note that a_button_id index start at 0
		require
			is_buttons_pressed_opened: is_open
			is_button_pressed_button_id_valid: a_button_id < buttons_count
			not_removed: not is_removed
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_joystickgetbutton (item, a_button_id)
		end

	hats_count: INTEGER_32
			-- Return the number of hats on the joystick.
		require
			get_hats_number_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joysticknumhats (item)
			manage_error_code (Result, "Error while querying the number of joystick hats.")
		end

	hats_number: INTEGER_32
		obsolete "Use `hats_count' instead"
			-- Return the number of hats on the joystick.
		require
			get_hats_number_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joysticknumhats (item)
			manage_error_code (Result, "Error while querying the number of joystick hats.")
		end

	hat_state (a_hat_id: INTEGER_32): GAME_JOYSTICK_HAT_STATE
			-- The state of the hat identified by a_hat_id
			-- Note that a_hat_id index start at 0
		require
			get_hat_state_opened: is_open
			not_removed: not is_removed
			get_hat_state_hat_id_valid: a_hat_id < hats_count
		do
			create Result.make ({GAME_SDL_EXTERNAL}.sdl_joystickgethat (item, a_hat_id))
		end

	guid: READABLE_STRING_GENERAL
			-- A unique hardware identifier of Current
		require
			not_removed: not is_removed
		local
			l_string_buffer: POINTER
		do
			l_string_buffer := l_string_buffer.memory_alloc (50)
			if is_open then
				{GAME_SDL_EXTERNAL}.c_sdl_joystickgetguidstring (item, l_string_buffer, 50)
			else
				{GAME_SDL_EXTERNAL}.c_sdl_joystickgetdeviceguidstring (open_index, l_string_buffer, 50)
			end
			Result := (create {C_STRING}.own_from_pointer (l_string_buffer)).string
		end

	instance_id: INTEGER_32
			-- Identifier of Current used in event handeling
		require
			is_buttons_pressed_opened: is_open
			not_removed: not is_removed
		do
			clear_error
			Result := {GAME_SDL_EXTERNAL}.sdl_joystickinstanceid (item)
			manage_error_code (Result, "Error while querying the joystick's instance ID.")
		end

	is_haptic_capable: BOOLEAN
			-- Is Current has haptic features
		require
			is_buttons_pressed_opened: is_open
			not_removed: not is_removed
			is_haptic_enable: Game_library.is_haptic_enable
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_joystickishaptic (item)
			manage_error_code (l_error, "Error while querying if the joystick has haptic functionnalities.")
			Result := l_error = 1
		end

	haptic_controller: GAME_HAPTIC_JOYSTICK
			-- Used to manage the haptic (force feedback) of Current
		require
			is_buttons_pressed_opened: is_open
			not_removed: not is_removed
			is_haptic_capable: is_haptic_capable
			is_haptic_enable: Game_library.is_haptic_enable
		do
			if attached internal_haptic_controller as la_internal_haptic_controller then
				Result := la_internal_haptic_controller
			else
				create Result.make (Current)
				internal_haptic_controller := Result
			end
		end

	events_controller: GAME_EVENTS_CONTROLLER
			-- Used main event manager
	
feature {GAME_SDL_ANY} -- Implementation

	item: POINTER
			-- Point to the internal C structure of Current
	
feature {NONE} -- Implementation

	internal_haptic_controller: detachable GAME_HAPTIC_JOYSTICK
			-- Value of the lazy evaluated attribute haptic_controller

	dispose
			-- <Pecursor>
		do
			if not item.is_default_pointer then
				{GAME_SDL_EXTERNAL}.sdl_joystickclose (item)
			end
		end
	
feature {GAME_LIBRARY_CONTROLLER} -- Implementation

	open_index: INTEGER_32 assign set_open_index
			-- The internal index usedby open

	set_open_index (a_index: INTEGER_32)
			-- Assign a_index to open_index
		do
			open_index := a_index
		ensure
			is_assign: open_index = a_index
		end

	internal_close
			-- Close Current (Free internal structure).
		do
			if attached internal_haptic_controller as la_internal_haptic_controller and then la_internal_haptic_controller.is_open then
				la_internal_haptic_controller.close
			end
			{GAME_SDL_EXTERNAL}.sdl_joystickclose (item)
			create item
		end

	remove
			-- set is_removed to True
		do
			is_removed := True
		ensure
			is_removed_set: is_removed
		end
	
end -- class GAME_JOYSTICK

Generated by ISE EiffelStudio