minetest.register_tool('tasks:configurator', {
   description = 'Configurator Wrench',
   inventory_image = 'tasks_wrench.png',
   on_use = function(itemstack, user, pointed_thing)
      local pos = minetest.get_pointed_thing_position(pointed_thing)
      if pos then
         local name = user:get_player_name()
         local node = minetest.get_node(pos)
         if not minetest.is_protected(pos, name) or minetest.check_player_privs(name, {server = true}) then
            tasks.player_config[name] = pos
            if minetest.get_item_group(node.name, 'tasks') > 0 then
               tasks.configure(pos, name)
            elseif minetest.get_item_group(node.name, 'door') > 0 then
               doors.lock(pos, name)
            elseif minetest.get_item_group(node.name, 'stash') > 0 then
               tasks.stash(pos, name)
            end
         end
      end
   end,
   on_drop = lobby.no_drop
})

function tasks.configure(pos, name)
   local meta = minetest.get_meta(pos)
   local infotext = meta:get_string('infotext')
   local time_min = meta:get_int('time_min') or 60
   local time_max = meta:get_int('time_max') or 120
   local xp = meta:get_int('xp') or 5
   minetest.show_formspec(name, 'tasks:configuration', tasks.configuration_formspec(infotext, time_min, time_max, xp))
end

minetest.register_on_player_receive_fields(function(player, formname, fields)
   local name = player:get_player_name()
   if formname == 'tasks:configuration' then
      if fields.save then
         if tasks.is_integer(fields.time_min) and tasks.is_integer(fields.time_max) and tasks.is_integer(fields.xp)
            and tonumber(fields.time_max) >= tonumber(fields.time_min) then
               local pos = tasks.player_config[name]
               local meta = minetest.get_meta(pos)
               local timer = minetest.get_node_timer(pos)
               meta:set_int('time_min', math.max(fields.time_min,5))
               meta:set_int('time_max', math.max(fields.time_max,20))
               meta:set_int('xp', fields.xp)
               meta:set_string('infotext', fields.infotext)
               local random_number = math.random(fields.time_min, fields.time_max)
               timer:start(random_number)
         else
            minetest.chat_send_player(name, 'Please check your inputs.')
         end
      end
   end
end)

function tasks.configuration_formspec(infotext, time_min, time_max, xp)
   local formspec =
      'formspec_version[3]'..
      'size[8,6]'..
      'textarea[.5,.5;7,2;;;Set the minimum and maximum time a task will run before breaking down, and the XP to be awarded upon completion of the task. '..
      'Minimum time must be 5 or more seconds, and max time must be 20 or more seconds. Whole numbers only.\n'..
      'Pro-tip, set the min and max times the same to remove randomization.]'..
      'field[1,3;6,.5;infotext;Infotext;'..infotext..']'..
      'field[1,4;2,.5;time_min;Minimum time;'..time_min..']'..
      'field[5,4;2,.5;time_max;Maximum time;'..time_max..']'..
      'field[1,5;2,.5;xp;XP;'..xp..']'..
      'button_exit[5,5;2,.5;save;Submit]'
   return formspec
end

function tasks.stash(pos, name)
   local meta = minetest.get_meta(pos)
   local inv = meta:get_inventory()
   inv:set_size('stash', 8)
   local infotext = meta:get_string('infotext')
   minetest.show_formspec(name, 'tasks:stash', tasks.stash_formspec(pos, infotext))
end

function tasks.stash_formspec(pos, infotext)
   local spos = pos.x ..','.. pos.y ..','.. pos.z
   local formspec =
      'formspec_version[3]'..
      'size[10.25,7.5]'..
      'listcolors[#00000069;#5a5a5a]'..
      'textarea[.5,1.5;9.75,2;;;Place items above to let people find them in this node. If their search is successful they will randomly get one of the items here. Blanks will give nothing.]'..
      'field[1,3.0;5,.5;infotext;Infotext;'..infotext..']'..
      'list[detached:creative_trash;main;9,2.5;1,1;]'..
      'image[9,2.5;1,1;creative_trash_icon.png]'..
      'list[nodemeta:'..spos..';stash;.25,.25;8,1;]'..
      'list[detached:tasks_stash;main;.25,4.0;8,2;]'..
      'listring[]'..
      'button_exit[4,6.5;2.25,.75;save;Submit]'
   return formspec
end

minetest.register_on_player_receive_fields(function(player, formname, fields)
   local name = player:get_player_name()
   if formname == 'tasks:stash' then
      if fields.save then
         local pos = tasks.player_config[name]
         local meta = minetest.get_meta(pos)
         meta:set_string('infotext', fields.infotext)
      end
   end
end)

minetest.create_detached_inventory('tasks_stash', {
   allow_put = function(inv, listname, index, stack, player2)
      return 0
   end,
   allow_take = function(inv, listname, index, stack, player2)
      local name = player2 and player2:get_player_name() or ''
      if not creative.is_enabled_for(name) then
         return 0
      end
      return -1
   end,
   on_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
   end,
})

local stashable = {}
minetest.register_on_mods_loaded(function()
   for name, def in pairs(minetest.registered_items) do
      local group = def.groups or {}
      if group.stashable then
         stashable[name] = def
      end
   end
   local list = {}
   for name, def in pairs(stashable) do
      list[#list+1] = name
   end
   local stash_inv = minetest.get_inventory({type = 'detached', name = 'tasks_stash'})
   stash_inv:set_size('main', #list)
   stash_inv:set_list('main', list)
end)
