note
	description: "[
							Represent the direction that an effect come from (an not where
							it goes, be carefull). Direction is encoded by three position
							(X axis, Y axix and Z axis). Cardinal directions
							of the haptic device are relative to the positioning of the device. 
							North is considered to be away from the user, south is toward the user, 
							east is right, and west is left of the user:
		
							               .--.
							               |__| .-------.
							               |=.| |.-----.|
							               |--| ||     ||
							               |  | |'-----'|
							               |__|~')_____('
							                [ COMPUTER ]
							
							
							                 North (0,-1,0)
							                      ^
							                      |
							                      |
							(-1,0,0) West <----[ HAPTIC ]----> East (1,0,0)
							                      |
							                      |
							                      v
							                 South (0,1,0)
							
							
							                 [ USER ]
							                   \|||/
							                   (o o)
							             ---ooO-(_)-Ooo---
	]"
	author: "Louis Marchand"
	date: "Tue, 03 Mar 2015 15:22:37 +0000"
	revision: "2.0"

class 
	GAME_HAPTIC_CARTESIAN_DIRECTION

create {GAME_HAPTIC_EFFECT}
	make_from_other


create 
	make,
	make_with_2_axis,
	make_with_axis

feature {NONE} -- Initialization

	default_create
			-- Process instances of classes with no creation clause.
			-- (Default: do nothing.)
			-- (from ANY)
		do
		end

	make_from_other (a_other: GAME_HAPTIC_DIRECTION)
			-- Initalization of Current using a_other as source
		require
			other_exists: a_other.exists
			other_cartesian: a_other.is_cartesian
		do
			make
			copy (a_other)
		ensure
			exists: exists
			type_is_valid: type = {GAME_SDL_EXTERNAL}.sdl_haptic_cartesian
			is_equal_other: is_values_equal (a_other)
		end

	make_with_2_axis (a_x, a_y: INTEGER_32)
			-- Initialization of Current using a_x as x axis and a_y as y axis
		do
			make_with_axis (a_x, a_y, 0)
		ensure
			exists: exists
			type_is_valid: type = {GAME_SDL_EXTERNAL}.sdl_haptic_cartesian
			x_axis_valid: x = a_x
			y_axis_valid: y = a_y
			z_axis_valid: z = 0
		end

	make_with_axis (a_x, a_y, a_z: INTEGER_32)
			-- Initialization of Current using a_ as x axis, a_y as
			-- y axis and a_z as z axis.
		do
			make
			set_position (a_x, a_y, a_z)
		ensure
			exists: exists
			type_is_valid: type = {GAME_SDL_EXTERNAL}.sdl_haptic_cartesian
			x_axis_valid: x = a_x
			y_axis_valid: y = a_y
			z_axis_valid: z = a_z
		end
	
feature -- Initialization

	make
			-- Initialization of Current
		require -- from  MEMORY_STRUCTURE
			True
		do
			Precursor
			set_type ({GAME_SDL_EXTERNAL}.sdl_haptic_cartesian)
		ensure -- from MEMORY_STRUCTURE
			not_shared: not shared
		ensure then
			exists: exists
			type_is_valid: type = {GAME_SDL_EXTERNAL}.sdl_haptic_cartesian
			x_axis_valid: x = 0
			y_axis_valid: y = 0
			z_axis_valid: z = 0
		end

	make_by_pointer (a_ptr: POINTER)
			-- Initialize current with a_ptr.
			-- (from MEMORY_STRUCTURE)
		require -- from MEMORY_STRUCTURE
			a_ptr_not_null: a_ptr /= default_pointer
		do
			internal_item := a_ptr
			managed_pointer := Void
			shared := True
		ensure -- from MEMORY_STRUCTURE
			shared: shared
		end
	
feature -- Access

	generating_type: TYPE [detachable GAME_HAPTIC_CARTESIAN_DIRECTION]
			-- 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

	is_cartesian: BOOLEAN
			-- Is Current is represented with cartesian coordinate
			-- (from GAME_HAPTIC_DIRECTION)
		require -- from GAME_HAPTIC_DIRECTION
			exists: exists
		do
			Result := {GAME_SDL_EXTERNAL}.get_sdl_haptic_direction_struct_type (item) = {GAME_SDL_EXTERNAL}.sdl_haptic_cartesian
		end

	is_equal (a_other: GAME_HAPTIC_CARTESIAN_DIRECTION): BOOLEAN
			-- Is other attached to an object considered
			-- equal to current object?
			-- (from GAME_HAPTIC_DIRECTION)
		require -- from ANY
			other_not_void: a_other /= Void
		do
			Result := is_values_equal (a_other)
		ensure -- from ANY
			symmetric: Result implies a_other ~ Current
			consistent: standard_is_equal (a_other) implies Result
		end

	is_polar: BOOLEAN
			-- Is Current is represented with polar coordinate
			-- (from GAME_HAPTIC_DIRECTION)
		require -- from GAME_HAPTIC_DIRECTION
			exists: exists
		do
			Result := {GAME_SDL_EXTERNAL}.get_sdl_haptic_direction_struct_type (item) = {GAME_SDL_EXTERNAL}.sdl_haptic_polar
		end

	is_spherical: BOOLEAN
			-- Is Current is represented with spherical coordinate
			-- (from GAME_HAPTIC_DIRECTION)
		require -- from GAME_HAPTIC_DIRECTION
			exists: exists
		do
			Result := {GAME_SDL_EXTERNAL}.get_sdl_haptic_direction_struct_type (item) = {GAME_SDL_EXTERNAL}.sdl_haptic_spherical
		end

	is_values_equal (a_other: GAME_HAPTIC_DIRECTION): BOOLEAN
			-- Are the important values inside Current are equvalent
		do
			if exists then
				if a_other.exists then
					Result := attached {GAME_HAPTIC_CARTESIAN_DIRECTION} a_other as la_other and then (type = la_other.type and x = la_other.x and y = la_other.y and z = la_other.z)
				else
					Result := False
				end
			else
				Result := not a_other.exists
			end
		end

	item: POINTER
			-- Access to memory area.
			-- (from MEMORY_STRUCTURE)
		local
			m: like managed_pointer
		do
			if shared then
				Result := internal_item
			else
				m := managed_pointer
				if m /= Void then
					Result := m.item
				end
			end
		end

	position: TUPLE [x: INTEGER_32; y: INTEGER_32; z: INTEGER_32]
			-- The coordinate of the origin of Current
		require
			exists: exists
		do
			Result := [x, y, z]
		end

	set_position (a_x, a_y, a_z: INTEGER_32)
			-- Assign position with the value of a_x, a_y and a_z
		require
			exists: exists
		do
			set_x (a_x)
			set_y (a_y)
			set_z (a_z)
		ensure
			x_axis_valid: x = a_x
			y_axis_valid: y = a_y
			z_axis_valid: z = a_z
		end

	set_x (a_x: INTEGER_32)
			-- Assign x with the value of a_x
		require
			exists: exists
		do
			{GAME_SDL_EXTERNAL}.set_sdl_haptic_direction_struct_dir_i (item, 0, a_x)
		ensure
			is_assign: x = a_x
		end

	set_y (a_y: INTEGER_32)
			-- Assign y with the value of a_y
		require
			exists: exists
		do
			{GAME_SDL_EXTERNAL}.set_sdl_haptic_direction_struct_dir_i (item, 2, a_y)
		ensure
			is_assign: y = a_y
		end

	set_z (a_z: INTEGER_32)
			-- Assign z with the value of a_z
		require
			exists: exists
		do
			{GAME_SDL_EXTERNAL}.set_sdl_haptic_direction_struct_dir_i (item, 2, a_z)
		ensure
			is_assign: z = a_z
		end

	shared: BOOLEAN
			-- Is current memory area shared with others?
			-- (from MEMORY_STRUCTURE)

	x: INTEGER_32 assign set_x
			-- The horizontal coordinate of the origin of Current
		require
			exists: exists
		do
			Result := {GAME_SDL_EXTERNAL}.get_sdl_haptic_direction_struct_dir_i (item, 0)
		end

	y: INTEGER_32 assign set_y
			-- The vertical coordinate of the origin of Current
		require
			exists: exists
		do
			Result := {GAME_SDL_EXTERNAL}.get_sdl_haptic_direction_struct_dir_i (item, 1)
		end

	z: INTEGER_32 assign set_z
			-- The depth coordinate of the origin of Current.
			-- To use this coordinate, you need a 3 axis haptic
			-- (See: GAME_HAPTIC.axes_count)
		require
			exists: exists
		do
			Result := {GAME_SDL_EXTERNAL}.get_sdl_haptic_direction_struct_dir_i (item, 2)
		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_CARTESIAN_DIRECTION): 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

	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_CARTESIAN_DIRECTION): 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

	exists: BOOLEAN
			-- Is allocated memory still allocated?
			-- (from MEMORY_STRUCTURE)
		do
			Result := item /= default_pointer
		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 -- 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_object (other: GAME_HAPTIC_CARTESIAN_DIRECTION)
			-- 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_CARTESIAN_DIRECTION)
			-- Effect equivalent to that of:
			--		copy (other . deep_twin)
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		do
			copy_object (other.deep_twin)
		ensure -- from ANY
			deep_equal: deep_equal (Current, other)
		end

	frozen deep_twin: GAME_HAPTIC_CARTESIAN_DIRECTION
			-- 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_CARTESIAN_DIRECTION)
			-- 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_CARTESIAN_DIRECTION
			-- 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_CARTESIAN_DIRECTION
			-- 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_CARTESIAN_DIRECTION
		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_CARTESIAN_DIRECTION
			-- 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 {GAME_HAPTIC_DIRECTION, GAME_HAPTIC_EFFECT} -- Implementation

	copy (a_other: GAME_HAPTIC_DIRECTION)
			-- Copy the memory of a_other into the one used by Current
			-- (from GAME_HAPTIC_DIRECTION)
		require -- from GAME_HAPTIC_DIRECTION
			exists: exists
			other_exists: a_other.exists
		do
			item.memory_copy (a_other.item, structure_size)
		ensure -- from GAME_HAPTIC_DIRECTION
				is_values_equal (a_other)
		end

	set_type (a_type: NATURAL_8)
			-- Assign type with the value of a_type
			-- (from GAME_HAPTIC_DIRECTION)
		require -- from GAME_HAPTIC_DIRECTION
			exists: exists
			type_valid: a_type = {GAME_SDL_EXTERNAL}.sdl_haptic_cartesian or a_type = {GAME_SDL_EXTERNAL}.sdl_haptic_polar or a_type = {GAME_SDL_EXTERNAL}.sdl_haptic_spherical
		do
			{GAME_SDL_EXTERNAL}.set_sdl_haptic_direction_struct_type (item, a_type)
		ensure -- from GAME_HAPTIC_DIRECTION
			is_assign: type = a_type
		end

	type: NATURAL_8 assign set_type
			-- The type of the encoding
			-- (from GAME_HAPTIC_DIRECTION)
		require -- from GAME_HAPTIC_DIRECTION
			exists: exists
		do
			Result := {GAME_SDL_EXTERNAL}.get_sdl_haptic_direction_struct_type (item)
		end
	
feature {NONE} -- Implementation

	internal_item: POINTER
			-- Pointer holding value when shared.
			-- (from MEMORY_STRUCTURE)

	managed_pointer: detachable MANAGED_POINTER
			-- Hold memory area in a managed way.
			-- (from MEMORY_STRUCTURE)
	
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 {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
	
feature -- implementation

	structure_size: INTEGER_32
			-- Size to allocate (in bytes).
			-- (from GAME_HAPTIC_DIRECTION)
		do
			Result := {GAME_SDL_EXTERNAL}.c_sizeof_sdl_haptic_direction
		ensure -- from MEMORY_STRUCTURE
			is_class: class
			positive_result: Result > 0
		end
	
invariant
	type_valid: type = {GAME_SDL_EXTERNAL}.sdl_haptic_cartesian
	position_valid: attached position as la_position and then (la_position.x = x and la_position.y = y and la_position.z = z)

		-- from GAME_HAPTIC_DIRECTION
	type_valid: type = {GAME_SDL_EXTERNAL}.sdl_haptic_cartesian or type = {GAME_SDL_EXTERNAL}.sdl_haptic_polar or type = {GAME_SDL_EXTERNAL}.sdl_haptic_spherical

		-- from MEMORY_STRUCTURE
	managed_pointer_valid: not shared implies managed_pointer /= Void
	internal_item_valid: shared implies internal_item /= default_pointer

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

end -- class GAME_HAPTIC_CARTESIAN_DIRECTION

Generated by ISE EiffelStudio