---------------------------------------------------------------------------------------------------------------------
--	Схема отыгрывания связных звуковых последовательностей.
--	автор:  Диденко Руслан  (Stohe)
----------------------------------------------------------------------------------------------------------------------

--' Таблица содержит менеджеры историй
local sound_managers = {}

local story_ltx = ini_file("misc\\sound_stories.ltx")


--' Звуковой менеджер содержит в себе список персонажей, которые могут рассказать историю по ролям.
class "sound_manager"
function sound_manager:__init(id)
	self.id = tostring(id)
	self.npc = {}			--'Таблица персонажей, зарегистрированных в саундменеджер
	self.storyteller = nil	--'Кто является рассказчиком
	self.story = nil		--'Какую историю будет отыгрывать данный менеджер. Один менеджер умеет отыгрывать только одну историю.
	self.last_playing_npc = nil
	self.phrase_timeout = nil	--' Хранит время начала паузы между фразами.
	self.phrase_idle = 0	--' Хранит длину паузы между фразами.
end
--' Зарегистрировать НПС.
function sound_manager:register_npc(npc_id)
	--printf("Register sm npc [%s]:[%s]", self.id, npc_id)
	table.insert(self.npc, {npc_id = npc_id})
	--print_table(self.npc)
end
--' Отрегистрировать нпс
function sound_manager:unregister_npc(npc_id)
	--printf("UnRegister sm npc [%s]:[%s]", self.id, npc_id)

	if self.last_playing_npc == npc_id and
	   xr_sound.sound_table[self.last_playing_npc]
	then
		-- Удаляется чувак, который щас говорит фразу. Нужно обрубить историю
		self.story = nil
	end

	if self.storyteller == npc_id then
		self.storyteller = nil
	end

	local remove_id = nil
	for k,v in pairs(self.npc) do
		if v.npc_id == npc_id then
			remove_id = k
			break
		end
	end
	if remove_id ~= nil then
		table.remove(self.npc, remove_id)
	end
	--print_table(self.npc)
end
--' Установить нпс, как разказчика.
function sound_manager:set_storyteller(npc_id)
	self.storyteller = npc_id
	--printf("Set storyteller sm [%s] = [%s]", self.id, npc_id)
end

--' Обновление
function sound_manager:update()
	--printf("Updating sm [%s]", self.id)
	if self.story == nil then
		--printf("no story")
		return
	end

	--' Ждем пока не закончится уже начатый звук
	if xr_sound.sound_table[self.last_playing_npc] ~= nil then
		--printf("wait sound")
		return
	end
	--' Устанавливаем таймаут ожидания между фразами.
	local t_global = time_global()
	if self.phrase_timeout == nil then
		self.phrase_timeout = t_global
	end

	if t_global - self.phrase_timeout < self.phrase_idle then
		--printf("wait time")
		return
	end


	--' Выбираем следующую фразу.
	local next_phrase = self.story:get_next_phrase()

	--' В теме закончились фразы
	if next_phrase == nil then
		--printf("no phrase")
		return
	end

	local npc = nil
	local tn = #self.npc
	if tn == 0 then
		--printf("no npc")
		return
	end

	--' Выбираем персонажа, который скажет фразу
	if next_phrase.who == "teller" then
		--' фраза рассказчика
		if self.storyteller == nil then
			self:choose_random_storyteller()
		end
		npc = self.storyteller

	elseif next_phrase.who == "reaction" then
		--' Фраза кого угодно, кроме рассказчика
		local teller_id = 0
		for k,v in pairs(self.npc) do
			if v.npc_id == self.storyteller then
				teller_id = k
				break
			end
		end

		if tn >= 2 then
			local id = math.random(1,tn-1)
			if id >= teller_id then
				id = id + 1
			end
			npc = self.npc[id].npc_id
		else
			npc = self.npc[1].npc_id
		end
	elseif next_phrase.who == "reaction_all" then
		local npc_id = nil
		for k,v in pairs(self.npc) do
			if v.npc_id ~= self.storyteller then
				xr_sound.set_sound_play(v.npc_id, next_phrase.theme)		
				npc_id = v.npc_id
			end
		end
	
		self.last_playing_npc = npc_id
		self.phrase_timeout = nil
		self.phrase_idle = next_phrase.timeout * 1000		
		return
	else
		--' Фраза кого угодно.
		npc = self.npc[math.random(1,#self.npc)].npc_id
	end

	--printf("Speaking sm [%s] npc[%s] phrase[%s]", self.id, npc, next_phrase.theme)

	--' Кешируем кто произносит фразу, чтобы отлавливать когда он закончит
	self.last_playing_npc = npc

	--' Произносим фразу
	if next_phrase.theme ~= "nil" then
		if(self.story.id=="squad_counter_attack") then
			local npc = alife():object(npc)
			local board = sim_board.get_sim_board()
			if(npc) and (board) then
	            local our_squad = board.squads[npc.squad_id]
				if(our_squad) then
	                local our_smart = our_squad.smart_id
	                local task = task_manager.get_task_manager():get_tasks_by_smart(our_smart)
	                if(next_phrase.who~="teller") then
                        local enemy_faction = task.counter_attack_community
                        xr_sound.set_sound_play(npc.id, next_phrase.theme, enemy_faction)
                        self.phrase_timeout = nil
                        self.phrase_idle = next_phrase.timeout * 1000
                        return
	                end
                    xr_sound.set_sound_play(npc.id, next_phrase.theme, our_squad.player_id, our_smart)
                    self.phrase_timeout = nil
                    self.phrase_idle = next_phrase.timeout * 1000
                    return
				end
			end
		end
	    xr_sound.set_sound_play(npc, next_phrase.theme)
	end

	self.phrase_timeout = nil
	self.phrase_idle = next_phrase.timeout * 1000
end
--' Рандомный выбор разказчика (вызывается если на момент рассказа рассказчика нет)
function sound_manager:choose_random_storyteller()
	self.storyteller = self.npc[math.random(1,#self.npc)].npc_id
end
--' Закончил ли саунд менеджер играть свою историю
function sound_manager:is_finished()
	if self.story == nil then
		return true
	end
	return self.story:is_finished()
end
--' Установить какую историю менеджер должен отыграть
function sound_manager:set_story(story_id)
	self.story = CStory(story_id)
	--printf("Set story sm [%s] = [%s]", self.id, story_id)
end



--' Создать новый саунд-менеджер. Нужно передать уникальный айдишник
function get_sound_manager(id)
	if sound_managers[id] == nil then
		sound_managers[id] = sound_manager(id)
	end
	return sound_managers[id]
end







--' Класс "история". Содержит дерево фраз. У каждой фразы указано должен ли ее говорить рассказчик или слушатели.
class "CStory"
function CStory:__init(story_id)
	--printf("Creating story [%s]", tostring(story_id))

	if not story_ltx:section_exist(story_id) then
		abort("There is no story [%s] in sound_stories.ltx", tostring(story_id))
	end

	self.replics = {}
	--' Вычитываем шаблон истории из ini файла

	local n = story_ltx:line_count(story_id)
	local id, value = "",""

	for i=0,n-1 do
		result, id, value	= story_ltx:r_line(story_id,i,"","")

		local t = parse_names(value)

		if t[1] ~= "teller" and t[1] ~= "reaction" and t[1] ~= "reaction_all" then
			abort("Wrong fist field [%s] in story [%s]", tostring(t[1]), tostring(story_id))
		end

		self.replics[i] = {who = t[1], theme = t[2], timeout = t[3]}
	end
    self.id = tostring(story_id)
	self.max_phrase_count = n-1
	self.next_phrase = 0
	--print_table(self.replics)
end
--' Закончена ли история
function CStory:is_finished()
	return self.next_phrase > self.max_phrase_count
end
--' Ресет истории
function CStory:reset_story()
	self.next_phrase = 0
end
--' Возвращает следующую фразу
function CStory:get_next_phrase()
	local phrase = self.replics[self.next_phrase]
	self.next_phrase = self.next_phrase + 1
	return phrase
end