var Messenger = {

  messages: new Array(),
  
  startRefresh: function(url, frequency, lastId) {
    this.url = url;
    this.lastId = lastId;
    this.firstId = null;
    this.lastRefresh = new Date().getTime();
    this.frequency = frequency;
    this.onChanged();
    new PeriodicalExecuter(function() { Messenger.refresh() }, frequency / 1000);
  },
  
  refresh: function(force) {
    var time = new Date().getTime();
    if (force || time - this.lastRefresh >= this.frequency) {
      this.lastRefresh = time;
      var self = this;
      var parameters = "since_id=" + this.lastId;
      if (this.messages.length > 0) {
        parameters += "&known_ids=" + this.messages.join(",");
      }
      new Ajax.Updater({success: 'messenger_inbox'}, 
        this.url + "/messenger_fragment", {
          asynchronous: true, 
          evalScripts: true, 
          insertion: Insertion.Top,
          onFailure: function(request) {
            var error = request.responseText;
            if (error == null || error == "")
            {
              error = "Kunne ikke hente meldinger.";
            }
            self.setStatus(error);
          },
          onComplete: function(request) {
          	self.setStatus(null);
            var dismissedIds = self._parseMessageIds(
              request.getResponseHeader("X-Dismissed-Ids"));
            var newIds = self._parseMessageIds(
              request.getResponseHeader("X-Message-Ids"));
            for (var index = 0; index < newIds.length; index++) {
              var id = newIds[index];
              if (dismissedIds.indexOf(id) == -1) {
                self.onAddedMessage(id, true);
              }
            }
            dismissedIds.each(function(id) {
              self.onDeletedMessage(id, {effect: false});
            }.bind(this));
          }, 
          parameters: parameters
        }); 
    }
  },
  
  onAddedMessage: function(id, incremental) {
    this.messages[this.messages.length] = id;
    if (id > this.lastId)
    {
      this.lastId = id;
    }
    if (this.firstId == null || this.firstId > id) {
      this.firstId = id;
    }
    this.onChanged();
    if (incremental)
    {
      var elementId = "messenger_inbox_" + id;
      new Effect.Appear(elementId, {
        beforeStart: function() {
          new Effect.Highlight(elementId, {
            startcolor: "#ffff99",
            endcolor: "#ffffd9",
            restorecolor: "#ffffd9",
            duration: 10.0
          })
        }
      });
    }
  },
  
  onDeletedMessage: function(id, options) {
    options = options || {};
    var found = false;
    for (var index = 0; index < this.messages.length; index++)
    {
      if (this.messages[index] == id)
      {
        this.messages.splice(index, 1);
        found = true;
        break;
      }
    }
    if (found)
    {
      var elementId = "messenger_inbox_" + id;
      if ($(elementId) != null) {
        if (options.effect) {
          new Effect.Fade(elementId, {
            duration: 0.5,
            afterFinish: function() { Element.remove(elementId) }});
        } else {
          $(elementId).remove();
        }
        this.onChanged();
      }
    }
    if (this.firstId == id) {
      if (this.messages.length > 0) {
        this.firstId = this.messages[this.messages.length - 1];
      } else {
        this.firstId = null;
      }
    }
  },

  onDeletedMessages: function(ids) {
    for (var index = 0; index < ids.length; index++)
    {
      onDeletedMessage(ids[index]);
    }
  },
  
  onChanged: function() {
    $("user_unread_count").innerHTML = (this.messages.length == 0 ? "Ingen" :
      this.messages.length) + " beskjed" + (this.messages.length != 1 ? "er" : "");
    var mark = $("messenger_mark_all");
    if (mark != null)
    {
      mark.style.display = (this.messages.length == 0 ? "none" : "");
    }
  },
  
  markRead: function(ids) {
    var params = "";
    for (var index = 0; index < ids.length; index++) {
      id = ids[index];
      if (params != "") {
        params += "&";
      }
      params += "id[]=" + id;
    }
    var self = this;
    new Ajax.Request(this.url + "/dismiss", {
      asynchronous: true, 
      evalScripts: true, 
      onLoading: function(request) {
        self.setStatus("Merker meldinger...");
      },
      onFailure: function(request) {
        self.setStatus(null);
        var error = request.responseText;
        if (error == null || error == "")
        {
          error = "Kunne ikke merke meldinger.";
        }
        self._showError(error);
      },
      onComplete: function(request) {
        self.setStatus(null);
        var markedIds = self._parseMessageIds(
          request.getResponseHeader("X-Message-Ids"));
        for (var index = 0; index < markedIds.length; index++)
        {
          var id = markedIds[index];
          self.onDeletedMessage(id, true);
        }
      }, 
      parameters: params
    });
  },
  
  markAllRead: function() {
    this.markRead(this.messages);    
  },

  /**  
   * Sets the messenger status message.
   */
  setStatus: function(status) {
    if (status != null && status != "") {
      $("messenger_status").innerHTML = status;
      Element.show("messenger_status");
    }
    else {
      $("messenger_status").innerHTML = "";
      Element.hide("messenger_status");
    }
  },

  /**  
   * Shows an error message.
   */
  _showError: function(error) {
    alert(error);
  },
  
  /**
   * Parses a comma-separated list of message IDs.
   */
  _parseMessageIds: function(s) {
    var ids = new Array();
    if (s != null)
    {
      var strings = s.split(",");
      for (var index = 0; index < strings.length; index++)
      {
        var id = parseInt(strings[index]);
        if (!isNaN(id))
        {
          ids[ids.length] = id;
        }
      }
    }
    return ids;
  }
};