if (typeof (Dottoro) == "undefined") {
	var Dottoro = {}; // namespace
}

Dottoro.BROWSER_IE = 0x0001;
Dottoro.BROWSER_FF = 0x0002;
Dottoro.BROWSER_OP = 0x0004;
Dottoro.BROWSER_SA = 0x0008;
Dottoro.BROWSER_ALL = 0x000F;

(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;


  this.Dottoro.Class = function(){};
  
  Dottoro.Class.extend = function(prop) {
    var _super = this.prototype;
    
    initializing = true;
    var prototype = new this();
    initializing = false;
    
    for (var name in prop) {
      prototype[name] = typeof prop[name] == "function" && 
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
            
            this._super = _super[name];
            
            var ret = fn.apply(this, arguments);        
            this._super = tmp;
            
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }
    
    Dottoro.Class = function () {
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }
    
    Dottoro.Class.prototype = prototype;
    
    Dottoro.Class.constructor = Dottoro.Class;

    Dottoro.Class.extend = arguments.callee;
    
    return Dottoro.Class;
  };
})();

	// Store registered event handlers to remove them on unload (avoid memory eating on refresh)
Dottoro.registeredEventHandlers = new Array();
Dottoro.registeredEventCounter = 0;

Dottoro.AddAttachEvent = function (type, handler, elem, browsers, myObj, myData) {
	var callbackFunc = (myData)? function (e) {handler(e, myObj, myData)} : function (e) {handler(e, myObj, elem)};

	var registered = false;
	if (elem.addEventListener) {
		if (browsers & (Dottoro.BROWSER_FF | Dottoro.BROWSER_OP | Dottoro.BROWSER_SA)) {
			elem.addEventListener (type, callbackFunc, false);
			registered = true;
		}
	}
	else {
		if (elem.attachEvent) {
			if (browsers & Dottoro.BROWSER_IE) {
				elem.attachEvent ("on" + type, callbackFunc);
				registered = true;
			}
		}
	}

	var data = []
	if (registered) {
		data = [Dottoro.registeredEventCounter, type, callbackFunc, elem, browsers];
		Dottoro.registeredEventHandlers["" + Dottoro.registeredEventCounter] = data;
		Dottoro.registeredEventCounter++;
	}
	return data;

};

Dottoro.RemoveDetachEvent = function (data) {
	if (!(data instanceof Array) || data.length < 5) {
		return false;
	}

	var key = "" + data[0];
	var type = data[1];
	var handler = data[2];
	var elem = data[3];
	var browsers = data[4];

	var removed = false;
	if (elem.removeEventListener) {
		if (browsers & (Dottoro.BROWSER_FF | Dottoro.BROWSER_OP | Dottoro.BROWSER_SA)) {
			elem.removeEventListener (type, handler, false);
			removed = true;
		}
	}
	else {
		if (elem.detachEvent) {
			if (browsers & Dottoro.BROWSER_IE) {
				elem.detachEvent ("on" + type, handler);
				removed = true;
			}
		}
	}

	if (removed) {
		delete Dottoro.registeredEventHandlers[key];
	}

	return removed;
};

Dottoro.RemoveHandlersOnUnload = function () {
	for (var i in Dottoro.registeredEventHandlers) {
		Dottoro.RemoveDetachEvent (Dottoro.registeredEventHandlers[i]);
	}
};


Dottoro.CreateHTTPRequestObject = function () {
	if (typeof (XMLHttpRequest) == "undefined") {
		if (typeof (ActiveXObject) != "undefined") {
			var progIDs = new Array (
									  "Msxml2.XMLHTTP.6.0", 
									  "Msxml2.XMLHTTP.5.0", 
									  "Msxml2.XMLHTTP.4.0", 
									  "Msxml2.XMLHTTP.3.0", 
									  "Msxml2.XMLHTTP", 
									  "Microsoft.XMLHTTP"
									);
			for (i in progIDs) {
				try { 
					return new ActiveXObject(progIDs[i]); 
				} catch(e) {};
			}
		}
	}
	else {
		return new XMLHttpRequest;
	}
	
	alert ("Your browser doesn't support XML handling!");
	return null;
}


Dottoro.AddAttachEvent ("unload", Dottoro.RemoveHandlersOnUnload, window, Dottoro.BROWSER_ALL);
