if (Function.prototype.bind == null) {
	Function.prototype.bind = function(object) {
		var __method = this;
		return function() {
			return __method.apply(object, arguments);
		}
	}
}

// Gingle Namespace

if (typeof(Gingle) == "undefined")
	Gingle = { };



/**
 * Browser types
 */

Gingle.Browser = { 
	isKHTML: function() {
		return /Konqueror|KHTML/.test(navigator.userAgent) && !/Apple/.test(navigator.userAgent);
	},
	
	isSafari: function() {
		return /KHTML/.test(navigator.userAgent) && /Apple/.test(navigator.userAgent);
	},
	
	isOpera: function() {
		return typeof(window.opera) != "undefined";
	},

	isIE: function() {
		return typeof(document.all) != "undefined" && typeof(window.opera) == "undefined";
	},
	
	isIEQuirks: function() {
		// is the browser internet explorer in quirks mode (we could use document.compatMode too)		
		return Gingle.Browser.isIE() && document.documentElement.clientHeight == 0;
	},		
	
	isIE7: function() {
		var index = navigator.userAgent.indexOf("MSIE");
		var version = parseFloat(navigator.userAgent.substring(index + 5));
		return Gingle.Browser.isIE() && version >= 7;
	},
	
	isGecko: function() {
		return /Gecko/.test(navigator.userAgent) && !Gingle.Browser.isSafari();
	}
};





/**
 * Events related code
 * Based on code from Mootools (http://mootools.net)
 */

Gingle.Event = {
	// adds an event of specified type to the element
	// also supports the domready event on window
	// domready is event fired when the DOM is complete, but before loading external resources (images, ...)
	add: function(element, type, fn) {
		// is the event domready?
		if (element == window && type == "domready") {
			Gingle.Event.addDomReadyEvent(fn);
		} else {
			if (element.addEventListener){
				element.addEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, fn, false);
			} else {
				fn = fn.bind(element);
				// Because of the fn.bind (returning a new function object)
				// you can't detach the event first to be sure that there are no doubles :(
				//element.detachEvent('on'+type, fn);
				element.attachEvent('on'+type, fn);
			}
		}
		return element;
	},
	
	// handlers that will be fired on dom ready event
	domReadyHandlers : new Array(),
	
	// fires the dom ready event and cleanup the handlers
	fireDomReadyHandlers : function() {
		var h = Gingle.Event.domReadyHandlers;
		while (h.length > 0) {
			var c = h.shift();
			c();
		}
		Gingle.Event.domReadyHandlers = null;
	},
	
	// adds the dom ready event 
	addDomReadyEvent : function(fn) {
		// is the window already loaded?
		if (window.loaded)  {
			fn();
		} else if (!window.events || !window.events.domready) {
			// register the handler
			Gingle.Event.domReadyHandlers.push(fn);
		
			// callback
			var domReady = function() {
				if (window.loaded) 
					return;
				window.loaded = true;
				
				// if there was a timer, clean it (khtml, safari)
				if (Gingle.Event.domReadyTimer) {
					clearTimeout(Gingle.Event.domReadyTimer);
					Gingle.Event.domReadyTimer = null;
				}
				
				// invoke the handlers
				Gingle.Event.fireDomReadyHandlers();
			}.bind(this);
			
			if (document.readyState && (Gingle.Browser.isKHTML() || Gingle.Browser.isSafari())) { 
			   //safari and konqueror don't support the event - simulate it through a timeou
				Gingle.Event.domReadyTimer = window.setTimeout(function() {
					if (document.readyState == "loaded" ||
					    document.readyState == "complete") {
					    domReady();
					}
				}, 1);
			} else if (document.readyState && Gingle.Browser.isIE()) { 
				if (document.getElementById('ie_ready') == null) {
					// for internet explorer we need to load a "dummy" scrip from ::/ to get the 
					// readystatechangeevernt - that means the main page being loaded and now the browser
					// is loading dependencies
					var src = (window.location.protocol == 'https:') ? '\/\/:' : 'javascript:void(0)';
					document.write('<script id="ie_ready" defer src="' + src + '"><\/script>');
					document.getElementById('ie_ready').onreadystatechange = function() {
						if (this.readyState == 'complete') domReady();
					};
				}
			} else { 
				// other browsers
				Gingle.Event.add(document, "DOMContentLoaded", domReady);
			}
		} else {
			window.addEventListener("domready", fn, false);
		}
	}
}
