note
	description: "An haptic device uniquely identified with an index."
	author: "Louis Marchand"
	date: "Mon, 02 Mar 2015 14:20:07 +0000"
	revision: "2.0"

class 
	GAME_HAPTIC_DEVICE

create {GAME_LIBRARY_CONTROLLER}
	make

feature {NONE} -- Initialization

	default_create
			-- Process instances of classes with no creation clause.
			-- (Default: do nothing.)
			-- (from GAME_HAPTIC)
		do
			create {LINKED_LIST [GAME_HAPTIC_EFFECT_COMPILED]} internal_compiled_effect.make
		end

	make (a_index: INTEGER_32)
			-- Initialization of Current using a_index as internal index.
		require
			is_haptic_enabled: Game_library.is_haptic_enable
			is_index_valid: a_index < {GAME_SDL_EXTERNAL}.sdl_numhaptics
			is_haptic_not_already_open: not {GAME_SDL_EXTERNAL}.sdl_hapticopened (a_index)
		do
			default_create
			index := a_index
		end
	
feature -- Access

	close
			-- Make Current not usable
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			{GAME_SDL_EXTERNAL}.sdl_hapticclose (item)
			item := create {POINTER}
		ensure -- from GAME_HAPTIC
			is_close: not is_open
		end

	compile (a_effect: GAME_HAPTIC_EFFECT)
			-- Create a new compiled effect and store it in the compiled_effects
			-- list. You can get ot quicker by using last_compiled_effect
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			current_valid: is_open
			effect_valid: a_effect.exists
			effect_supported: is_effect_supported (a_effect)
		local
			l_effect: GAME_HAPTIC_EFFECT_COMPILED
		do
			clear_error
			create l_effect.make (Current, a_effect)
			if l_effect.is_open then
				internal_compiled_effect.extend (l_effect)
			else
				has_error := True
			end
		ensure -- from GAME_HAPTIC
			is_count_valid: not has_error implies (compiled_effect_count = compiled_effect_count + 1)
			is_count_not_null: not has_error implies (compiled_effect_count > 0)
			last_compiled_valid: not has_error implies (last_compiled_effect.is_open and last_compiled_effect.haptic = Current and last_compiled_effect.effect = a_effect)
		end

	compiled_effect_count: INTEGER_32
			-- Number of compiled_effects in Current
			-- (from GAME_HAPTIC)
		do
			Result := internal_compiled_effect.count
		end

	compiled_effects: CHAIN_INDEXABLE_ITERATOR [GAME_HAPTIC_EFFECT_COMPILED]
			-- Every compiled effect into Current
			-- (from GAME_HAPTIC)
		do
			create Result.make (internal_compiled_effect)
		end

	gain: INTEGER_32 assign set_gain
			-- The intensity of Current
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			gain_control_supported: is_gain_control_supported
		do
			Result := i_gain
		end

	Game_library: GAME_LIBRARY_CONTROLLER
			-- The main controller of the game library
			-- (from GAME_LIBRARY_SHARED)
		once ("PROCESS")
			if attached internal_game_library as la_game_library then
				Result := la_game_library
			else
				create Result
			end
		end

	generating_type: TYPE [detachable GAME_HAPTIC_DEVICE]
			-- Type of current object
			-- (type of which it is a direct instance)
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			generating_type_not_void: Result /= Void
		end

	generator: STRING_8
			-- Name of current object's generating class
			-- (base class of the type of which it is a direct instance)
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			generator_not_void: Result /= Void
			generator_not_empty: not Result.is_empty
		end

	has_error: BOOLEAN
			-- Is the library has generate an error
			-- (from GAME_ERROR_MANAGER)

	initialize_rumble
			-- Initialized a rumble playback into Current
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
			rumble_supported: is_rumble_supported
			not_already_rumble: not is_rumble
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticrumbleinit (item)
			if l_error < 0 then
				manage_error_code (l_error, "Cannot initialize a rumble playback.")
			else
				is_rumble := True
			end
		ensure -- from GAME_HAPTIC
			is_rumble_activated: not has_error implies is_rumble
		end

	last_compiled_effect: GAME_HAPTIC_EFFECT_COMPILED
			-- Last compiled effect that has been compiled with compile
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			element_exist: compiled_effect_count > 0
		do
			Result := internal_compiled_effect.last
		end

	last_error: READABLE_STRING_GENERAL
			-- The last error generate by the library
			-- (from GAME_SDL_ANY)
		local
			l_string: C_STRING
		do
			if is_manual_error then
				Result := Precursor {GAME_ERROR_MANAGER}
			else
				create l_string.make_by_pointer ({GAME_SDL_EXTERNAL}.sdl_geterror)
				Result := l_string.string
			end
		end

	open
			-- Make Current usable
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			not_open: not is_open
		do
			clear_error
			item := internal_open
			manage_error_pointer (item, "Cannot open the haptic device")
			if is_open and then is_gain_control_supported then
				set_gain (100)
			end
		ensure -- from GAME_HAPTIC
			is_open: not has_error implies is_open
		end

	pause
			-- Mommentaly stop the playing effect. Use resume to restart it
			-- where it was when paused.
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
			pause_supported: is_pause_supported
			not_paused: not is_paused
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticpause (item)
			if l_error < 0 then
				manage_error_code (l_error, "Cannot pause the haptic effect.")
			else
				is_paused := True
			end
		ensure -- from GAME_HAPTIC
			is_paused: not has_error implies is_paused
		end

	resume
			-- Restart an effect that has been pause before.
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
			pause_supported: is_pause_supported
			is_paused: is_paused
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticunpause (item)
			if l_error < 0 then
				manage_error_code (l_error, "Cannot resume the effect.")
			else
				is_paused := False
			end
		ensure -- from GAME_HAPTIC
			in_unpaused: not has_error implies not is_paused
		end

	rumble_play (a_strength: REAL_32; a_length: NATURAL_32)
			-- Start a rumble playback with a magnitude of a_strength
			-- and a duration a_length in millisecond
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
			rumble_supported: is_rumble_supported
			is_rumble_device: is_rumble
			strength_is_valid: a_strength >= 0.to_real and a_strength <= 1.to_real
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticrumbleplay (item, a_strength, a_length)
			manage_error_code (l_error, "Cannot playback a rumble.")
		end

	rumble_play_infinite_length (a_strength: REAL_32)
			-- Start a rumble playbacki with a magnitude of a_strength
			-- and never stop (use rumble_stop to stop)
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
			rumble_supported: is_rumble_supported
			is_rumble_device: is_rumble
			strength_is_valid: a_strength >= 0.to_real and a_strength <= 1.to_real
		do
			rumble_play (a_strength, {GAME_SDL_EXTERNAL}.sdl_haptic_infinity)
		end

	rumble_stop
			-- Stop a rumble playback
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
			rumble_supported: is_rumble_supported
			is_rumble_device: is_rumble
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticrumblestop (item)
			manage_error_code (l_error, "Cannot stop a rumble.")
		end

	set_gain (a_gain: INTEGER_32)
			-- Assign to gain the value of a_gain
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
			gain_control_supported: is_gain_control_supported
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticsetgain (item, a_gain)
			if l_error < 0 then
				manage_error_code (l_error, "Cannot set the haptic gain")
			else
				i_gain := a_gain
			end
		ensure -- from GAME_HAPTIC
			is_assign: not has_error implies gain = a_gain
		end

	stop_all_effects
			-- Stop every effect on Current
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticstopall (item)
			manage_error_code (l_error, "Could not stop all effect on haptic.")
		end
	
feature -- Comparison

	frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void
			-- or attached to isomorphic object structures?
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.is_deep_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			shallow_implies_deep: standard_equal (a, b) implies Result
			both_or_none_void: (a = Void) implies (Result = (b = Void))
			same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b))
			symmetric: Result implies deep_equal (b, a)
		end

	frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void or attached
			-- to objects considered equal?
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.is_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b))
		end

	frozen is_deep_equal alias "≡≡≡" (other: GAME_HAPTIC_DEVICE): BOOLEAN
			-- Are Current and other attached to isomorphic object structures?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			shallow_implies_deep: standard_is_equal (other) implies Result
			same_type: Result implies same_type (other)
			symmetric: Result implies other.is_deep_equal (Current)
		end

	is_equal (other: GAME_HAPTIC_DEVICE): BOOLEAN
			-- Is other attached to an object considered
			-- equal to current object?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			symmetric: Result implies other ~ Current
			consistent: standard_is_equal (other) implies Result
		end

	frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void or attached to
			-- field-by-field identical objects of the same type?
			-- Always uses default object comparison criterion.
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.standard_is_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b))
		end

	frozen standard_is_equal alias "" (other: GAME_HAPTIC_DEVICE): BOOLEAN
			-- Is other attached to an object of the same type
			-- as current object, and field-by-field identical to it?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			same_type: Result implies same_type (other)
			symmetric: Result implies other.standard_is_equal (Current)
		end
	
feature -- Status report

	conforms_to (other: ANY): BOOLEAN
			-- Does type of current object conform to type
			-- of other (as per Eiffel: The Language, chapter 13)?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		end

	same_type (other: ANY): BOOLEAN
			-- Is type of current object identical to type of other?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			definition: Result = (conforms_to (other) and other.conforms_to (Current))
		end
	
feature {NONE} -- Status report

	is_in_final_collect: BOOLEAN
			-- Is GC currently performing final collection
			-- after execution of current program?
			-- Safe to use in dispose.
			-- (from DISPOSABLE)
		external
			"C inline use %"eif_memory.h%""
		alias
			"return eif_is_in_final_collect;"
		end
	
feature -- Duplication

	frozen clone (other: detachable ANY): like other
		obsolete "Use `twin' instead. [2017-05-31]"
			-- Void if other is void; otherwise new object
			-- equal to other
			--
			-- For non-void other, clone calls copy;
			-- to change copying/cloning semantics, redefine copy.
			-- (from ANY)
		do
			if other /= Void then
				Result := other.twin
			end
		ensure -- from ANY
			instance_free: class
			equal: Result ~ other
		end

	copy (other: GAME_HAPTIC_DEVICE)
			-- Update current object using fields of object attached
			-- to other, so as to yield equal objects.
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
			type_identity: same_type (other)
		external
			"built_in"
		ensure -- from ANY
			is_equal: Current ~ other
		end

	frozen deep_clone (other: detachable ANY): like other
		obsolete "Use `deep_twin' instead. [2017-05-31]"
			-- Void if other is void: otherwise, new object structure
			-- recursively duplicated from the one attached to other
			-- (from ANY)
		do
			if other /= Void then
				Result := other.deep_twin
			end
		ensure -- from ANY
			instance_free: class
			deep_equal: deep_equal (other, Result)
		end

	frozen deep_copy (other: GAME_HAPTIC_DEVICE)
			-- Effect equivalent to that of:
			--		copy (other . deep_twin)
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		do
			copy (other.deep_twin)
		ensure -- from ANY
			deep_equal: deep_equal (Current, other)
		end

	frozen deep_twin: GAME_HAPTIC_DEVICE
			-- New object structure recursively duplicated from Current.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			deep_twin_not_void: Result /= Void
			deep_equal: deep_equal (Current, Result)
		end

	frozen standard_clone (other: detachable ANY): like other
		obsolete "Use `standard_twin' instead. [2017-05-31]"
			-- Void if other is void; otherwise new object
			-- field-by-field identical to other.
			-- Always uses default copying semantics.
			-- (from ANY)
		do
			if other /= Void then
				Result := other.standard_twin
			end
		ensure -- from ANY
			instance_free: class
			equal: standard_equal (Result, other)
		end

	frozen standard_copy (other: GAME_HAPTIC_DEVICE)
			-- Copy every field of other onto corresponding field
			-- of current object.
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
			type_identity: same_type (other)
		external
			"built_in"
		ensure -- from ANY
			is_standard_equal: standard_is_equal (other)
		end

	frozen standard_twin: GAME_HAPTIC_DEVICE
			-- New object field-by-field identical to other.
			-- Always uses default copying semantics.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			standard_twin_not_void: Result /= Void
			equal: standard_equal (Result, Current)
		end

	frozen twin: GAME_HAPTIC_DEVICE
			-- New object equal to Current
			-- twin calls copy; to change copying/twinning semantics, redefine copy.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			twin_not_void: Result /= Void
			is_equal: Result ~ Current
		end
	
feature -- Basic operations

	frozen as_attached: attached GAME_HAPTIC_DEVICE
		obsolete "Remove calls to this feature. [2017-05-31]"
			-- Attached version of Current.
			-- (Can be used during transitional period to convert
			-- non-void-safe classes to void-safe ones.)
			-- (from ANY)
		do
			Result := Current
		end

	frozen default: detachable GAME_HAPTIC_DEVICE
			-- Default value of object's type
			-- (from ANY)
		do
		end

	frozen default_pointer: POINTER
			-- Default value of type POINTER
			-- (Avoid the need to write p.default for
			-- some p of type POINTER.)
			-- (from ANY)
		do
		ensure -- from ANY
			instance_free: class
		end

	default_rescue
			-- Process exception for routines with no Rescue clause.
			-- (Default: do nothing.)
			-- (from ANY)
		do
		end

	frozen do_nothing
			-- Execute a null action.
			-- (from ANY)
		do
		ensure -- from ANY
			instance_free: class
		end
	
feature {NONE} -- Implementation

	clear_error
			-- Remove error pending in Current
			-- (from GAME_SDL_ANY)
		require -- from  GAME_ERROR_MANAGER
			True
		do
			{GAME_SDL_EXTERNAL}.sdl_clearerror
			Precursor {GAME_ERROR_MANAGER}
			is_manual_error := False
		ensure -- from GAME_ERROR_MANAGER
			no_error: not has_error
		ensure then -- from GAME_SDL_ANY
			no_error: not is_manual_error
		end

	disable_print_on_error
			-- Desactive the print_on_error functionnality.
			-- (from GAME_ERROR_MANAGER)
		do
			Print_on_error_internal.put (False)
		end

	enable_print_on_error
			-- Active the print_on_error functionnality.
			-- (from GAME_ERROR_MANAGER)
		do
			Print_on_error_internal.put (True)
		end

	i_gain: INTEGER_32
			-- Internal value of the gain
			-- (from GAME_HAPTIC)

	internal_compiled_effect: LIST [GAME_HAPTIC_EFFECT_COMPILED]
			-- Every compiled effect into Current
			-- (from GAME_HAPTIC)

	internal_game_library: detachable GAME_LIBRARY_CONTROLLER
			-- Assign to this attribute prior to use Game_library to inject a specific GAME_LIBRARY_CONTROLLER singleton.
			-- (from GAME_LIBRARY_SHARED)

	internal_open: POINTER
			-- The internal C function to open the haptic
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticopen (index)
		end

	is_manual_error: BOOLEAN
			-- Is the current pending error is a manual error (using manual_error as message)
			-- (from GAME_SDL_ANY)

	manage_error_boolean (a_boolean: BOOLEAN; a_message: READABLE_STRING_GENERAL)
			-- Create an error if a_boolean is false.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if not a_boolean then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		ensure -- from GAME_SDL_ANY
				not a_boolean implies has_error
		end

	manage_error_code (a_error_code: INTEGER_32; a_message: READABLE_STRING_GENERAL)
			-- If needed create an error depending of the error code a_code.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if a_error_code < 0 then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		end

	manage_error_pointer (a_pointer: POINTER; a_message: READABLE_STRING_GENERAL)
			-- Create an error if a_pointer is not valid.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if a_pointer.is_default_pointer then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		ensure -- from GAME_SDL_ANY
				a_pointer.is_default_pointer implies has_error
		end

	manual_error: detachable READABLE_STRING_GENERAL
			-- The specific message for the last error
			-- (from GAME_ERROR_MANAGER)

	print_on_error: BOOLEAN
			-- When an error occured, the library will print
			-- informations about the error on the error console
			-- output (default is True).
			-- (from GAME_ERROR_MANAGER)
		do
			Result := Print_on_error_internal.item
		end

	Print_on_error_internal: CELL [BOOLEAN]
			-- True when an error occured,
			-- The library will print it right away.
			-- (from GAME_ERROR_MANAGER)
		once ("PROCESS")
			create Result.put (True)
		end

	put_manual_error (a_general_message, a_specific_error: READABLE_STRING_GENERAL)
			-- Create an error using a_general_error for the debug information
			-- and a_specific_error for the lasting information
			-- (from GAME_SDL_ANY)
		do
			is_manual_error := True
			Precursor {GAME_ERROR_MANAGER} (a_general_message, a_specific_error)
		ensure -- from GAME_ERROR_MANAGER
				has_error
		end

	set_print_on_error (a_value: BOOLEAN)
			-- Assign to print_on_error the value of a_value
			-- (from GAME_ERROR_MANAGER)
		do
			if a_value then
				enable_print_on_error
			else
				disable_print_on_error
			end
		ensure -- from GAME_ERROR_MANAGER
			is_assign: print_on_error ~ a_value
		end
	
feature {GAME_HAPTIC_EFFECT_COMPILED} -- Implementation

	item: POINTER
			-- Internal pointer of Current
			-- (from GAME_HAPTIC)

	remove_compiled_effect (a_compiled_effect: GAME_HAPTIC_EFFECT_COMPILED)
			-- Remove a_compiled_effect from the compiled_effects
			-- Warning, this will not close the effect. You have to close
			-- it first.
			-- (from GAME_HAPTIC)
		do
			internal_compiled_effect.prune_all (a_compiled_effect)
		ensure -- from GAME_HAPTIC
			removed: not compiled_effects.has (a_compiled_effect)
		end
	
feature -- Implementation

	dispose
			-- Action to be executed just before garbage collection
			-- reclaims an object.
			-- Effect it in descendants to perform specific dispose
			-- actions. Those actions should only take care of freeing
			-- external resources; they should not perform remote calls
			-- on other objects since these may also be dead and reclaimed.
			-- (from GAME_HAPTIC)
		do
			if is_open then
				close
			end
		end
	
feature -- Output

	Io: STD_FILES
			-- Handle to standard file setup
			-- (from ANY)
		once
			create Result;
			Result.set_output_default
		ensure -- from ANY
			instance_free: class
			io_not_void: Result /= Void
		end

	out: STRING_8
			-- New string containing terse printable representation
			-- of current object
			-- (from ANY)
		do
			Result := tagged_out
		ensure -- from ANY
			out_not_void: Result /= Void
		end

	print (o: detachable ANY)
			-- Write terse external representation of o
			-- on standard output.
			-- (from ANY)
		local
			s: READABLE_STRING_8
		do
			if attached o then
				s := o.out
				if attached {READABLE_STRING_32} s as s32 then
					Io.put_string_32 (s32)
				elseif attached {READABLE_STRING_8} s as s8 then
					Io.put_string (s8)
				else
					Io.put_string_32 (s.as_string_32)
				end
			end
		ensure -- from ANY
			instance_free: class
		end

	frozen tagged_out: STRING_8
			-- New string containing terse printable representation
			-- of current object
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			tagged_out_not_void: Result /= Void
		end
	
feature -- Platform

	Operating_environment: OPERATING_ENVIRONMENT
			-- Objects available from the operating system
			-- (from ANY)
		once
			create Result
		ensure -- from ANY
			instance_free: class
			operating_environment_not_void: Result /= Void
		end
	
feature -- Query

	axes_count: INTEGER_32
			-- The number of axes of Current
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticnumaxes (item)
		end

	index: INTEGER_32
			-- The unique identifier of Current

	is_auto_center_supported: BOOLEAN
			-- Is Current supported the auto center feature
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_autocenter) /= 0
		end

	is_conditionnal_damper_effect_supported: BOOLEAN
			-- Is Current supported conditionnal effect base on axis velocities
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_damper) /= 0
		end

	is_conditionnal_friction_effect_supported: BOOLEAN
			-- Is Current supported conditionnal effect base on axis movement
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_friction) /= 0
		end

	is_conditionnal_inertia_effect_supported: BOOLEAN
			-- Is Current supported conditionnal effect base on axis acceleration
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_inertia) /= 0
		end

	is_conditionnal_spring_effect_supported: BOOLEAN
			-- Is Current supported conditionnal effect base on axis position
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_spring) /= 0
		end

	is_constant_effect_supported: BOOLEAN
			-- Is Current supported constant effect
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_constant) /= 0
		end

	is_custom_effect_supported: BOOLEAN
			-- Is Current supported custom effect
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_custom) /= 0
		end

	is_effect_supported (a_effect: GAME_HAPTIC_EFFECT): BOOLEAN
			-- Is a_effect can be compiled by Current
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
				is_open
		local
			l_value: INTEGER_32
		do
			clear_error
			l_value := {GAME_SDL_EXTERNAL}.sdl_hapticeffectsupported (item, a_effect.item)
			Result := False
			if l_value < 0 then
				manage_error_code (l_value, "Cannot validate if an effect is supported by an haptic")
			else
				Result := l_value > 0
			end
		end

	is_gain_control_supported: BOOLEAN
			-- Is Current supported gain control
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_gain) /= 0
		end

	is_left_right_effect_supported: BOOLEAN
			-- Is Current supported left/right effect
			-- Used in lots of recent console controller
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_leftright) /= 0
		end

	is_linear_ramp_effect_supported: BOOLEAN
			-- Is Current supported linear ramp effect
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_ramp) /= 0
		end

	is_open: BOOLEAN
			-- Is Current currently usable
			-- (from GAME_HAPTIC)
		do
			Result := not item.is_default_pointer
		end

	is_pause_supported: BOOLEAN
			-- Is Current supported the pause of an effect
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_pause) /= 0
		end

	is_paused: BOOLEAN
			-- Has Current presently stop with a pause.
			-- (from GAME_HAPTIC)

	is_periodic_saw_tooth_down_effect_supported: BOOLEAN
			-- Is Current supported periodic effect of the type
			-- sawtooth with the openning at the top.
			-- \  |\  |\  |\  |\  |\  |\  |
			--  \ | \ | \ | \ | \ | \ | \ |
			--   \|  \|  \|  \|  \|  \|  \|
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_sawtoothdown) /= 0
		end

	is_periodic_saw_tooth_up_effect_supported: BOOLEAN
			-- Is Current supported periodic effect of the type
			-- sawtooth with the openning at the bottom.
			--   /|  /|  /|  /|  /|  /|  /|
			--  / | / | / | / | / | / | / |
			-- /  |/  |/  |/  |/  |/  |/  |
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_sawtoothup) /= 0
		end

	is_periodic_sine_effect_supported: BOOLEAN
			-- Is Current supported periodic sine effect
			--   __      __      __      __
			--  /  \    /  \    /  \    /
			-- /    \__/    \__/    \__/
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_sine) /= 0
		end

	is_periodic_triangle_effect_supported: BOOLEAN
			-- Is Current supported periodic triangle effect
			--   /\    /\    /\    /\    /\
			--  /  \  /  \  /  \  /  \  /
			-- /    \/    \/    \/    \/
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_triangle) /= 0
		end

	is_rumble: BOOLEAN
			-- Is Current initialized as a rumble playback
			-- (from GAME_HAPTIC)

	is_rumble_supported: BOOLEAN
			-- Can Current be used as a simple rumble playback
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticrumblesupported (item)
		end

	is_status_query_supported: BOOLEAN
			-- Is Current supported the query of effect status
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_hapticquery (item).bit_and ({GAME_SDL_EXTERNAL}.sdl_haptic_status) /= 0
		end

	maximum_effect_compiled: INTEGER_32
			-- The maximum number of effect that Current can compiled and store
			-- Note that on some system, tis information is not given, so this
			-- may be a simple approximation
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticnumeffects (item)
			if l_error < 0 then
				manage_error_code (l_error, "Cannot get the maximum number of effect that an haptic can compile.")
				Result := 0
			else
				Result := l_error
			end
		end

	maximum_effect_playing: INTEGER_32
			-- The maximum number of effect that Current can play at the same time
			-- Note that on some system, tis information is not given, so this
			-- may be a simple approximation
			-- (from GAME_HAPTIC)
		require -- from GAME_HAPTIC
			is_open: is_open
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_hapticnumeffectsplaying (item)
			if l_error < 0 then
				manage_error_code (l_error, "Cannot get the maximum number of effect that an haptic can play.")
				Result := 0
			else
				Result := l_error
			end
		end

	name: READABLE_STRING_GENERAL
			-- A text to identified Current
		local
			l_c_pointer: POINTER
		do
			clear_error
			l_c_pointer := {GAME_SDL_EXTERNAL}.sdl_hapticname (index)
			if l_c_pointer.is_default_pointer then
				manage_error_pointer (l_c_pointer, "Cannot retreive haptic name.")
				Result := ""
			else
				Result := (create {C_STRING}.make_by_pointer (l_c_pointer)).string
			end
		end
	
feature {NONE} -- Retrieval

	frozen internal_correct_mismatch
			-- Called from runtime to perform a proper dynamic dispatch on correct_mismatch
			-- from MISMATCH_CORRECTOR.
			-- (from ANY)
		local
			l_msg: STRING_32
			l_exc: EXCEPTIONS
		do
			if attached {MISMATCH_CORRECTOR} Current as l_corrector then
				l_corrector.correct_mismatch
			else
				create l_msg.make_from_string ("Mismatch: ".as_string_32)
				create l_exc;
				l_msg.append (generating_type.name_32);
				l_exc.raise_retrieval_exception (l_msg)
			end
		end
	
invariant
		-- from GAME_HAPTIC
	is_haptic_enabled: Game_library.is_haptic_enable

		-- from ANY
	reflexive_equality: standard_is_equal (Current)
	reflexive_conformance: conforms_to (Current)

end -- class GAME_HAPTIC_DEVICE

Generated by ISE EiffelStudio