-- LUALOCALS < ---------------------------------------------------------
local ipairs, klots, math, minetest, pairs, string, table
    = ipairs, klots, math, minetest, pairs, string, table
local math_ceil, string_find, string_lower, string_sub, table_sort
    = math.ceil, string.find, string.lower, string.sub, table.sort
-- LUALOCALS > ---------------------------------------------------------

local function invform() return "" end

if klots.editmode then
	klots.register_item_modifier(function(name, def)
			local desc = def.description or ""
			if desc ~= "" then desc = desc .. "\n" end
			def.description = desc .. name
		end)

	local fse = minetest.formspec_escape
	invform = function(text)
		local invname = "creative_" .. minetest.sha1(text)
		minetest.remove_detached_inventory(invname)

		local allnames = {}
		local searchwords = string_lower(text):split(" ")
		for k, v in pairs(minetest.registered_nodes) do
			local nic = v.groups.not_in_creative_inventory
			if not (nic and nic > 0) then
				local desc = string_lower(v.description)
				local ok = true
				for _, s in ipairs(searchwords) do
					ok = ok and string_find(desc, s, 1, true)
				end
				if ok then
					allnames[#allnames + 1] = k
				end
			end
		end
		table_sort(allnames)

		local creativeinv
		local function reinit()
			for i = 1, #allnames do
				local s = allnames[i]
				if creativeinv:get_stack("main", i):to_string() ~= s then
					creativeinv:set_stack("main", i, s)
				end
			end
		end
		creativeinv = minetest.create_detached_inventory(invname, {
				allow_take = function() return -1 end,
				allow_put = function() return -1 end,
				on_move = reinit
			})
		creativeinv:set_size("main", #allnames)
		reinit()

		local rows = math_ceil(creativeinv:get_size("main") / 9)
		local scrollrate = (((rows - 7.75) * 1.25 - 0.25) / 1000)
		return "formspec_version[6]"
		.. "size[12.75,10.5]"
		.. "field[0.25,0.25;12.25,0.75;search;;" .. fse(text) .. "]"
		.. "field_close_on_enter[search;false]"
		.. "scroll_container[0.5,1.25;11.25,6;scroll;vertical;"
		.. scrollrate .. "]"
		.. "list[detached:" .. fse(invname) .. ";main;0,0;10," .. rows .. "]"
		.. "scroll_container_end[]"
		.. (scrollrate > 0 and "scrollbar[11.75,1.25;0.5,6;vertical;scroll;0]" or "")
		.. "list[current_player;main;0.25,8;10,2;]"
	end

	minetest.register_on_player_receive_fields(function(player, formname, fields)
			if formname == "" and fields.search and not (fields.scroll
				and string_sub(fields.scroll, 1, 4) == "CHG:") then
				return minetest.show_formspec(player:get_player_name(),
					"", invform(fields.search))
			end
		end)
end

minetest.register_on_joinplayer(function(player)
		player:set_properties({pointable = false})
		player:set_armor_groups({
				immortal = 1,
				fall_damage_add_percent = -100
			})
		local inv = player:get_inventory()
		inv:set_size("main", klots.editmode and 20 or 1)
		player:set_inventory_formspec(invform(""))
		if not klots.editmode then
			player:get_inventory():set_stack("main", 1, "")
		end
	end)

if klots.editmode then
	-- Tap zoom key to rotate inventory through hotbar
	klots.register_playerstep(function(player, data)
			local ctl = player:get_player_control()
			if ctl.zoom then
				data.zoom = true
			elseif data.zoom then
				data.zoom = nil
				local inv = player:get_inventory()
				local list = inv:get_list("main")
				local size = inv:get_size("main")
				for i = 1, size do
					inv:set_stack("main", i, list[(i + 9) % size + 1])
				end
			end
		end)
end
