var N = (function () {
  var topics = ['chat', 'status', 'kiss', 'roomChat', 'profileSearch', 'presence', 'message', 'content', 'visitor', 'comment', 'signIn', 'takenTest'];
  // var MIN_TIME = 1500;
  // var MAX_TIME = 3500;
  var MIN_TIME = 5000;
  var MAX_TIME = 7500;
  
  var i, len;
  var h = 0;
  var o = {};
  
  var flag = true;

  var messages = {};
  var subscribers = [];

  var Queue = function () {
    var q = [];
    this.insert = function (x) {
      var l = q.length;
      q[l] = x;
    };
    this.remove = function () {
      return q.shift();
    };
    this.dump = function () {
      return q;
    };
    this.reset = function () {
      q = [];
    };
  };

  for (i=0, len=topics.length; i<len; i++) {
    messages[topics[i]] = new Queue();
  }

  o.subscribe = function (topic, call) {
    var sub = {};
    sub.topic = topic;
    sub.call = call;
    sub.handle = h++;
    subscribers.push(sub);
    return sub.handle;
  };

  // TODO: unsubscribe

  o.publish = function (topic, messageObject) {
    // TODO: rivedere
    messageObject.topic = topic;
    messageObject.date = new Date();
    if (topic in messages) {
      messages[topic].insert(messageObject);
    }
  };

  o.reset = function (topic) {
    messages[topic].reset();
  };

  function fire() {
    var i, len;
    for (var topic in messages) {
      if (messages.hasOwnProperty(topic)) {
        var messageObject = messages[topic].remove();
        if (messageObject) {
          for (i=0, len=subscribers.length; i<len; i++) {
            if (messageObject.topic == subscribers[i].topic) {
              subscribers[i].call(messageObject);
            }
          }
        }
      }
    }
    if (flag) {
      var time = MIN_TIME + Math.floor(Math.random() * (MAX_TIME - MIN_TIME));
      //alert(time);
      setTimeout(fire, time);
    }
  }
  
  o.start = function () {
	flag = true;
    setTimeout(fire, MIN_TIME);
  }
  
  o.stop = function () {
    flag = false;
  }
  
  setTimeout(fire, MIN_TIME);
  //setInterval(fire, 500);
  
  return o;
})();

