---------------------------------------------------------------------------------------------
--' Для того, что бы мир не был загружен кучей трупов,
--' будем их потихоньку удалять.
--' Made by Distemper ----------------------------------------------------------------
--' 11.02.08 ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
local IDLE_AFTER_DEATH = 40000
local function add_to_release_table(release_tbl, object_id)
	printf("add to release_objects_table ["..object_id.."]")
	local obj_params = {}
	obj_params.id = object_id
	obj_params.death_time = time_global()
	table.insert(release_tbl, obj_params)
end

local function find_nearest_obj_to_release(release_tbl)
	local max_distanse = 4900
	local pos_in_table = nil
	local actor = db.actor
	local actor_pos = actor:position()
	for k,v in pairs(release_tbl) do
		printf("release_objects_table["..k.."] = "..v.id)
		local object = alife():object(v.id)
		if object then
			printf("object_id = "..object.id)
			printf("object_position x = "..vec_to_str(object.position))
			local distance_to_body = actor_pos:distance_to_sqr(object.position)
			printf("distanse = "..distance_to_body)
			if distance_to_body > max_distanse and ((v.death_time == nil) or (time_global() > v.death_time + IDLE_AFTER_DEATH)) then
				max_distanse = distance_to_body
				pos_in_table = k
			end
		end
	end
	return pos_in_table
end

local RB_manager = nil

class "Crelease_body"

function Crelease_body:__init()
	self.release_objects_table = {} -- таблица "СТЕК" трупов
	self.keep_items_table = {} -- таблица квестовых предметов
 	self.body_max_count = 50 -- количество тел которое одновременно может находится в игре
	self.current_object_id = 0 -- id только что убитого npc
	--' Итерируемся по списку квестовых итемов.
	local snd_ini = ini_file("misc\\death_generic.ltx")
	if not snd_ini:section_exist("keep_items") then
		abort("There is no section [keep_items] in death_generic.ltx")
	end
	local n = snd_ini:line_count("keep_items")
	local value = ""
	for i = 0, n - 1 do
		result, section, value  = snd_ini:r_line("keep_items", i, "", "")
		table.insert(self.keep_items_table, section)
	end
end

function Crelease_body:moving_dead_body(obj)
	printf("current body name ["..obj:name().."]")
	printf("-------table-------")
	print_table(self.release_objects_table)
	printf("-----end table-----")

	local object_id = obj:id()
	if self:inspection_result(obj) then
		printf("inspection_result return  ->  true")
		if #self.release_objects_table <= self.body_max_count then
			add_to_release_table(self.release_objects_table, object_id)
			return
		else
			self:try_to_release()
		end
		add_to_release_table(self.release_objects_table, object_id)
	end
end

function Crelease_body:try_to_release()
	printf("dead body -> ["..self.body_max_count.."]")
	local pos_in_table = nil
	local overflow_count = #self.release_objects_table - self.body_max_count
	for i = 1, overflow_count do
		pos_in_table = find_nearest_obj_to_release(self.release_objects_table)

		if pos_in_table == nil then
			return
		end

		local release_object = alife():object(self.release_objects_table[pos_in_table].id)

		if release_object then
			printf("releasing object ["..release_object:name().."]")
			if (IsStalker(release_object) or IsMonster(release_object)) and not release_object:alive() then
				alife():release(release_object, true)
			end
		end

		table.remove(self.release_objects_table, pos_in_table)
	end
end



function Crelease_body:inspection_result(obj)
	for k,v in pairs(self.keep_items_table) do
		if obj:object(self.keep_items_table[k]) ~= nil then
			printf("Object << "..obj:name().." >> presence_in_keep_items_table") -- в инвентаре есть квестовый предмет
			return false
		end
	end
	if get_object_story_id(obj:id()) ~= nil then
		printf("Object << "..obj:name().." >> presence_in_story") -- помечен как сюжетный
		return false
	end
	if self:check_for_known_info(obj) then
		printf("Object << "..obj:name().." >> presence_in_known_info")
		return false
	end
	return true
end

function  Crelease_body:check_for_known_info(obj)
	local char_ini = ""
	local spawn_ini = obj:spawn_ini()
	local filename = nil
	if spawn_ini then
		filename = utils.cfg_get_string(spawn_ini, "logic", "cfg", obj, false, "")
		printf("filename is [%s]", tostring(filename))
	end
	if filename ~= nil then
		if not getFS():exist("$game_config$", filename) then
			abort("There is no configuration file [%s] in [%s]", filename, obj:name())
		end
		char_ini = ini_file(filename)
	else
		char_ini = obj:spawn_ini() or ini_file("scripts\\dummy.ltx")
	end
	local st = db.storage[obj:id()]
	local known_info = utils.cfg_get_string(char_ini, st.section_logic, "known_info", obj, false, "", nil) or "known_info"
	if char_ini:section_exist(known_info) then
		return true
	end
	return false
end

function Crelease_body:save(packet)
	set_save_marker(packet, "save", false, "Crelease_body")
	local count = #self.release_objects_table
	packet:w_u16(count)
	for k,v in pairs(self.release_objects_table) do
		packet:w_u16(v.id)
	end
	local level_id = game_graph():vertex(alife():actor().m_game_vertex_id):level_id()
	packet:w_u16(level_id)
	set_save_marker(packet, "save", true, "Crelease_body")
end

function Crelease_body:load(reader)
	set_save_marker(reader, "load", false, "Crelease_body")
	local count = reader:r_u16()
	self.release_objects_table = {}
	for i = 1, count do
		local vid = reader:r_u16()
		self.release_objects_table[i] = {}
		self.release_objects_table[i].id = vid
	end
	local level_id = reader:r_u16()
	if level_id ~= game_graph():vertex(alife():object(0).m_game_vertex_id):level_id() then
		self.release_objects_table = {}
	end
	set_save_marker(reader, "load", true, "Crelease_body")
end

function get_release_body_manager()
	if(RB_manager==nil) then
		RB_manager = Crelease_body()
	end
	return RB_manager
end
