local function mannequin_formspec(pos, start)
   start = start or 0
   local spos = pos.x ..','.. pos.y ..','.. pos.z
   local formspec =
      'formspec_version[3]'..
      'size[10.25,7.5]'..
      'listcolors[#00000069;#5a5a5a]'..
      'textarea[.5,.5;9.75,2;;;Show off some articles of clothing.]'..
      'list[detached:creative_trash;main;9,2.5;1,1;]'..
      'image[9,2.5;1,1;creative_trash_icon.png]'..
      'button[.5,6.5;.75,.75;prev;<]'..
      'button[9,6.5;.75,.75;next;>]'..
      'list[nodemeta:'..spos..';clothes;.25,1.25;8,1;]'..
      'list[detached:clothing_list;main;.25,4.0;8,2;'..start..']'..
      'listring[]'..
      'button_exit[4,6.5;2.25,.75;;close]'
   return formspec
end

minetest.register_on_player_receive_fields(function(player, formname, fields)
   if formname == 'clothing:mannequin' then
      local name = player:get_player_name()
      local pos = tasks.player_config[name]
      local meta = minetest.get_meta(pos)
      local start = meta:get_int('start')
      if fields.prev then
         start = start - 16
         start = math.max(start, 0)
         meta:set_int('start', start)
         minetest.show_formspec(name, 'clothing:mannequin', mannequin_formspec(pos, start))
      elseif fields.next then
         if start + 16 <= clothing.inv_size then
            start = start + 16
         end
         meta:set_int('start', start)
         minetest.show_formspec(name, 'clothing:mannequin', mannequin_formspec(pos, start))
      end
   end
end)

local function update_entity(pos, pose)
   local node = minetest.get_node(pos)
   if node.name == 'clothing:mannequin_'..pose then
      local clothes = nil
      for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do
         local entity = obj:get_luaentity()
         if entity then
            if entity.name == 'clothing:mannequin_'..pose..'_entity' then
               if clothes then
                  obj:remove()
               else
                  clothes = obj
               end
            end
         end
      end
      if not clothes then
         clothes = minetest.add_entity(pos, 'clothing:mannequin_'..pose..'_entity')
         clothes:set_yaw(math.pi * 2 - node.param2 * math.pi / 2)
      end
      local meta = minetest.get_meta(pos)
      local inv = meta:get_inventory(pos)
      local clothing_texture = {}
      for i = 1,8 do
         local item = inv:get_stack('clothes', i)
         local def = item:get_definition() or {}
         if def.tex then
            clothing_texture[#clothing_texture+1] = def.tex
         end
      end
      local texture = table.concat(clothing_texture, '^')
      if texture == '' then
         texture = 'blank.png'
      end
      clothes:set_properties({textures = {texture}})
      clothes:set_yaw(math.pi * 2 - node.param2 * math.pi / 2)
   else
      for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do
         obj:remove()
      end
   end
end

minetest.register_node('clothing:mannequin_standing', {
   description = 'Standing Mannequin',
   drawtype = 'mesh',
   mesh = 'clothing_mannequin_standing.obj',
   tiles = {'clothing_mannequin.png'},
   paramtype = 'light',
   paramtype2 = 'facedir',
   groups = {breakable=1},
   selection_box = {
      type = 'fixed',
      fixed = {-.45, -.5, -.125, .45, .75, .125},
      },
   collision_box = {
      type = 'fixed',
      fixed = {-.45, -.5, -.125, .45, .75, .125},
      },
   on_construct = function(pos)
      local meta = minetest.get_meta(pos)
      local inv = meta:get_inventory()
      inv:set_size('clothes', 8)
   end,
   on_rightclick = function(pos, node, clicker)
      local name = clicker:get_player_name()
      if not minetest.is_protected(pos, name) or minetest.check_player_privs(name, {server = true}) then
         local meta = minetest.get_meta(pos)
         meta:set_int('start', 0)
         tasks.player_config[name] = pos
         minetest.show_formspec(name, 'clothing:mannequin', mannequin_formspec(pos))
      end
   end,
   allow_metadata_inventory_put = function(pos, listname, index, stack)
      local def = stack:get_definition() or {}
      local groups = def.groups or {}
      if groups['clothing'] then
         return 1
      end
      return 0
   end,
   on_metadata_inventory_put = function(pos)
      update_entity(pos, 'standing')
   end,
   on_metadata_inventory_move = function(pos)
      update_entity(pos, 'standing')
   end,
   on_metadata_inventory_take = function(pos)
      update_entity(pos, 'standing')
   end,
   after_destruct = function(pos)
      update_entity(pos, 'standing')
   end
})

minetest.register_entity('clothing:mannequin_standing_entity', {
   visual = 'mesh',
   mesh = 'clothing_mannequin_standing_clothes.obj',
   visual_size = {x=10, y=10, z=10.1},
   collisionbox = {0},
   physical = false,
   textures = {'blank.png'},
   on_activate = function(self)
      local pos = self.object:get_pos()
      local name = minetest.get_node(pos).name
      if name ~= 'clothing:mannequin_standing' then
         self.object:remove()
      else
         update_entity(pos, 'standing')
      end
   end
})
