﻿(function($){
  // Creates events before content which fire the events fire.
  $.LateBoundEvents = function() {
    this.__constructor();
  }
  
	// Define our class
	$.extend($.LateBoundEvents.prototype, {	
	  // Our Latebind events class definition
    eventlist: null,
	  __constructor: function() {
      this.eventlist = new Object();	    
	  },
    add: function(event, func, overwrite) { 
      // Event should be unique
      var subclass = "default";
      if (event.contains(".")) {
        subclass = event.substring(event.indexOf(".")+1);
        event = event.substring(0, event.indexOf("."));
      }
      if (!this.eventlist[event]) {
        this.eventlist[event] = new Object();
      }
      var list = this.eventlist[event];
      if (!list[subclass] || overwrite ) {
        list[subclass] = func;
      }
      else {
        alert("Event "+event+" with subclass "+ subclass + " already exists.");
      }
    },
    addRange: function(range) {
      // TODO
    },
    remove: function(event, subclass) {
      if (this.eventlist[event] && this.eventlist[event][subclass ? subclass : "default"]) {
        this.eventlist[event][subclass ? subclass : "default"] = null;
      }
    },
    bind: function(wrappedset, subclassOnly) {
      for (var eventName in this.eventlist) {
        var event = this.eventlist[eventName];
        for (var subclassName in event) {
          var combinedEvent = eventName;
          if (subclassName != "default") {
            combinedEvent += "." + subclassName;
          }
          if (!subclassOnly || subclassName.startswith(subclassOnly)) {
            // Unbind and bind again
            wrappedset.unbind(combinedEvent).bind(combinedEvent, event[subclassName]);
          }
        }
      }
    },
    bindone: function(wrappedset, event, subclass) {
      if (!subclass) {
        subclass = "default";
      }
      if (this.eventlist[event][subclass]) {
        var combinedEvent = event;
        if (subclass != "default") {
          combinedEvent += "." + subclass;
        }
        // Unbind one and bind one again
        wrappedset.unbind(combinedEvent).bind(combinedEvent, this.eventlist[event][subclass]);
      }
    },
    unbind: function(wrappedset, subclassOnly) {
      for (var eventName in this.eventlist) {
        var event = this.eventlist[eventName];
        for (var subclassName in event) {
          var combinedEvent = eventName;
          if (subclassName != "default") {
            combinedEvent += "." + subclassName;
          }
          if (!subclassOnly || subclassName.startswith(subclassOnly)) {
            // Unbind and bind again
            wrappedset.unbind(combinedEvent);
          }
        }
      }
    },
    unbindone: function(wrappedset, event, subclass) {
      if (!subclass) {
        subclass = "default";
      }
      if (this.eventlist[event][subclass]) {
        var combinedEvent = event;
        if (subclass != "default") {
          combinedEvent += "." + subclass;
        }
        // Unbind one and bind one again
        wrappedset.unbind(combinedEvent);
      }
    }
  });
})(jQuery);
