inventory = {}
inventory.Elems = {}
inventory.collectElems = {}
inventory.incrementElems = {}
inventory.active_item = 0;
inventory.scroll_distance = 110;
inventory.elem_depth = 12
inventory.base_depth = 14
inventory.outer_distance = 200;
inventory.per_element_distance = 20;
inventory.min_border = 20;
inventory.visible_width = 300;
inventory.width = inventory.visible_width - 2 * inventory.min_border;


inventory.mp_elems_for_depth = { {"base"},
								 {"frame"},
								 {"btn_left", "btn_right"},
								 {"mp_skip_btn"},
								 {"TaskText", "TextPlace", "mp_menu_btn"},
								 {"mp_hint_btn"}
							   }

--inventory.
--local offset = 0


----------------------------------------------------------------------------------------------------
function inventory.set_depth_for_all()

	local cur_depth = inventory.base_depth
	
	for i = 1, #inventory.mp_elems_for_depth do
		
		for j = 1, #inventory.mp_elems_for_depth[i] do
			main_panel():setElementDepth_(inventory.mp_elems_for_depth[i][j], cur_depth)
		end
		
		cur_depth = cur_depth + 1
		
	end
end

------------------------------------------------------------------------------------------------
function inventory.find_cell(elem_name)
	for i=1, #inventory.Elems do
		if inventory.Elems[i].name == elem_name or inventory.Elems[i].element_name == elem_name then
			return i
		end
	end
	return nil;
end

----------------------------------------------------------------------------------------------------
function getInventoryFirstCellPos()
	--local elem = Panel.parent:getElement("Inv_flag")
	--local pos = elem:getPos()
	
	--return pos
end

----------------------------------------------------------------------------------------------------
function inventory.update()
	inventory.check()
	inventory.updatePositions()
	inventory.reactivate_elements()
end

----------------------------------------------------------------------------------------------------
function inventory.get_visible_width(first, last)

	if #inventory.Elems == 0 then
		return 0
	end

--	console:print(first.."  "..last.."  "..#inventory.Elems)

	local width = (last - first) * inventory.per_element_distance;

	for i=first, last do
		--local scale  = inventory.Elems[i].scale
		--local size = get_clip_size(inventory.Elems[i].element_name)
		local size = inventory.Elems[i].elemObj:getSize()
		width = width + size.x-- * scale
--		console:print("prev:  "..inventory.Elems[i].element_name..": "..width)
	end

	return width
end

----------------------------------------------------------------------------------------------------
function inventory.get_new_pos(elem_width)
	local prev_width = 0;

	if #inventory.Elems == 1 then
		return getInventoryFirstCellPos().x;
	end

	local first;
	local last;

	if #inventory.Elems == 2 then
		first = #inventory.Elems
		last = #inventory.Elems
	else
		first = #inventory.Elems - 1
		last = #inventory.Elems
	end

--	console:print(first.."; "..last)

	prev_width = inventory.get_visible_width(first, last)
--	console:print(prev_width)

	local width = prev_width + inventory.per_element_distance + elem_width
	--local center_offset = (width - inventory.visible_width) / 2
	local new_pos = getInventoryFirstCellPos().x - (width / 2) + prev_width + inventory.per_element_distance + elem_width / 2

	return new_pos
end

----------------------------------------------------------------------------------------------------
function inventory.shift(first, last, dir)
	--inventory.active_item

	if dir == -1 then --двигаем влево
		for i=first, last do
			inventory.scroll_elems(i, i, -inventory.scroll_distance)
		end
	else
		for i=first, last do --двигаем вправо
			inventory.scroll_elems(i, i, inventory.scroll_distance)
		end
	end
end

------------------------------------------------------------------------------------------------
function inventory.scroll_elems(first, last, distance)
	for i=first, last do
		--local elem = get_current_level():getElementByName(inventory.Elems[i].element_name);
		local elem = inventory.Elems[i].elemObj
		local item_index = inventory.find_cell(elem:getName())
		if not inventory.Elems[item_index].flying then
			if inventory.Elems[i].move_anim == nil then
				--inventory.Elems[i].move_anim.deltaX = inventory.Elems[i].move_anim.deltaX + distance
				--inventory.Elems[i].move_anim.time = inventory.Elems[i].move_anim.time + 0.2
			--else
				inventory.Elems[i].move_anim = {}
				local anim = inventory.Elems[i].move_anim;
				anim.deltaX = distance;
				anim.deltaY = 0;
				anim.startPos = elem:getPos()
				anim.time = 0.2;
				anim.time_left = 0.0
				anim.scriptOnEnd = "";
				elem:setEventHandler(eiUpdate, "invmove_update")
			end
		end
	end
end

------------------------------------------------------------------------------------------------
function inventory.reactivate_elements()
	for i=1, #inventory.Elems do
--		local elem = get_current_level():getElementByName(inventory.Elems[i].element_name)
		local elem = inventory.Elems[i].elemObj
		if (i >= inventory.active_item) and (i < inventory.active_item + 4) then
--			console:print(inventory.Elems[i].element_name..": on")
			elem:setEventHandler(eiLeftClick, "inventory.elem_taken(\""..inventory.Elems[i].name.."\")")
		else
--			console:print(inventory.Elems[i].element_name..": off")
			elem:setEventHandler(eiLeftClick, "")
		end
	end
end

------------------------------------------------------------------------------------------------
function inventory.get_element_name(adapted_name)
	for i=1, #inventory.Elems do
		if inventory.Elems[i].name == adapted_name then
			return inventory.Elems[i].element_name
		end
	end
end

------------------------------------------------------------------------------------------------
function inventory.elem_land(elem_name)
	--activateInventoryElement(inventory.get_element_name(elem_name), true)
	inventory.reactivate_elements()
	play_movie_clip_ex(elem_name, 2, 2)
	local cell_elem = inventory.Elems[inventory.find_cell(elem_name)];
	find_element(cell_elem.element_name):setScale(cell_elem.natural_scale)
	--
	cell_elem.flying = false
	cell_elem.needed_count = cell_elem.needed_count - 1

	---------------------------------------main_panel():setElementDepth(elem_name, "mainpanel", inventory.elem_depth)

	if cell_elem.increment then 
		inc_elements_count(cell_elem.element_name)
	end
	
	for i=1, #inventory.collectElems do
	
		for j=1, #inventory.collectElems[i].elements do			
			if inventory.collectElems[i].elements[j] == cell_elem.name and cell_elem.needed_count == 0 then
				inventory.collectElems[i].elems_found = inventory.collectElems[i].elems_found + 1
			end
		end
		--console:print("elem_name = "..elem_name..", cell_elem.needed_count = "..cell_elem.needed_count)
		
		--[[
		if inventory.collectElems[i].elems_found == #inventory.collectElems[i].elements then
			local pos = Vec2(0, 512)
			--console:print("#inventory.collectElems[i].elements = "..#inventory.collectElems[i].elements)
			for j=1, #inventory.collectElems[i].elements do
				pos.x = pos.x + inventory.get_element_name(inventory.collectElems[i].elements[j])):getPos().x
			end
			pos.x = getInventoryFirstCellPos().x -- inventory.scroll_distance  + pos.x / #inventory.collectElems[i].elements
			
			for j = 1, #inventory.collectElems[i].elements do
				local name = inventory.get_element_name(inventory.collectElems[i].elements[j])
				local elem = get_current_level():getElementByName(name);
				local cell = inventory.find_cell(inventory.collectElems[i].elements[j])
				inventory.Elems[cell].move_anim = {}
				local anim = inventory.Elems[cell].move_anim;
				anim.deltaX = pos.x - elem:getPos().x;
				anim.deltaY = pos.y - elem:getPos().y;
				anim.startPos = elem:getPos()
				anim.time = 0.2;
				anim.time_left = 0.0
				anim.scriptOnEnd = "inventory.collect_flying_callback(\""..inventory.collectElems[i].elements[j].."\")";
				elem:setEventHandler(eiUpdate, "invmove_update")
			end
			if inventory.collectElems[i].callback ~= nil then
				add_timer(inventory.collectElems[i].callback, 1, 1)
			end
		end
		--]]
	end

	--inventory.active_item = #inventory.Elems
	--inventory.check()
	--inventory.updatePositions()
	inventory.check()
	inventory.updatePositions()
	
end

----------------------------------------------------------------------------------------------------
function inventory.activate_arrows(state)
	--main_panel:activate_arrows(state)
	--main_panel.parent:getElement("btn_right"):setVisible(state)
	--main_panel.parent:getElement("btn_left"):setVisible(state)
end


------------------------------------------------------------------------------------------------
function inventory.find_prev_increment(index)
	for i=1, #inventory.Elems do
		if string.find(inventory.Elems[i].name, inventory.incrementElems[index].name_part) ~= nil then
			return i
		end
	end
	return nil
end

------------------------------------------------------------------------------------------------
--[[
function on_inventory_item_added(elem, move)
	inventory.add_elem(elem, move)
end
--]]

function set_inv_elem_pos(index, x)
	--local elem = get_current_level():getElementByName(inventory.Elems[index].element_name);
	local elem = inventory.Elems[index].elemObj

	local pos = Vec2();
	pos.x = x
	pos.y = 700
	elem:setPos(pos)
end

local is_playing = false

function play_inv()
	is_playing = false
end

 
function inventory.get_max_active_item()
	if #inventory.Elems < 3 then
		return 1
	end

	local last = 1
	for i=1, #inventory.Elems do
		if inventory.get_visible_width(i, #inventory.Elems) > inventory.width then
			last = last + 1
		end
	end

--	console:print("inventory.get_max_active_item(): "..last)
	return last
end

local prev_items_count = 0

function inventory.updatePositions()

	if inventory.active_item == 0 then
		return;
	end

	local last = inventory.active_item

--	console:print("active item: "..inventory.active_item)
	for i=inventory.active_item, #inventory.Elems do
		--if last < #inventory.Elems and last < inventory.active_item + 2 then
		if last <= #inventory.Elems and inventory.get_visible_width(inventory.active_item, i) < inventory.width then
			last = last + 1
		end
	end

	local vis_width = inventory.get_visible_width(inventory.active_item, last - 1)
--	console:print("vis_width: "..vis_width)
	local center = getInventoryFirstCellPos()
	local vis_offset = 0

--	console:print("first: "..inventory.active_item.."; last: "..last)
	for e=1, #inventory.Elems do
		--local elem = get_current_level():getElementByName(inventory.Elems[e].element_name);
		local elem = inventory.Elems[e].elemObj

		local pos = Vec2()
		pos.y = center.y

--		console:print("element index: "..e)

		if e >= inventory.active_item and e < last then
			local size = inventory.Elems[e].elemObj:getSize().x-- * inventory.Elems[e].scale
--			console:print("vis_offset: "..vis_offset.." element widht: "..size)
--			console:print("center: "..center.x.."    (vis_width / 2): "..(vis_width / 2))
			pos.x = center.x - (vis_width / 2) + vis_offset + (size / 2)
--			console:print("pos after: "..pos.x)
			vis_offset = vis_offset + size + inventory.per_element_distance
		else
			if e < inventory.active_item then
				pos.x = center.x - 350
			elseif e >= last then
				pos.x = center.x + 350
			end
		end

		local distance = pos.x - elem:getPos().x
		
		if mouse:getConnectedName() ~= inventory.Elems[e].element_name then
			inventory.scroll_elems(e, e, distance)
		end
		--console:print("position: "..pos.x)
		--elem:setPos(pos)
	end
end

------------------------------------------------------------------------------------------------
function inventory.check()
	local state = inventory.get_visible_width(1, #inventory.Elems) > inventory.width

	inventory.activate_arrows(state)

	--console:print("inventory.check(): previous active item: "..inventory.active_item)

	if #inventory.Elems == 0 then
		inventory.active_item = 0
		return
	end

	local max_active_item = inventory.get_max_active_item()

	if inventory.active_item > max_active_item then
		inventory.active_item = max_active_item
		inventory.reactivate_elements()
		return
	end
	
	if inventory.active_item < 1 then
		inventory.active_item = 1
	end

	--console:print("inventory.check(): new active item: "..inventory.active_item)

	inventory.reactivate_elements()
end

------------------------------------------------------------------------------------------------
function invmove_update(elem, dt)


	local table_cell = inventory.Elems[inventory.find_cell(elem:getName())]
	if table_cell == nil then return;	end



	local anim_up = table_cell.move_anim;
	anim_up.time_left = anim_up.time_left + dt;
	local pos = elem:getPos()
	pos.x = anim_up.startPos.x + anim_up.deltaX*(anim_up.time_left/anim_up.time);
	pos.y = anim_up.startPos.y + anim_up.deltaY*(anim_up.time_left/anim_up.time);

	if table_cell == 1 then
		--console:print("invmove_update(): get_first: "..pos.x)
	end
	if anim_up.time <= anim_up.time_left then
		pos.x = anim_up.startPos.x + anim_up.deltaX;
		pos.y = anim_up.startPos.y + anim_up.deltaY;
		elem:setEventHandler(eiUpdate, "")
		if anim_up.scriptOnEnd ~= "" then
			exec_string(anim_up.scriptOnEnd)
		end
		table_cell.move_anim = nil

		if inventory.active_item > 0 then
			local active_elem = inventory.Elems[inventory.active_item].elemObj
			--console:print("invmove_update(): "..active_elem:getPos().x)

			if active_elem:getPos().x < getInventoryFirstCellPos().x - 150 then
				local flag = true
				for j = 1, #inventory.Elems do
					if inventory.Elems[j].move_anim ~= nil then
						flag = false
					end
				end
				if flag then
					inventory.updatePositions()
				end
			end
		end
	end
	elem:setPos(pos)

end

------------------------------------------------------------------------------------------------
function inventory.scroll_right()
	if inventory.active_item >= inventory.get_max_active_item() then
		return;
	end

	--inventory.shift(1, #inventory.Elems, -1)
	--inventory.scroll_elems(1, #inventory.Elems, -inventory.scroll_distance)
	
	inventory.active_item = inventory.active_item + 1
	inventory.updatePositions()
	--inventory.reactivate_elements()
end

------------------------------------------------------------------------------------------------
function inventory.scroll_left()
	if inventory.active_item < 2 then
		return;
	end	
	--inventory.shift(1, #inventory.Elems, 1)
	--inventory.scroll_elems(1, #inventory.Elems, inventory.scroll_distance)
	
	inventory.active_item = inventory.active_item - 1
	inventory.updatePositions()
	--inventory.reactivate_elements()
end

------------------------------------------------------------------------------------------------
function inventory.right_click_callback(elem_name)
	
	--console:print("inventory.right_click_callback: "..elem_name)

	local cell = inventory.find_cell(elem_name)
	if cell == nil then return end
	play_movie_clip_ex(elem_name, 2, 2)
--	console:print("inventory.right_click_callback1111111: "..elem_name)
	local pos = Vec2();
	local cell_pos = getInventoryFirstCellPos()
	--console:print(offset)
	pos.x = cell_pos.x + (--[[ offset +  ]]cell - inventory.active_item)*inventory.scroll_distance;
	pos.y = cell_pos.y;
	getMouse():setConnElem(nil)
	--local elem = get_current_level():getElementByName(inventory.Elems[cell].element_name)
	local elem = inventory.Elems[cell].elemObj
	--elem:setPos(pos)
	inventory.updatePositions();
	mouse():overElement("default_cursor")
	--play_movie_clip_ex(elem_name, 2, 2)
	--elem:scale(element_fly_animation.elem_props[elem:getName()].targetScale)
end

------------------------------------------------------------------------------------------------
function inventory.elem_taken(elem_name)
	local cell = inventory.find_cell(elem_name)
	if cell == nil then return end
	
	local elem = inventory.Elems[cell].elemObj
	elem:setEventHandler(eiRightClick, "inventory.right_click_callback(\""..elem_name.."\")")
	--getMouse():setConnElem(elem)
	mouse:setConnCharacter(elem:getCharacter())
	--elem:scale(inventory.Elems[cell].natural_scale)
	play_movie_clip_ex(elem_name, 3, 3)
end

------------------------------------------------------------------------------------------------
function inventory.add_collect(elements_table, result)
	inventory.collectElems[#inventory.collectElems+1] = {}
	inventory.collectElems[#inventory.collectElems].elements = elements_table
	inventory.collectElems[#inventory.collectElems].result = result
	inventory.collectElems[#inventory.collectElems].elems_found = 0
	inventory.collectElems[#inventory.collectElems].landed = 0
	inventory.collectElems[#inventory.collectElems].callback = nil
end

------------------------------------------------------------------------------------------------
function inventory.add_collect_ex(elements_table, result, script)
	inventory.add_collect(elements_table, result)
	inventory.collectElems[#inventory.collectElems].callback = script
end

------------------------------------------------------------------------------------------------
function inventory.collect_flying_callback(elem_name)
--console:print("inventory.collect_flying_callback(\""..elem_name.."\")")
	--[[
	for i=1, #inventory.collectElems do
		for j=1, #inventory.collectElems[i].elements do
			if inventory.collectElems[i].elements[j] == elem_name then
				inventory.collectElems[i].landed = inventory.collectElems[i].landed + 1
				inventory.check()
				inventory.updatePositions()
				if #inventory.collectElems[i].elements == inventory.collectElems[i].landed then
					local elem = get_current_level():getElementByName(inventory.collectElems[i].result)
					if elem == nil then
						elem = create_script_element(inventory.collectElems[i].result)
					end
					--elem:setPos(get_current_level():getElementByName(inventory.get_element_name(elem_name)):getPos())
					elem:setPos(get_current_level():getElementByName(inventory.get_element_name(elem_name)):getPos())
					--local pos = getInventoryFirstCellPos();
					--elem:setPos(pos)

					for k=1, #inventory.collectElems[i].elements do
						inventory.delete_elem(inventory.collectElems[i].elements[k])
					end
					
					--inventory.add_elem(elem, true)
					inventory.add_elem(elem, true)
					--main_panel():setElementDepth(elem:getName(), "mainpanel", inventory.elem_depth)
					--inventory.check()
					--inventory.updatePositions()

					table.remove(inventory.collectElems, i)
				end
				
				return
			end
		end
	end
	--]]
end

------------------------------------------------------------------------------------------------
function inventory.delete_elem(elem_name)
	local idx = inventory.find_cell(elem_name)
	if idx == nil then
		return
	end
	
	--local elem = get_current_level():getElementByName(inventory.Elems[idx].element_name)
	local elem = inventory.Elems[idx].elemObj

	table.remove(inventory.Elems, idx)
	inventory.reactivate_elements()
	for i=1, eiUpdate do
		elem:setEventHandler(i, "")
	end
	set_element_visible(elem:getName(), false)
	drop_inventory_element(elem)
	
	inventory.check()
	inventory.updatePositions()
end

------------------------------------------------------------------------------------------------
function inventory.add_increment(name_part, count)
	inventory.incrementElems[#inventory.incrementElems+1] = {}
	inventory.incrementElems[#inventory.incrementElems].name_part = name_part;
	inventory.incrementElems[#inventory.incrementElems].count = count;
end

------------------------------------------------------------------------------------------------
function inventory.reset()
	for i=1, #inventory.Elems do
		set_element_visible(inventory.Elems[i].element_name, false)
		local elem = inventory.Elems[i].elemObj
		drop_inventory_element(elem) -- C function. Removes element from mainpanel's display list
		for j=1, eiUpdate do
			elem:setEventHandler(i, "")
		end
	end
	inventory.Elems = {}
	inventory.collectElems = {}
	inventory.incrementElems = {}
	inventory.active_item = 0;
	inventory.check()
	-----------------------------------main_panel():setElementDepth_("base", inventory.base_depth)
	inventory.set_depth_for_all()
end 


----------------------------------------------------------------------------------------------------
function inventory.print_elements()
--	console:print("Inventory elements ("..#inventory.Elems..") :")
	for i = 1, #inventory.Elems do
--		console:print(inventory.Elems[i].element_name)
	end
end