local init = os.clock()
local path = minetest.get_modpath(minetest.get_current_modname())

local filepath = minetest.get_worldpath()

CREATIVE_SEARCH_ITEMS = ""

local creative_type = "search"

filepath = minetest.get_worldpath()
se = {}

function save_player_data()
	local file = io.open(filepath .. "/playerdata.txt", "w")
	file:write(minetest.serialize(playerdata))
	file:close()
end

function load_player_data()
	local file = io.open(filepath .. "/playerdata.txt", "r")
	if file then
		local table = minetest.deserialize(file:read("*all"))
		if type(table) == "table" then
			return table
			
		end
	end
	return {}
end



inventory = {}
inventory.inventory_size = 0
pagenum = 0
playerdata = load_player_data()

dofile(path.."/config.txt")
dofile(path.."/api.lua")
dofile(path.."/workbench.lua")

local function save_newplayer(pname)
	if not playerdata[pname] then
		playerdata[pname] = {}
		playerdata[pname]['isPlayer'] = true
		playerdata[pname]['gamemode'] = Default_Mode
		save_player_data()
		minetest.after(1, function() load_player_data() end)
		playerdata = load_player_data()
	end
end

minetest.register_on_joinplayer(function(player)
	local pname = player:get_player_name()
	local playerdata = load_player_data()
	if not playerdata[pname] then
		playerdata[pname] = {}
		playerdata[pname]['isPlayer'] = true
		playerdata[pname]['gamemode'] = Default_Mode
		save_player_data()

	end
	if not playerdata[pname]['gamemode'] then
		playerdata[pname]['gamemode'] = Default_Mode
		save_player_data()
		playerdata = load_player_data()
		minetest.after(1, function() updategamemode(pname, "0") end)
	else
		minetest.after(1, function() updategamemode(pname, "0") end)
	end
end)

--Ensure that all mods are loaded before editing inventory.
minetest.after(0.3, function()
local trash = minetest.create_detached_inventory("creative_trash", {
		-- Allow the stack to be placed and remove it in on_put()
		-- This allows the creative inventory to restore the stack
		allow_put = function(inv, listname, index, stack, player)
				return stack:get_count()
		end,
		on_put = function(inv, listname, index, stack, player)
			inv:set_stack(listname, index, "")
		end,
})
trash:set_size("main", 1)


local creative_list = {}
for name,def in pairs(minetest.registered_items) do
		if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0)
				and def.description and def.description ~= "" then
			table.insert(creative_list, name)
		end

end


local inv = minetest.create_detached_inventory("creative", {
		allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
				return count
		end,
		allow_put = function(inv, listname, index, stack, player)
			return 0
		end,
		allow_take = function(inv, listname, index, stack, player)
				return -1
		end,
		on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
		end,
		on_put = function(inv, listname, index, stack, player)
		end,
		on_take = function(inv, listname, index, stack, player)
			print(player:get_player_name().." takes item from creative inventory; listname="..dump(listname)..", index="..dump(index)..", stack="..dump(stack))
			if stack then
				print("stack:get_name()="..dump(stack:get_name())..", stack:get_count()="..dump(stack:get_count()))
			end
		end,
	})
	
table.sort(creative_list)

inv:set_size("main", #creative_list)

for _,itemstring in ipairs(creative_list) do
        local stack = ItemStack(itemstring)
        local stack2 = nil
        if stack:get_stack_max() == 1 then
            stack2 = ItemStack(stack:get_name())
        else
            stack2 = ItemStack(stack:get_name().." "..(stack:get_stack_max()))--- for know how many item
        end
        inv:add_item("main", stack2)
end
	inventory.inventory_size = #creative_list

end)	

-- Create detached creative inventory after loading all mods
function updategamemode(pname, status)
	playerdata = load_player_data()
	if not status then
		print(pname.." has switched to "..playerdata[pname]['gamemode'].." Mode.")
		minetest.chat_send_all(pname.." has switched to "..playerdata[pname]['gamemode'].." Mode.")
	end
	print(playerdata[pname])
	if playerdata[pname] == nil then
		save_newplayer(pname)
	end
	if playerdata[pname]['gamemode'] == "Creative" then
		local player = minetest.env:get_player_by_name(pname)
		inventory.set_player_formspec(player, 1, 1)
	else
	
	local player = minetest.env:get_player_by_name(pname)
	inventory.set_player_formspec(player, 1, 1)

	end
end
inventory.set_player_formspec = function(player, start_i, pagenum)
playerdata = load_player_data()
	if playerdata[player:get_player_name()]['gamemode'] == "Creative" then
		inventory.creative_inv(player)
		inventory.hotbar(player)
	end
	
	if creative_type == "search" and playerdata[player:get_player_name()]['gamemode'] == "Creative" then
		local pagenum = math.floor(pagenum)
		local pagemax = math.floor((inventory.inventory_size-1) / (9*3) + 1)
		CREATIVE_SEARCH_ITEMS = "invsize[10,7;]"..
		"background[-0.22,-0.25;10.8,7.7;creative_inventory_bg.png]"..
			"button[8,0;1.5,1;creative_search;Search]"..
			"list[current_player;main;0.21,6.05;9,1;]"..
			"list[detached:creative;main;0.21,2.78;9,3;"..tostring(start_i).."]"..
			"label[7.25,1.7;"..tostring(pagenum).."/"..tostring(pagemax).."]"..
			"button[5.5,1.5;1.5,1;creative_prev;<<]"..
			"button[8,1.5;1.5,1;creative_next;>>]"..
			"button[5.5,0;1.5,1;creative_survival;Survival]"..
			"list[detached:creative_trash;main;9.28,6.05;1,1;]"
		player:set_inventory_formspec(CREATIVE_SEARCH_ITEMS)
		inventory.hotbar(player)
	end
	if playerdata[player:get_player_name()]['gamemode'] == "Survival" then
		inventory.survival_inv(player)
		inventory.hotbar(player)
	end
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
	if playerdata[player:get_player_name()]['gamemode'] == "Survival" then
		return
	end
	-- Figure out current page from formspec
	local current_page = 0
	local formspec = player:get_inventory_formspec()
	local start_i = string.match(formspec, "list%[detached:creative;main;[%d.]+,[%d.]+;[%d.]+,[%d.]+;(%d+)%]")
	start_i = tonumber(start_i) or 0

	if fields.clear_inventory then
		local inventory = {}
		player:get_inventory():set_list("main", inventory)
	end
	
	if fields.creative_search then
		creative_type = "search"
	end
	
	if fields.creative_survival then
		creative_type = "default"
		inventory.creative_inv(player)
	end
	
	if fields.creative_prev then
		start_i = start_i - 9*3
	end
	if fields.creative_next then
		start_i = start_i + 9*3
	end

	if start_i < 0 then
		start_i = start_i + 9*3
	end
	if start_i >= inventory.inventory_size then
		start_i = start_i - 9*3
	end
		
	if start_i < 0 or start_i >= inventory.inventory_size then
		start_i = 0
	end
	
	inventory.set_player_formspec(player, start_i, start_i / (9*3) + 1)
end)

local gm_priv = false

if minetest.setting_getbool("creative_mode")==false then
	 gm_priv = true
elseif minetest.setting_getbool("creative_mode")==true then
	 gm_priv = false
end

minetest.register_chatcommand('gamemode',{
	params = "1, c | 0, s",
	description = 'Switch your gamemode',
	privs = {gamemode = gm_priv},
	func = function(name, param)
		if param == "1" or param == "c" then
			playerdata[name]['gamemode'] = "Creative"
			save_player_data()
			minetest.chat_send_player(name, 'Your gamemode is now: '..playerdata[name]['gamemode'])
			updategamemode(name)
		elseif param == "0" or param == "s" then
			playerdata[name]['gamemode'] = "Survival"
			save_player_data()
			minetest.chat_send_player(name, 'Your gamemode is now: '..playerdata[name]['gamemode'])
			updategamemode(name)
		else
			minetest.chat_send_player(name, "Error: That player does not exist!")
			return false
		end
	end
})


--[[minetest.register_on_punchnode(function(pos, node, puncher)
	local pos = pos
	local pname = puncher:get_player_name()
	if playerdata[pname]['gamemode'] == "Creative" then
	minetest.after(0.1, function()
	minetest.env:remove_node(pos)
	end)
	end
end)]]

minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
	local pname = placer:get_player_name()
	if playerdata[pname]['gamemode'] == "Creative" then
	return true
	end
end)

minetest.register_privilege("gamemode", "Permission to use /gamemode.")
local time_to_load= os.clock() - init
print(string.format("[MOD] "..minetest.get_current_modname().." loaded in %.4f s", time_to_load))