
-- bell_positions are saved through server restart
-- bells ring every hour
-- they ring as many times as a bell ought to

bell = {};

bell.RING_INTERVAL = 3600; --60*60; -- ring each hour

bell.BELL_SAVE_FILE = minetest.get_worldpath().."/bell_positions.data";

local bell_positions = {};


bell.save_bell_positions = function( player )
  
   str = minetest.serialize( ({ bell_data = bell_positions}) );

   local file, err = io.open( bell.BELL_SAVE_FILE, "wb");
   if (err ~= nil) then
      if( player ) then
         minetest.chat_send_player(player:get_player_name(), "Error: Could not save bell data");
      end
      return
   end
   file:write( str );
   file:flush();
   file:close();
   --minetest.chat_send_all("Wrote data to savefile "..tostring( bell.BELL_SAVE_FILE ));
end


bell.restore_bell_data = function()

   local bell_position_table;

   local file, err = io.open(bell.BELL_SAVE_FILE, "rb");
   if (err ~= nil) then
      print("Error: Could not open bell data savefile (ignore this message on first start)");
      return
   end
   local str = file:read();
   file:close();
   
   local bell_positions_table = minetest.deserialize( str );
   if( bell_positions_table and bell_positions_table.bell_data ) then
     bell_positions = bell_positions_table.bell_data;
     print("[bell] Read positions of bells from savefile.");
   end
end
   

-- actually ring the bell
bell.ring_bell_once = function()

   for i,v in ipairs( bell_positions ) do
-- print("Ringing bell at "..tostring( minetest.pos_to_string( v )));
      minetest.sound_play( "bell_bell",
        { pos = v, gain = 1.5, max_hear_distance = 100,});
   end
end



bell.ring_bell = function()

   -- figure out if this is the right time to ring
   local sekunde = tonumber( os.date( "%S"));
   local minute  = tonumber( os.date( "%M"));
   local stunde  = tonumber( os.date( "%I")); -- in 12h-format (a bell that rings 24x at once would not survive long...)
   local delay   = bell.RING_INTERVAL;
 
   --print("[bells]It is now H:"..tostring( stunde ).." M:"..tostring(minute).." S:"..tostring( sekunde ));

   --local datum = os.date( "Stunde:%l Minute:%M Sekunde:%S");
   --print('[bells] ringing bells at '..tostring( datum ))

   delay = bell.RING_INTERVAL - sekunde - (minute*60);

   -- make sure the bell rings the next hour
   minetest.after( delay, bell.ring_bell );

   -- if no bells are around then don't ring
   if( bell_positions == nil or #bell_positions < 1 ) then
      return;
   end

   if( sekunde > 10 ) then
--      print("[bells] Too late. Waiting for "..tostring( delay ).." seconds.");
      return;
   end

   -- ring the bell for each hour once
   for i=1,stunde do
     minetest.after( (i-1)*5,  bell.ring_bell_once );
   end

end

-- first call (after the server has been started)
minetest.after( 10, bell.ring_bell );
-- read data about bell positions
bell.restore_bell_data();

function bell.bell_sounds(table)
	table = table or {}
	table.dig = table.dig or
			{name = "metal_dig", gain = 1.0, pitch = 0.8}
	table.dug = table.dug or
			{name = "bell_wield", gain = 0.9, pitch = 0.5}
	table.place = table.place or
			{name = "bell_wield", gain = 1.0, pitch = 0.7}
	return table
end

minetest.register_node("bell:bell", {
    description = "bell",
    node_placement_prediction = "",
	tiles = {"blank.png"},
	paramtype = "light",
	is_ground_content = true,
    stack_max = 1,
	drawtype = "nodebox",
    on_punch = function (pos,node,puncher)
        minetest.sound_play( "bell_bell",
           { pos = pos, gain = 1.5, max_hear_distance = 100,});
	end,

	sounds = bell.bell_sounds(),
	
    after_place_node = function(pos, placer)
       if( placer ~= nil ) then
       end
       -- remember that there is a bell at that position
       table.insert( bell_positions, pos );
       bell.save_bell_positions( placer );
    end,

    after_dig_node = function(pos, oldnode, oldmetadata, digger)
       if( digger ~= nil ) then
       end

       local found = 0;
       -- actually remove the bell from the list
       for i,v in ipairs( bell_positions ) do
          if( v ~= nil and v.x == pos.x and v.y == pos.y and v.z == pos.z ) then
             found = i;
          end
       end
       -- actually remove the bell
       if( found > 0 ) then
          table.remove( bell_positions, found );
          bell.save_bell_positions( digger );
       end
    end,

   on_select = function(itemstack, player)
		minetest.sound_play("bell_wield", {pitch = 0.3})
		minetest.sound_play("select", {pitch = 1.3})
    end,
 
    groups = {by_pick = 3},
})
