-------------------------------------------------------------------------------------
-- Компонент редактора отвечающий за выделение обьекта или групы обьектов
-- AA 2013
-------------------------------------------------------------------------------------

class 'Selection'

function Selection:__init(game_scene)
	self.game_scene = game_scene
	self.current_selected_object = nil -- временно, в будущем добавить возможность выделения множества обьектов
	self.blocker_objects = {}  -- спрайты, которые создаются поверх редактируемого обьекта, чтобы по клику не вызывались подписаные на него обработчики
	self.blocker_objects_reversed = {}
	self.is_enabled = false
end

-------------------------------------------------------------------------------------
function Selection:on_scene_start()
	if self.is_enabled then
		self:disable()
		self:enable()
	end
	self:remove_selection()
end

-------------------------------------------------------------------------------------
function Selection:add_click_handler(object)
	local blocker_object = CreateSpriteEntity('')

	blocker_object:attachTo(object)
	blocker_object:setName('click_blocker_'..object:getName())
	if object.getWidth then -- временно
		blocker_object:setSize(object:getWidth(), object:getHeight())
	end
	if object.getColor then
		local object_color = object:getColor()
		blocker_object:setColor(object_color:getR(), object_color:getG(), object_color:getB(), 1/255)
	end
	
	self.blocker_objects[object:getName()] = blocker_object
	self.blocker_objects_reversed['click_blocker_'..object:getName()] = object

	object.onDestroy:add(function() 
		self.blocker_objects[object:getName()] = nil 
	end)

	blocker_object.onPress:add(function() 
		self.game_scene:getIngameEditor():on_object_selected(object)
		self.current_selected_object = object
	end)

	return blocker_object
end

-------------------------------------------------------------------------------------
function Selection:resize_click_handler(object)
	self.blocker_objects[object:getName()]:setSize(object:getWidth(), object:getHeight())
end

-------------------------------------------------------------------------------------
function Selection:set_click_handlers()
	local function get_child_objects(root)
		local result = {}
		-- Все кроме зумов
		for i = 0, root:size() - 1 do
			local str_start, str_end = string.find(root:get(i):getName(), 'ZoomZone')
			if not (str_start and str_start == 1) then
				table.insert(result, root:get(i))
				if root:get(i):getChilds():size() > 0 then
					table.insert(result, get_child_objects(root:get(i):getChilds()))
				end
			end
		end

		local flatten_childs = table.unpack(result)
		return flatten_childs
	end

	local playfield_objects = get_child_objects(self.game_scene:getPlayField():getMainEntity():getChilds())
	for _, object in pairs(playfield_objects) do
		local blocker_object = self:add_click_handler(object)
		blocker_object:setRespondable(self.is_enabled)
	end

	local zoom_zones_objects = {}
	for _, zone in pairs(self.game_scene:getPlayField():getZones()) do
		table.insert(zoom_zones_objects, get_child_objects(zone:getEntityAnchor():getChilds()))
	end
	for _, object in pairs(table.unpack(zoom_zones_objects)) do
		local blocker_object = self:add_click_handler(object)
		blocker_object:setRespondable(self.is_enabled)
	end
end

-------------------------------------------------------------------------------------
function Selection:remove_selection()
	self.current_selected_object = nil
	self.game_scene:getIngameEditor():on_selection_removed()
end

-------------------------------------------------------------------------------------
function Selection:enable()
	if not self.is_enabled then
		self.is_enabled = true
		self:set_click_handlers()
		for name, obj in pairs (self.blocker_objects) do 
			obj:setRespondable(true) 
		end
	end
end

-------------------------------------------------------------------------------------
function Selection:disable()
	self.is_enabled = false
	for _, obj in pairs (self.blocker_objects) do 
		if obj then
			obj:destroy() 
		end
	end
	for _, obj in pairs (self.blocker_objects_reversed) do 
		if obj then
			obj.onDestroy:removeAll() 
		end
	end
	self.current_selected_object = nil
	self.blocker_objects = {}
	self.blocker_objects_reversed = {}
end

-------------------------------------------------------------------------------------
function Selection:get_current_selected_object()
	return self.current_selected_object
end