local sounds_table = {
   'coniferous_forest', 'deciduous_forest', 'desert', 'grassland', 'icesheet', 'ocean_beach', 'rainforest' , 'savanna', 'engines', 'office_noise', 'traffic_intersection', 'construction_noise',
   'washing_machine', 'subway', 'energy_wave', 'pulsing_vibrations', 'radio_static', 'spraying_water', 'underwater', 'coyote', 'small_river', 'pub_ambience'
}

local function formspec_selection(sound, dist)
   local formspec =
   'size[6,3]'..
   'textarea[.5,.25;5.5,2;;;Select the sound you want to play, and the distance it should be audible.]'..
   'dropdown[.5,1.5;4,1;Sound;'..table.concat(sounds_table, ',')..';'..sound..']'..
   'dropdown[4.5,1.5;1,1;Distance;1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16;'..dist..']'..
   'button_exit[2,2.25;2,1;save;Save]'
   return formspec
end

minetest.register_node('sounds:speaker', {
   description = 'Speaker',
   tiles = {'sounds_speaker.png'},
   paramtype = 'light',
   paramtype2 = 'facedir',
   selection_box = {
      type = 'fixed',
      fixed = {-.5, -.5, -.5, .5, .5, .5}},
   collision_box = {
      type = 'fixed',
      fixed = {-.5, -.5, -.5, .5, .5, .5}},
   groups = {breakable=1},
   on_construct = function(pos)
      local meta = minetest.get_meta(pos)
      meta:set_int('sound_index', 1)
      meta:set_int('dist', 10)
      meta:set_string('formspec', formspec_selection(1, 10))
   end,
   on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
      local meta = minetest.get_meta(pos)
      local sound_index = meta:get_int('sound_index')
      local dist = meta:get_int('dist')
      meta:set_string('formspec', formspec_selection(sound_index, dist))
   end,
   on_receive_fields = function(pos, forname, fields, sender)
      local meta = minetest.get_meta(pos)
      local name = sender:get_player_name()
      if not minetest.is_protected(pos, name) and minetest.check_player_privs(name, { creative = true }) then
         if fields ['save'] then
            meta:set_string('sound', fields.Sound)
            meta:set_int('dist', fields.Distance)
            minetest.sound_play(fields.Sound, {to_player = name, gain = 1})
            for i, sounds_index in ipairs(sounds_table) do
               if sounds_index == fields.Sound then
                  meta:set_int('sound_index', i)
               end
            end
         end
      end
   end,
})

minetest.register_abm({
   nodenames = {'sounds:speaker'},
   interval = 60,
   chance = 5,
   action = function(pos)
      local meta = minetest.get_meta(pos)
      local sound = meta:get_string('sound')
      local dist = meta:get_int('dist')
      minetest.sound_play(sound, {pos = pos, gain = 1, max_hear_distance = dist})
   end,
})

minetest.register_abm({
   nodenames = {'group:plays_sound'},
   interval = 60,
   chance = 10,
   action = function(pos)
      local node = minetest.get_node(pos)
      local def = minetest.registered_nodes[node.name]
      local sound = def._sound
      minetest.sound_play(sound, {pos = pos, gain = 1, max_hear_distance = 5})
   end
})
