local jewelry_formspec =
'size[8,8.5]'..
'list[current_name;jewelry;.5,0;1,1;]'..
'list[current_name;crystal;1.5,0;1,1;]'..
'list[current_name;mese;3,0;1,1;]'..
'image[3,0;1,1;armor_mese_outline.png]'..
'list[current_name;orb;4,0;1,1;]'..
'image[4,0;1,1;armor_orb_outline.png]'..
'list[current_name;output;6,.5;1,1;]'..
'list[current_name;relics;1,3;6,1;]'..
'list[current_player;main;0,4.5;8,4;]'..
'button[5.75,1.55;1.5,.75;forge;Forge]'..
'textarea[.5,1;5.5,2.25;;;Currently gloves aren\'t working!\n'..
'Input a plain ring, amulet or pair of gloves, and a Gemstone with the perk you want added.'..
'\nYou\'ll also need a mese crystal and lava orb.'..
'\nRelics can be added to tweak the chances that control how powerful the outputted item will be.'..
' Relics are not typically consumed and can be used time and time again.]'..
'label[0,3;Relics\n--->]'

minetest.register_node('stations:jewelry', {
   description = 'Jewelry Workshop',
   drawtype = 'mesh',
   mesh = 'stations_jewelry.obj',
   tiles = {'stations_jewelry.png'},
   use_texture_alpha = 'opaque',
   sounds = default.node_sound_metal_defaults(),
   paramtype2 = 'facedir',
   paramtype = 'light',
   selection_box = {
      type = 'fixed',
      fixed = {
         {-.5, -.5, -.5, 1.5, .5, .5},
         }
      },
   collision_box = {
      type = 'fixed',
         {-.5, -.5, -.5, 1.5, .5, .5},
      },
   groups = {oddly_breakable_by_hand=3, cracky=1},
   on_construct = function(pos)
      local meta = minetest.get_meta(pos)
      local inv = meta:get_inventory()
      inv:set_size('main', 8*4)
      inv:set_size('jewelry', 1)
      inv:set_size('mese', 1)
      inv:set_size('orb', 1)
      inv:set_size('crystal', 1)
      inv:set_size('output', 1)
      inv:set_size('relics', 6)
      meta:set_string('infotext', 'Jewelry Workshop')
      meta:set_string('formspec', jewelry_formspec)
   end,
   after_place_node = function(pos, placer, itemstack)
      if not epic.space_to_side(pos) then
         minetest.remove_node(pos)
         return itemstack
      end
   end,
   can_dig = function(pos,player)
      local meta = minetest.get_meta(pos);
      local inv = meta:get_inventory()
      if inv:is_empty('jewelry') and inv:is_empty('mese') and inv:is_empty('orb')
      and inv:is_empty('crystal') and inv:is_empty('output') then
         return true
      else
         return false
      end
   end,
   after_dig_node = function(pos, oldnode, oldmetadata, digger)
      epic.remove_side_node(pos, oldnode)
   end,
   allow_metadata_inventory_put = function(pos, listname, index, stack, player)
      local input = stack:get_name()
      if listname == 'jewelry' then
         if input == 'armor:ring_gol' or input == 'armor:ring_tit' --[[or input == 'armor:gloves']]
         or input == 'armor:amulet_gol' or input == 'armor:amulet_tit' then
            return 99
         else
            return 0
         end
      elseif listname == 'mese' then
         if input == 'default:mese_crystal' then
            return 99
         else
            return 0
         end
      elseif listname == 'orb' then
         if input == 'mobs:lava_orb' then
            return 99
         else
            return 0
         end
      elseif listname == 'crystal' then
         if input == 'epic:float_crystal' or input == 'epic:bloodstone' or input == 'epic:huntite'
         or input == 'ocean:prismarine_crystals' or input == 'epic:garnet' or input == 'quartz:quartz_crystal_piece' then
            return 99
         else
            return 0
         end
      elseif listname == 'output' then
         return 0
      end
      return 1
   end,
   allow_metadata_inventory_move = function(pos, listname, index, stack, player)
      return 0
   end,
   can_dig = function(pos,player)
      local meta = minetest.get_meta(pos);
      local inv = meta:get_inventory()
      if inv:is_empty('jewelry') and inv:is_empty('mese') and inv:is_empty('orb')
      and inv:is_empty('crystal') and inv:is_empty('output') and inv:is_empty ('relics') then
         return true
      else
         return false
      end
   end,
   on_receive_fields = function(pos, formname, fields, sender)
      local meta = minetest.get_meta(pos)
      local inv = meta:get_inventory(pos)
      local output = inv:get_stack('output', 1)
      local output_count = output:get_count()
      if fields['forge'] and output_count == 0 then
         local jewelry = inv:get_stack('jewelry', 1)
         local mese = inv:get_stack('mese', 1)
         local orb = inv:get_stack('orb', 1)
         local crystal = inv:get_stack('crystal', 1)
         local relics = inv:get_list('relics')
         local jewelry_name = jewelry:get_name()
         local mese_name = mese:get_name()
         local orb_name = orb:get_name()
         local crystal_name = crystal:get_name()
         local perk = 'nothing'
         if crystal_name == 'epic:float_crystal' then
            perk = 'gravity'
         elseif crystal_name == 'epic:bloodstone' then
            perk = 'healing'
         elseif crystal_name == 'epic:huntite' then
            perk = 'fire'
         elseif crystal_name == 'ocean:prismarine_crystals' then
            perk = 'water'
         elseif crystal_name == 'epic:garnet' then
            perk = 'speed'
         elseif crystal_name == 'quartz:quartz_crystal_piece' then
            perk = 'jump'
         end
         local level = 0
         if type(relics) == 'table' then
            for i, stack in pairs(relics) do
               local def = stack:get_definition()
               if def.groups['relic_general'] then
                  level = level + def.groups['relic_general']
               end
               if def.groups['relic_'..perk] then
                  level = level + def.groups['relic_'..perk]
               end
            end
         end
         --If you're looking at the code to see how this works please don't spoil it for other players.
         --If I expect that is going on, I'll be forced to change things around, and not release the code.
         local random = math.random(0, 100)
         local chance = random + level
         local tier = 1
         if chance < 0 then
            tier = 0
         elseif chance > 0 and chance <= 80 then
            tier = 1
         elseif chance > 80 and chance <= 90 then
            tier = 2
         elseif chance > 90 and chance <= 98 then
            tier = 3
         elseif chance > 98 and chance <= 100 then
            tier = 4
         end
         local phase = moon_phases.get_phase()
         local time_of_day = minetest.get_timeofday()
         if phase == 4 and (time_of_day < .2 or time_of_day > .8) then
            tier = tier + 1
         end
         if perk ~= 'nothing' and jewelry_name ~= '' and mese_name ~= '' and orb_name ~= '' and tier ~= 0 then
            jewelry:take_item(1)
            mese:take_item(1)
            orb:take_item(1)
            crystal:take_item(1)
            inv:set_stack('jewelry', 1, jewelry)
            inv:set_stack('mese', 1, mese)
            inv:set_stack('orb', 1, orb)
            inv:set_stack('crystal', 1, crystal)
            inv:set_stack('output', 1, jewelry_name..'_'..perk..'_'..tier)
            minetest.log("action", sender:get_player_name() .. " crafts "..jewelry_name..'_'..perk..'_'..tier)
         else
            jewelry:take_item(1)
            mese:take_item(1)
            orb:take_item(1)
            crystal:take_item(1)
            inv:set_stack('jewelry', 1, jewelry)
            inv:set_stack('mese', 1, mese)
            inv:set_stack('orb', 1, orb)
            inv:set_stack('crystal', 1, crystal)
         end
      end
   end,
   on_rotate = function(pos, node)
      return false
   end,
})

minetest.register_node('stations:jewelry_locked', {
   description = 'Jewelry Workshop (Locked)',
   drawtype = 'mesh',
   mesh = 'stations_jewelry.obj',
   tiles = {'stations_jewelry.png'},
   use_texture_alpha = 'opaque',
   sounds = default.node_sound_metal_defaults(),
   paramtype2 = 'facedir',
   paramtype = 'light',
   selection_box = {
      type = 'fixed',
      fixed = {
         {-.5, -.5, -.5, 1.5, .5, .5},
         }
      },
   collision_box = {
      type = 'fixed',
         {-.5, -.5, -.5, 1.5, .5, .5},
      },
   groups = {oddly_breakable_by_hand=3, cracky=1},
   on_construct = function(pos)
      local meta = minetest.get_meta(pos)
      local inv = meta:get_inventory()
      inv:set_size('main', 8*4)
      inv:set_size('jewelry', 1)
      inv:set_size('mese', 1)
      inv:set_size('orb', 1)
      inv:set_size('crystal', 1)
      inv:set_size('output', 1)
      inv:set_size('relics', 6)
      meta:set_string('infotext', 'Jewelry Workshop (Locked)')
      meta:set_string('formspec', jewelry_formspec)
   end,
   after_place_node = function(pos, placer, itemstack)
      if not epic.space_to_side(pos) then
         minetest.remove_node(pos)
         return itemstack
      end
   end,
   can_dig = function(pos,player)
      local meta = minetest.get_meta(pos);
      local inv = meta:get_inventory()
      if inv:is_empty('jewelry') and inv:is_empty('mese') and inv:is_empty('orb')
      and inv:is_empty('crystal') and inv:is_empty('output') then
         return true
      else
         return false
      end
   end,
   after_dig_node = function(pos, oldnode, oldmetadata, digger)
      epic.remove_side_node(pos, oldnode)
   end,
   allow_metadata_inventory_put = function(pos, listname, index, stack, player)
      local input = stack:get_name()
      if listname == 'jewelry' then
         if input == 'armor:ring_gol' or input == 'armor:ring_tit' --[[or input == 'armor:gloves']]
         or input == 'armor:amulet_gol' or input == 'armor:amulet_tit' then
            return 99
         else
            return 0
         end
      elseif listname == 'mese' then
         if input == 'default:mese_crystal' then
            return 99
         else
            return 0
         end
      elseif listname == 'orb' then
         if input == 'mobs:lava_orb' then
            return 99
         else
            return 0
         end
      elseif listname == 'crystal' then
         if input == 'epic:float_crystal' or input == 'epic:bloodstone' or input == 'epic:huntite'
         or input == 'ocean:prismarine_crystals' or input == 'epic:garnet' or input == 'quartz:quartz_crystal_piece' then
            return 99
         else
            return 0
         end
      elseif listname == 'output' then
         return 0
      end
      return 1
   end,
   allow_metadata_inventory_move = function(pos, listname, index, stack, player)
      return 0
   end,
   can_dig = function(pos,player)
      local meta = minetest.get_meta(pos);
      local inv = meta:get_inventory()
      if inv:is_empty('jewelry') and inv:is_empty('mese') and inv:is_empty('orb')
      and inv:is_empty('crystal') and inv:is_empty('output') and inv:is_empty ('relics') then
         return true
      else
         return false
      end
   end,
   on_receive_fields = function(pos, formname, fields, sender)
      local meta = minetest.get_meta(pos)
      local inv = meta:get_inventory(pos)
      local output = inv:get_stack('output', 1)
      local output_count = output:get_count()
      if fields['forge'] and output_count == 0 then
         local jewelry = inv:get_stack('jewelry', 1)
         local mese = inv:get_stack('mese', 1)
         local orb = inv:get_stack('orb', 1)
         local crystal = inv:get_stack('crystal', 1)
         local relics = inv:get_list('relics')
         local jewelry_name = jewelry:get_name()
         local mese_name = mese:get_name()
         local orb_name = orb:get_name()
         local crystal_name = crystal:get_name()
         local perk = 'nothing'
         if crystal_name == 'epic:float_crystal' then
            perk = 'gravity'
         elseif crystal_name == 'epic:bloodstone' then
            perk = 'healing'
         elseif crystal_name == 'epic:huntite' then
            perk = 'fire'
         elseif crystal_name == 'ocean:prismarine_crystals' then
            perk = 'water'
         elseif crystal_name == 'epic:garnet' then
            perk = 'speed'
         elseif crystal_name == 'quartz:quartz_crystal_piece' then
            perk = 'jump'
         end
         local level = 0
         if type(relics) == 'table' then
            for i, stack in pairs(relics) do
               local def = stack:get_definition()
               if def.groups['relic_general'] then
                  level = level + def.groups['relic_general']
               end
               if def.groups['relic_'..perk] then
                  level = level + def.groups['relic_'..perk]
               end
            end
         end
         --If you're looking at the code to see how this works please don't spoil it for other players.
         --If I expect that is going on, I'll be forced to change things around, and not release the code.
         local random = math.random(0, 100)
         local chance = random + level
         local tier = 1
         if chance < 0 then
            tier = 0
         elseif chance > 0 and chance <= 80 then
            tier = 1
         elseif chance > 80 and chance <= 90 then
            tier = 2
         elseif chance > 90 and chance <= 98 then
            tier = 3
         elseif chance > 98 and chance <= 100 then
            tier = 4
         end
         local phase = moon_phases.get_phase()
         local time_of_day = minetest.get_timeofday()
         if phase == 4 and (time_of_day < .2 or time_of_day > .8) then
            tier = tier + 1
         end
         if perk ~= 'nothing' and jewelry_name ~= '' and mese_name ~= '' and orb_name ~= '' and tier ~= 0 then
            jewelry:take_item(1)
            mese:take_item(1)
            orb:take_item(1)
            crystal:take_item(1)
            inv:set_stack('jewelry', 1, jewelry)
            inv:set_stack('mese', 1, mese)
            inv:set_stack('orb', 1, orb)
            inv:set_stack('crystal', 1, crystal)
            inv:set_stack('output', 1, jewelry_name..'_'..perk..'_'..tier)
            minetest.log("action", sender:get_player_name() .. " crafts "..jewelry_name..'_'..perk..'_'..tier)
         else
            jewelry:take_item(1)
            mese:take_item(1)
            orb:take_item(1)
            crystal:take_item(1)
            inv:set_stack('jewelry', 1, jewelry)
            inv:set_stack('mese', 1, mese)
            inv:set_stack('orb', 1, orb)
            inv:set_stack('crystal', 1, crystal)
         end
      end
   end,
   allow_metadata_inventory_take = function(pos, listname, index, stack, player)
      local player_name = player:get_player_name()
      if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(player, 'protection_bypass') then
         return 0
      else
         return 99
      end
   end,
   on_rotate = function(pos, node)
      return false
   end,
})

unified_inventory.register_craft_type("jewelry", {
   description = "Jewelry Workshop",
   icon = 'stations_jewelry_icon.png',
   width = 4,
   height = 1,
   uses_crafting_grid = false
})
