--[[------------------------------------------------------------------------------------------------------------------
Проигровка звуков в голове актера
Tunduk Vladimir aka Sidorovich

--------------------------------------------------------------------------------------------------------------------]]


class "action_sound2d"
----------------------
function action_sound2d:__init (obj, storage)
	self.object = obj
	self.st = storage
	self.snd_obj_l = nil
	self.snd_obj_r = nil
	self.time = 0
	self.playing = false
	self.current = 0
end
----------------------
function action_sound2d:reset_scheme()

    self:recreate_sounds ()
    
	self.st.signals = {}
	self.time = time_global ()
	self.playing = false
end
----------------------
function action_sound2d:recreate_sounds ()
    self.snd_obj_l = nil
    self.snd_obj_r = nil
    local name_left, name_right = self:get_sound_name ()
    
    if name_left ~= nil then
       printf ("RECREATE_SOUNDS. LEFT CHANNEL = %s", name_left)
    end    

    if name_right ~= nil then
       printf ("RECREATE_SOUNDS. RIGHT CHANNEL = %s", name_right)
    end    

    self.snd_obj_l = xr_sound.get_safe_sound_object (name_left)
    if name_right ~= nil then
       self.snd_obj_r = xr_sound.get_safe_sound_object (name_right)
    else   
       self.snd_obj_r = nil
    end   
end
----------------------
function action_sound2d:get_next_sound_index ()
    local idx = self.current
    local tsize = #sound_theme.ph_snd_themes[self.st.snd_theme]
    if tsize == 1 then 
       idx = 1
    else    
       while idx == self.current do
             idx = math.random (1, tsize)
       end
    end   
    self.current = idx
    return idx
end
----------------------
function action_sound2d:get_sound_name ()
    local name
    if self.st.snd_name ~= nil then
       name = self.st.snd_name
    else   
       name = sound_theme.ph_snd_themes[self.st.snd_theme][self:get_next_sound_index ()]
		if type(name) == "table" then
			name = name[1]
		end
    end
        
    if self.st.stereo == false then
       return name, nil
    end
    return string.format ("%s_l", name), string.format ("%s_r", name)
end
----------------------
function action_sound2d:update (delta)
    if self.snd_obj_l == nil then 
       return 
    end
    
    local actor = db.actor
    
    if self.playing == false then
       self:play_sounds ()
       self.playing = true
       return
    end
    
    if self.st.stereo == true then
       local pos_l, pos_r = self:get_source_positions ()
       if self.snd_obj_l ~= nil and self.snd_obj_l:playing () == true then
          self.snd_obj_l:set_position (pos_l)
       end   
       if self.snd_obj_r ~= nil and self.snd_obj_r:playing () == true then
          self.snd_obj_r:set_position (pos_r)
       end   
    end   
    
        
    if self.snd_obj_l:playing () == false then
       self.st.signals["sound_end"] = true
       if self.st.snd_theme ~= nil then
          self:recreate_sounds ()  
          self.time = time_global ()
	      self.playing = false
       end       
    end   
    
    xr_logic.try_switch_to_another_section (self.object, self.st, actor)
end
----------------------
function action_sound2d:play_sounds ()

    --рассчет задержки
    local d
    if self.st.delay == self.st.delay_max then
       d = self.st.delay
    else
       d = math.random (self.st.delay, self.st.delay_max)
    end       

    local actor = db.actor
    -- если звук моно, то играем только с левого канала и только в жбане актера
    if self.st.stereo == false then
       if self.snd_obj_l ~= nil then
          self.snd_obj_l:play_at_pos (actor, vector ():set (0, 0, 0), d / 1000.0, sound_object.s2d)
       end
    else
       --если один из каналов отсутсвует, то пинать жестоко звуковика 
       if self.snd_obj_l == nil or self.snd_obj_r == nil then
          abort ("Can't play stereo sound because sound file for left or right channel not loaded")  
       end
       --рассчитаем направления на источники звука для левого и правого лопуха
       local pos_l, pos_r = self:get_source_positions ()
       self.snd_obj_l:play_at_pos (actor, pos_l, d / 1000.0, sound_object.s3d)
       self.snd_obj_r:play_at_pos (actor, pos_r, d / 1000.0, sound_object.s3d)
    end      
end
----------------------
function action_sound2d:get_source_positions ()
    local actor = db.actor
    local dir = actor:direction ()
    dir.y = 0.0
    local dir_left = vector_rotate_y (dir, 45)
    local dir_right = vector_rotate_y (dir, -45)
    dir_left:normalize ()
    dir_right:normalize ()
       --рассчитаем высоту 
    local pos = actor:position ()
    pos.y = pos.y + 1.5   --ну низкорослый у нас актер...
    local pos_l = pos;
    return pos_l:add (dir_left:mul (1.5)), pos:add (dir_right:mul (1.5))
end
----------------------
function action_sound2d:deactivate ()
    if self.snd_obj_l ~= nil then
       if self.snd_obj_l:playing () == true then
          self.snd_obj_l:stop ()
       end
       self.snd_obj_l = nil
    end         
    
    if self.snd_obj_r ~= nil then
       if self.snd_obj_r:playing () == true then
          self.snd_obj_r:stop ()
       end
       self.snd_obj_r = nil
    end         
end



----------------------
function add_to_binder( npc, ini, scheme, section, storage )

--	local new_action = 

	-- Зарегистрировать все actions, в которых должен быть вызван метод reset_scheme при изменении настроек схемы:
	xr_logic.subscribe_action_for_events (npc, storage, action_sound2d (npc, storage))
end
----------------------
function set_scheme (obj, ini, scheme, section, gulag_name)

	local st = xr_logic.assign_storage_and_bind (obj, ini, scheme, section)
	st.logic = xr_logic.cfg_get_switch_conditions (ini, section, obj)
	st.snd_name = utils.cfg_get_string (ini, section, "snd", obj, false, "", nil)
	st.snd_theme = utils.cfg_get_string (ini, section, "theme", obj, false, "", nil)
	
	if st.snd_theme ~= nil and st.snd_name then
	   abort ("SR_SOUND2D : can't definition sound file name and sound theme at the one time");
	end    
	
	st.delay = utils.cfg_get_number (ini, section, "delay", obj, false, 0)
	st.delay_max = utils.cfg_get_number (ini, section, "delay_max", obj, false, 0)
	st.stereo = utils.cfg_get_bool (ini, section, "stereo", obj, false, false)
	
	if st.delay_max < st.delay then
	    st.delay_max = st.delay
	end
	
	if st.snd_name ~= nil then
       if st.snd_name == "" then
	      abort ("SR_SOUND2D : invalid sound name")
	   end   
	else   
	   if st.snd_theme == nil or st.snd_theme == "" then
	      abort ("SR_SOUND2D : invalid sound theme")  
	   end
	end   
	
end
----------------------
----------------------
----------------------
----------------------

