player_style.register_button=function(def)
	if def.low_priority then
		def.low_priority = nil
		table.insert(player_style.buttons.low_priority,def)
		return
	elseif def.lower_priority then
		def.lower_priority = nil
		table.insert(player_style.buttons.lower_priority,def)
		return
	end

	local a = (def.type and (def.type .. "_button") or "button")
	.. (def.exit and "_exit" or "") .. "["

	local b = ",0;1,1;"
	.. (((def.type == "image" or def.type == "item_image") and def.image and (def.image .. ";")) or "")
	.. def.name ..";"
	.. (def.label or "") .."]"
	..(def.info and ("tooltip["..def.name..";"..def.info.."]") or "")

	player_style.buttons.num_of_buttons = player_style.buttons.num_of_buttons + 1
	player_style.buttons.action[def.name]=def.action

	table.insert(player_style.buttons.buttons,{text1=a,text2=b,privs=def.privs})
end

player_style.register_manual_page=function(def)
	if type(def.name) ~= "string" then
		error("name (string) required!")
	elseif type(def.text) ~= "string" and type(def.action) ~= "function" then
		error("text (string) or action (function) required!")
	end
	local t
	if def.itemstyle and not def.item then
		t = "label[0,0;"..def.name.."]item_image[0,0.5;1,1;"..def.itemstyle.."]textarea[0,1.5;8.5,8.0;;;"..(def.text or "").."]"
	else
		t = def.text:find("%[") and def.text or "label[0,"..(def.label and 1 or 0)..";"..def.text.."]"
		t = t .. (def.label and "label[0,0;"..def.label.."]" or "")
	end
	table.insert(player_style.manual_pages,{name=def.name,text=t,tags=def.tags,action=def.action,item=def.item,itemstyle=def.itemstyle})
end

minetest.register_on_priv_grant(function(name, granter, priv)
	player_style.inventory(minetest.get_player_by_name(name))
end)

minetest.register_on_priv_revoke(function(name, revoker, priv)
	player_style.inventory(minetest.get_player_by_name(name))
end)

minetest.register_privilege("creative", {
	description = "Creative",
	give_to_singleplayer= false,
})

player_style.register_button({
	name="Manual",
	image="default_unknown.png",
	type="image",
	info="User manual",
	action=function(player)
		player_style.manual(player)
	end
})

player_style.inventory_handle=function(player,handle)-- {hide=true} {show=true} {clear=true}
	local m = player:get_meta()
	local name = player:get_player_name()
	local inv=player:get_inventory()
	local invp =  player_style.players[name].inv
	local items1 = {}
	local items2 = {}
	local items3 = {}
	if handle.hide or handle.clear then
		for i=1,4 do
			if handle.hide then
				m:set_string("backpack"..i.."_hide",m:get_string("backpack"..i))
				m:set_string("backpackslot"..i.."_hide",m:get_string("backpackslot"..i))
			end
			m:set_string("backpack"..i,"")
			m:set_string("backpackslot"..i,"")
			player_style.players[name].inv["backpackslot"..i]:set_stack("main",1, "")
		end

		for i,v in pairs(inv:get_list("main")) do
			items1[i] = v:to_table()
		end
		for i,v in pairs(inv:get_list("craft")) do
			items2[i] = v:to_table()
		end
		if handle.hide then
			m:set_int("hiding_inventory",1)
			m:set_string("hat_hide",m:get_string("hat"))
			m:set_string("insurance_hide",m:get_string("insurance"))
			m:set_string("main_hide",minetest.serialize(items1))
			m:set_string("craft_hide",minetest.serialize(items2))
			m:set_string("armor_hide",m:get_string("armor"))
		end

		m:set_string("hat","")
		m:set_string("insurance","")
		inv:set_list("main",{})
		inv:set_list("craft",{})
		armor.user[name].inv:set_list("main", {})
		m:set_string("armor","")

		if invp.backpack_object then
			invp.backpack_object:remove()
			invp.backpack_object = nil
		end

		player_style.players[name].inv["hat"]:set_stack("main",1, "")
		player_style.players[name].inv["insurance"]:set_stack("main",1, "")
	elseif handle.show and m:get_int("hiding_inventory") == 1 then
		for i=1,4 do
			m:set_string("backpack"..i,m:get_string("backpack"..i.."_hide"))
			m:set_string("backpackslot"..i,m:get_string("backpackslot"..i.."_hide"))
			m:set_string("backpack_hide"..i,"")
			m:set_string("backpackslot_hide"..i,"")
			player_style.players[name].inv["backpackslot"..i]:set_stack("main",1, minetest.deserialize(m:get_string("backpackslot"..i.."_hide")))
		end
		
		for i,v in pairs(minetest.deserialize(m:get_string("main_hide"))) do
			items1[i]=ItemStack(v)
		end
		for i,v in pairs(minetest.deserialize(m:get_string("craft_hide"))) do
			items2[i]=ItemStack(v)
		end

		for i,v in pairs(minetest.deserialize(m:get_string("armor_hide") or "") or {}) do
			local g = minetest.get_item_group(v.name,"armor")
			if g > 0 then
				items3[g] = ItemStack(v)
			end
		end

		inv:set_list("main",items1)
		inv:set_list("craft",items2)
		armor.user[name].inv:set_list("main", items3)
		m:set_string("hat",m:get_string("hat_hide"))
		m:set_string("insurance",m:get_string("insurance_hide"))
		m:set_string("armor",m:get_string("armor_hide"))
		player_style.players[name].inv["hat"]:set_stack("main",1, minetest.deserialize(m:get_string("hat_hide")))
		player_style.players[name].inv["insurance"]:set_stack("main",1, minetest.deserialize(m:get_string("insurance_hide")))

		m:set_string("hat_hide","")

		m:set_string("craft_hide","")
		m:set_string("main_hide","")
		m:set_string("armor_hide","")
		m:set_string("insurance_hide","")
		m:set_int("hiding_inventory",0)
	end
	player_style.inventory(player)
	armor.update(player)
end

player_style.inventory=function(player)
	local name = player:get_player_name()
	local m = player:get_meta()
	player_style.players[name].inv = player_style.players[name].inv or {adds={},adds_func={},itemmagnet=m:get_int("itemmagnet")}
	local invp = player_style.players[name].inv

--detached inventory (backpack)

	if not invp.backpack then
		
-- Backpack
		
		if player:get_meta():get_string("backpack") ~= "" then
			m:set_string("backpack1",m:get_string("backpack"))
			m:set_string("backpackslot1",m:get_string("backpackslot"))
			m:set_string("backpack","")
			m:set_string("backpackslot","")
		end

		invp.backpacki = m:get_int("backpackindex")
		invp.backcraft = m:get_int("backcraftlistring")

		for i=1,4 do
			invp["backpackslot"..i] = minetest.create_detached_inventory(name .. "_backpackslot"..i, {
				allow_put = function(inv, listname, index, stack, player)
					return minetest.get_item_group(stack:get_name(),"backpack") > 0 and stack:get_count() or 0
				end,
				allow_take = function(inv, listname, index, stack, player)
					for i,v in pairs(minetest.deserialize(player:get_meta():get_string("backpack"..i) or "") or {}) do
						if ItemStack(v):get_count() > 0 then
							return 0
						end
					end
					return stack:get_count()
				end,
				on_put = function(inv, listname, index, stack, player)
					player:get_meta():set_string("backpackslot"..i,minetest.serialize(stack:to_table()))
					if not invp.backpack_object then
						invp.backpack_object = minetest.add_entity(player:get_pos(),"default:wielditem")
						invp.backpack_object:set_attach(player, "body2",{x=2, y=0, z=0}, {x=180,y=90,z=0})
						invp.backpack_object:set_properties({textures={"player_style:backpack"},visual_size = {x=0.15,y=0.15,z=0.3}})
					end

					minetest.after(0,function(player)
						player_style.inventory(player)
					end,player)
				end,
				on_take = function(inv, listname, index, stack, player)
					player:get_meta():set_string("backpackslot"..i,"")
					if invp.backpack_object then
						invp.backpack_object:remove()
						invp.backpack_object = nil
					end
					player_style.inventory(player)
				end
			})

			invp["backpackslot"..i]:set_size("main",1)
			invp["backpackslot"..i]:set_stack("main",1,ItemStack(minetest.deserialize(player:get_meta():get_string("backpackslot"..i) or "")) or {})

			if invp["backpackslot"..i]:is_empty("main") == false then
				minetest.after(0.1,function(invp,player)
					invp.backpack_object = minetest.add_entity(player:get_pos(),"default:wielditem")
					invp.backpack_object:set_attach(player, "body2",{x=2, y=0, z=0}, {x=180,y=90,z=0})
					invp.backpack_object:set_properties({textures={"player_style:backpack"},visual_size = {x=0.15,y=0.15,z=0.3}})
				end,invp,player)
			end
		end
		invp.backpack = minetest.create_detached_inventory(name .. "_backpack", {
			allow_put = function(inv, listname, index, stack, player)
				local p = player_style.players[name]
				local invps = p and p.inv
				if invps and invps.backpacki == 0 or inv:is_empty("main") and minetest.get_item_group(stack:get_name(),"backpack") > 0 then
					return 0
				elseif invps and invps["backpackslot"..invps.backpacki]:is_empty("main") then
					return 0
				end
				return stack:get_count()
			end,
			on_move = function(inv, from_list, from_index, to_list, to_index, count,player)
				local name = player:get_player_name()
				local d = {}
				for i,v in pairs(inv:get_list("main")) do
					d[i]=v:to_table()
				end
				player:get_meta():set_string("backpack"..player_style.players[name].inv.backpacki,minetest.serialize(d))
			end,
			on_put = function(inv, listname, index, stack, player)
				local name = player:get_player_name()
				local d = {}
				for i,v in pairs(inv:get_list("main")) do
					d[i]=v:to_table()
				end
				player:get_meta():set_string("backpack"..player_style.players[name].inv.backpacki,minetest.serialize(d))
			end,
			on_take = function(inv, listname, index, stack, player)
				local name = player:get_player_name()
				local d = {}
				for i,v in pairs(inv:get_list("main")) do
					d[i]=v:to_table()
				end
				player:get_meta():set_string("backpack"..player_style.players[name].inv.backpacki,minetest.serialize(d))
			end
		})
		invp.backpack:set_size("main",24)

--hat

		invp.hat = minetest.create_detached_inventory(name .. "_hat", {
			allow_put = function(inv, listname, index, stack, player)
				return default.def(stack:get_name()).hat_properties and 1 or 0
			end,
			on_put = function(inv, listname, index, stack, player)
				player:get_meta():set_string("hat",minetest.serialize(stack:to_table()))
				local def = minetest.registered_items[stack:get_name()]
				if not invp.hat_object and def and def.hat_properties then
					invp.hat_object = minetest.add_entity(player:get_pos(),"default:wielditem")
					invp.hat_object:set_attach(player, "head",def.hat_properties.pos or {x=0, y=6, z=0}, def.hat_properties.rotation or {x=0,y=90,z=0})
					invp.hat_object:set_properties({textures={stack:get_name()},visual_size = def.hat_properties.size or {x=0.5,y=0.5,z=0.5}})
				end
			end,
			on_take = function(inv, listname, index, stack, player)
				if invp.hat_object then
					invp.hat_object:remove()
					invp.hat_object = nil
				end
				player:get_meta():set_string("hat","")
			end
		})
		invp.hat:set_size("main",1)
		local item = ItemStack(minetest.deserialize(player:get_meta():get_string("hat") or ""))
		invp.hat:set_stack("main",1,item or {})
		local def = minetest.registered_items[item:get_name()]

		if invp.hat:is_empty("main") == false and def and def.hat_properties then
			minetest.after(0.1,function(invp,player)
				invp.hat_object = minetest.add_entity(player:get_pos(),"default:wielditem")
				invp.hat_object:set_attach(player, "head",def.hat_properties.pos or {x=0, y=6, z=0}, def.hat_properties.rotation or {x=0,y=90,z=0})
				invp.hat_object:set_properties({textures={item:get_name()},visual_size = def.hat_properties.size or {x=0.5,y=0.5,z=0.5}})
			end,invp,player)
		end


--insurance


		invp.insurance = minetest.create_detached_inventory(name .. "_insurance", {
			allow_put = function(inv, listname, index, stack, player)
				return stack:get_name() == "bones:insurance" and stack:get_count() or 0
			end,
			on_put = function(inv, listname, index, stack, player)
				player:get_meta():set_string("insurance",minetest.serialize(stack:to_table()))
			end,
			on_take = function(inv, listname, index, stack, player)
				player:get_meta():set_string("insurance",minetest.serialize(stack:to_table()))
			end
		})
		invp.insurance:set_size("main",1)
		local item = ItemStack(minetest.deserialize(player:get_meta():get_string("insurance") or ""))
		invp.insurance:set_stack("main",1,item or {})
	end


--BackPacks


	local backpack = ""

	if invp.backpacki ~= 0 and minetest.get_item_group(invp["backpackslot"..invp.backpacki]:get_stack("main",1):get_name(),"backpack") > 0 then
		backpack = "list[detached:"..name.."_backpack;main;0,1.2;4,6;]listring[current_player;main]listring[detached:"..name.."_backpack;main]" or ""
		local list = {}
		for i,v in pairs(minetest.deserialize(player:get_meta():get_string("backpack"..invp.backpacki) or "") or {}) do
			list[i]=ItemStack(v)
		end
		invp.backpack:set_list("main", list)
	end

	for i=1,4 do
		if minetest.get_item_group(invp["backpackslot"..i]:get_stack("main",1):get_name(),"backpack") > 0 then
			if invp.backpacki ~= i then
				backpack = backpack .. "button["..(i-1)..",0.8;1,0.2;backpack"..i..";"..i.."]"
			else
				backpack = backpack .. "image_button["..(i-1)..",0.7;0.6,0.6;player_style_backpack.png;backpackmoveto;]"
				.. "image_button["..(i-0.6)..",0.7;0.6,0.6;default_craftgreed.png;backpackmovefrom;]"
				.. "tooltip[backpackmoveto;Move items to backpack]"
				.. "tooltip[backpackmovefrom;Move items to inventory]"
			end
		end
		backpack = backpack
		.."image_button["..(i-1)..",-0.2;1,1;player_style_backpack.png;backpack"..i..";]"
		.."list[detached:"..name.."_backpackslot"..i..";main;"..(i-1)..",-0.2;1,1;]"
	end


--Coins


	if Getcoin(name) < 0 then
		player_style.players[name].coins_guilty = {time=0}
	end


--inventory


	local buttons_bar = ""
	local adds = ""
	local buttons_pos = 0
	for i,v in pairs(invp.adds) do
		adds = adds .. v
	end

	for i,v in ipairs(player_style.buttons.buttons) do
		if minetest.check_player_privs(player, v.privs) then
			buttons_bar = buttons_bar .. v.text1 .. buttons_pos .. v.text2
			buttons_pos = buttons_pos + 0.8
		end
	end

	local coins = "label[4,-0.3;"..minetest.colorize("#FFFF00",Getcoin(player)).."]tooltip[4,-0.3;2,0.4;Coins]"
	local skin = minetest.formspec_escape(player:get_properties().textures[1] or "character.png")
	local model = "model[4,0.3;2,3;character_preview;character.b3d;"..skin..";0,180;false;true;1,31]"
	local music = "item_image_button[7,0;1,1;player_style:earphone_hat" .. ";music;]tooltip[music;Music]"
	local itemmagnet = "image_button[7,1;1,1;default_megenet.png" .. (invp.itemmagnet == 1 and "" or "^default_cross.png") .. ";itemmagnet;]tooltip[itemmagnet;Item Magnet]"
	local buttons = "scrollbaroptions[max="..((player_style.buttons.num_of_buttons-10)*10).."]scrollbar[0,8;12,0.5;horizontal;scrollbar;]scroll_container[0,8.2;15,1.5;scrollbar;horizontal]"
	.. buttons_bar
	.. "scroll_container_end[scrollbar]"

	if not (player_style.creative or minetest.check_player_privs(name, {creative=true})) then
--default inventory
		player:set_inventory_formspec(
			"size[12,8]" 
			.."listcolors[#77777777;#777777aa;#000000ff]"
			.."list[current_player;main;4,3.2;8,4;]"
			.."list[current_player;craft;8,0;3,3;]"
			.."list[current_player;craftpreview;11,1;1,1;]"
			.."item_image[6,0;1,1;player_style:top_hat]"
			.."list[detached:"..name.."_hat;main;6,0;1,1;]"
			.."tooltip[6,0;1,1;Hats]"
			.."item_image[11,0;1,1;bones:insurance]"
			.."list[detached:"..name.."_insurance;main;11,0;1,1;]"
			.."tooltip[11,0;1,1;Insurances]"
			.."listring[current_player;main]"
			.."image_button[6,2;1,1;default_craftgreed.png^default_unknown.png;craftguide;]tooltip[craftguide;Craftguide]"
			.. (invp.backcraft == 0 and "listring[current_player;craft]image_button[6,1;1,1;default_craftgreed.png;backcraft;]tooltip[backcraft;Shift-move to craftgreed]" or "listring[detached:"..name.."_backpack;main]image_button[6,1;1,1;player_style_backpack.png;backcraft;]tooltip[backcraft;Shift-move to backpack]")
			.. music
			.. itemmagnet
			..model
			..buttons
			..backpack
			..coins
			..adds
		)
	else
--creative inventory items
		if not player_style.inventory_items then
			player_style.inventory_items={}
			for i,it in pairs(minetest.registered_items) do
				if not (it.groups and it.groups.not_in_creative_inventory) then
					table.insert(player_style.inventory_items,it.name)
				end
			end
			table.sort(player_style.inventory_items)

			minetest.create_detached_inventory("deleteslot", {
				on_put = function(inv, listname, index, stack, player)
					inv:set_stack("main",1,"")
				end
			}):set_size("main", 1)
		end
--creative inventory
		invp.index = invp.index or 1
		invp.size = invp.size or 34
		invp.search = invp.search and invp.search.text ~= "" and invp.search or nil

		local itemlist = invp.search and invp.search.items or player_style.inventory_items
		local pages = math.floor(#itemlist/player_style.players[name].inv.size)
		local page = math.floor(player_style.players[name].inv.index/player_style.players[name].inv.size)+1
		local itembutts = ""
		local x=12
		local y=0

		for i=invp.index,invp.index+invp.size do
			local it = itemlist[i]
			if it then
				itembutts = itembutts.."item_image_button["..x..","..y..";1,1;"..it..";itembut_"..it..";]"
				x = x + 0.8
				if x >= 16 then
					y = y + 0.9
					x = 12
				end
			end
		end
		player:set_inventory_formspec(
			"size[16,8]" 
			.."listcolors[#77777777;#777777aa;#000000ff]"
			.."list[current_player;main;4,3.2;8,4;]"
			.."list[current_player;craft;8,0;3,3;]"
			.."list[current_player;craftpreview;11,1;1,1;]"

			.."item_image[6,0;1,1;player_style:top_hat]"
			.."list[detached:"..name.."_hat;main;6,0;1,1;]"
			.."tooltip[6,0;1,1;Hats]"

			.."item_image[11,0;1,1;bones:insurance]"
			.."list[detached:"..name.."_insurance;main;11,0;1,1;]"
			.."tooltip[11,0;1,1;Insurances]"

			.."image[11,2;1,1;default_bucket.png]list[detached:deleteslot;main;11,2;1,1;]"
			.."tooltip[11,2;1,1;Destroy item]"


			.."image_button[6,2;1,1;default_craftgreed.png^default_unknown.png;craftguide;]tooltip[craftguide;Craftguide]"
			.."listring[current_player;main]"
			.. (invp.backcraft == 0 and "listring[current_player;craft]image_button[6,1;1,1;default_craftgreed.png;backcraft;]tooltip[backcraft;Shift-move to craft grid]" or "listring[detached:"..name.."_backpack;main]image_button[6,1;1,1;player_style_backpack.png;backcraft;]tooltip[backcraft;Shift-move to backpack]")
			.. music
			.. itemmagnet

			..buttons

			.."image_button[13,7;1,1;default_crafting_arrowleft.png;creinvleft;]"
			.."image_button[14,7;1,1;default_crafting_arrowright.png;creinvright;]"
			.."image_button[15,7;1,1;synth_repeat.png;reset;]"
			.."image_button[12,7;1,1;default_bucket.png;clean;]"

			.."tooltip[creinvleft;Back]"
			.."tooltip[creinvright;Forward]"
			.."tooltip[reset;Reset search]"
			.."tooltip[clean;Clear inventory]"
			.."image[11,2;1,1;default_bucket.png]list[detached:deleteslot;main;11,2;1,1;]"
			.."tooltip[11,2;1,1;Destroy item]"
			.."label[13.6,7.9;"..page.."/"..pages.."]"

			.."field[12.3,6.5;3,1;searchbox;;"..(invp.search and invp.search.text or "").."]"
			.."field_close_on_enter[searchbox;false]"
			.."image_button[15,6.3;1,0.8;player_style_search.png;search;]"
			..model
			..backpack
			..itembutts
			..coins
			..adds
		)
	end
end

minetest.register_on_player_receive_fields(function(player, form, pressed)
	if form == "" then
		local name = player:get_player_name()
		for i,v in pairs(pressed) do
			if player_style.buttons.action[i] then
				player_style.buttons.action[i](player)
				return
			end
		end
		local invp = player_style.players[name].inv

		if invp then
			if pressed.quit and pressed.key_enter_field == nil then
				player_style.players[name].inv.clean = nil
				return
			elseif pressed.itemmagnet then
				invp.itemmagnet = invp.itemmagnet == 0 and 1 or 0
				player:get_meta():set_int("itemmagnet",invp.itemmagnet)
				player_style.inventory(player)
				return
			elseif pressed.craftguide then
				player_style.craftguide.show(player)
				return
			elseif pressed.music then
				music.show(player)
				return
			elseif pressed.creinvright and invp.index+invp.size < (invp.search and #invp.search.items or #player_style.inventory_items) then
				invp.index = invp.index + invp.size+1
				player_style.inventory(player)
				return
			elseif pressed.creinvleft and invp.index > 1 then
				invp.index = invp.index - invp.size-1
				player_style.inventory(player)
				return
			elseif pressed.reset then
				invp.index = 1
				invp.search = nil
				player_style.inventory(player)
				return
			elseif pressed.clean then
				if not invp.clean then
					minetest.chat_send_player(name,"Press again to clean you inventory")
					invp.clean = true
				else
					local inv = player:get_inventory()
					for i,v in pairs(inv:get_list("main")) do
						inv:set_stack("main",i,"")
					end
					player_style.players[name].inv.clean = nil
				end
			elseif pressed.search or pressed.key_enter_field == "searchbox" then
				local its = {}
				local s = pressed.searchbox:lower()
				for i,it in pairs(player_style.inventory_items) do
					if it:find(s) or (minetest.registered_items[it].description or ""):lower():find(s) then
						table.insert(its,it)
					end
				end
				invp.index = 1
				invp.search={
					text = s,
					items = its
				}
				player_style.inventory(player)
				return true
			elseif pressed.backcraft then
				local m = player:get_meta()
				invp.backcraft = m:get_int("backcraftlistring") == 0 and 1 or 0
				m:set_int("backcraftlistring",invp.backcraft)
				player_style.inventory(player)
			elseif pressed.backpackmoveto or pressed.backpackmovefrom then
				local inv = player:get_inventory()
				local d = {}
				if pressed.backpackmoveto then
					for i,item in pairs(inv:get_list("main")) do
						if invp.backpack:room_for_item("main",item) then
							invp.backpack:add_item("main",item)
							inv:set_stack("main",i,nil)
						end
					end
				else
					for i,item in pairs(invp.backpack:get_list("main")) do
						if inv:room_for_item("main",item) then
							inv:add_item("main",item)
							invp.backpack:set_stack("main",i,nil)
						end
					end
				end
				for i,v in pairs(invp.backpack:get_list("main")) do
					d[i]=v:to_table()
				end
				player:get_meta():set_string("backpack"..invp.backpacki,minetest.serialize(d))
			else
				for i=1,4 do
					if pressed["backpack"..i] and minetest.get_item_group(invp["backpackslot"..i]:get_stack("main",1):get_name(),"backpack") > 0 then
						player:get_meta():set_int("backpackindex",i)
						invp.backpacki = i
						player_style.inventory(player)
						return
					end
				end
			end
			for i,v in pairs(pressed) do
				if i:sub(1,8) == "itembut_" then
					local t = i:sub(9,-1)
					player:get_inventory():add_item("main",t.." "..minetest.registered_items[t].stack_max)
					break
				end
			end

			for i,v in pairs(invp.adds) do
				if pressed[i] and invp.adds_func[i] then
					invp.adds_func[i](player)
					break
				end
			end
		end
	elseif form == "player_style.manual" then
		if pressed.manuallist then
			local i = minetest.explode_textlist_event(pressed.manuallist).index
			player_style.manual(player,i)
		elseif pressed.close then
			player_style.manual(player,true)
		else
			for i,v in pairs(pressed) do
				if i:sub(1,7) == "manual_" then
					player_style.manual(player,tonumber(i:sub(8,-1)))
					break
				end
			end
		end
	end
end)

player_style.manual=function(player,page)
	local name = player:get_player_name()
	local ppr = player_style.players[name]
	ppr.manual = ppr.manual or {}
	local text = "size[12,10]listcolors[#77777777;#777777aa;#000000ff]"

	if not page or page == true then
		local dir = player:get_look_dir()
		local pos = player:get_pos()
		local p1 = {x=pos.x+dir.x,y=pos.y+1.4,z=pos.z+dir.z}
		local p2 = {x=pos.x+(dir.x*5),y=pos.y+1.4+(dir.y*5),z=pos.z+(dir.z*5)}

		local node
		local object

		for v in minetest.raycast(p1,p2,true,true) do
			if v.type == "node" then
				node = minetest.get_node(v.under).name
			elseif v.type == "object" then
				local en = v.ref:get_luaentity()
				if en then
					object = en.name
				end
			end
			break
		end

		local item = object or node or player:get_wielded_item():get_name()
		local items = ""
		local c = ""

		local def = minetest.registered_items[item] or {}
		local y = 2
		local x = 4
		for i,v in ipairs(player_style.manual_pages) do
			items = items .. c .. v.name
			c = ","

			if not page and (item == v.name or v.name == def.description) then
				player_style.manual(player,i)
				return
			end

			if v.itemstyle then
				text = text .. "item_image_button["..x..","..y..";1,1;"..v.itemstyle..";manual_"..i..";]"
				x = x + 1
				if x >= 11 then
					x = 4
					y = y + 1
				end
			end

			if v.tags and item then
				local groups = def.groups or {}
				for i1,v1 in ipairs(v.tags) do
					if item == v1 or groups[v1] then
						if def then
							text = text .. "item_image_button[4,1;1,1;"..item..";manual_"..i..";]"
						else
							text = text .. "image_button[4,1;1,1;default_unknown.png;manual_"..i..";]"
						end
						break
					end
				end
			end

		end
		text = text .. "textlist[0,0;4,10;manuallist;".. items .."]label[4,0;Look at the things and it opens or shows here\nautomacly if there is information about it]"
		return minetest.show_formspec(name, "player_style.manual",text)
	else
		local p = player_style.manual_pages[page]
		text = text .. (p.text or "")
		if p.action then
			text = text .. p.action(player) or ""
		end
		text = text .. "button[11.2,-0.3;1,1;close;X]"
		return minetest.show_formspec(name, "player_style.manual",text)
	end
end

player_style.register_manual_page({
	name = "Controls",
	text = "",
	tags = {"default:dirt","default:dirt_with_grass","snowy"},
	action=function(player)
		local y = 0
		local t = ""
		local l = {
			["Crawl"]="sneak",
			["Run"]="special/aux1",
			["Wallrun"]="run + jump into a wall (can be hard)",
			["Edge climb"]="touch an edge above the ground",
			["Kong"]="run into a block",
			["Cat leap"]="jump backwards in edge climbing",
			["Tic tac/walljump"]="run + jump side of a wall",
			["Double wall climb"]="hold left & right",
			["Backflip	"]="jump, (hold) place/RMB & press back",
			["Frontflip"]="jump, (hold) place/RMB & press forward",
			["Right sideflip"]="jump, (hold) place/RMB & press right",
			["Left sideflip"]="jump, (hold) place/RMB & press left",
			["Roll"]="sneak when falling from a height",
			["Dive roll"]="place/RMB and press up",
		}
		table.sort(l)
		for i,v in pairs(l) do
			t = t .. "label[-0.2,"..y..";"..i.."]label[2.5,"..y..";"..v.."]"
			y = y + 0.5
		end
		t = t .. "label[-0.2,"..y..";You can use all flips to reach more height and come over\nobstacles on 2 blocks while running, but sideflips wont hurt\non obstacles and there is no risk you breaks your neck.]"
		return t
	end
})

player_style.itemstrings_to_image=function(text,label)
	label = label or ""
	local i2 = 1
	local t = ""
	local text2 = text
	local x = 0
	for i=1,text:len() do
		if text:sub(i,i) == " " then
			local item = text:sub(i2,i-1)
			local def = minetest.registered_items[item]
			if def and item:find(":") then
				t = t .. "item_image["..x..",0.5;1,1;"..item.."]tooltip["..x..",0.5;1,1;"..(def.description or item).."]"
				text2 = text2:gsub(item.." ","")
				x = x + 1
			end
			i2 = i+1
		end
	end
	return t .. "label[0,-0.1;"..label.."]textarea[0,1.5;12,10;;;"..text2.."]"
end

minetest.register_on_mods_loaded(function(player)
	for i, def in ipairs(player_style.buttons.low_priority) do
		player_style.register_button(def)
	end
	for i, def in ipairs(player_style.buttons.lower_priority) do
		player_style.register_button(def)
	end

	for i,v in pairs(minetest.registered_items) do
		if (v.manual_page or v.manual_page_func) and not (v.groups and (v.groups.unbreakable)) then
			player_style.register_manual_page({
				name = v.description or i,
				itemstyle = i,
				item = true,
				text = player_style.itemstrings_to_image(v.manual_page_func and v.manual_page_func() or v.manual_page,v.description or i),
				action = v.manual_page_action,
				tags = v.manual_page_tags,
			})
		end
	end
	for i,v in pairs(minetest.registered_entities) do
		if v.manual_page then
			local def = minetest.registered_items[i]
			player_style.register_manual_page({
				item = true,
				name = def and def.description or i,
				text = player_style.itemstrings_to_image(v.manual_page,def and def.description or i),
				action=v.manual_page_action,
				tags = v.manual_page_tags,
			})
		end
	end
end)