////////////////////////////////////////////////////////////////////////////////////////////////////

var e = new Object;

var bindMethod = function(obj, method) {
	return function() { return method.apply(obj, arguments); }
};

if(!Object.extend) {
	if(!Object) { var Object = {}; }
	Object.extend = function(destination, source) {
		for(var property in source) {
			destination[property] = source[property];
		}
		return destination;
	};
}

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

Function.prototype.delay = function(ms, bind) {
	return setTimeout(this.bind(bind || this), ms * 100);
};

if(!Array.prototype.forEach) {
	Array.prototype.forEach = function(func, scope) {
		scope = scope || this;
		for(var i = 0, l = this.length; i < l; i++) {
			func.call(scope, this[i], i, this);
		}
	};
}

e = {
	guid : 1,
	add : function(element, type, handler) {
		if(element.addEventListener) {
			element.addEventListener(type, handler, false);
		} else {
			if(!handler.$$guid) {
				handler.$$guid = e.guid++;
			}
			if(!element.events) {
				element.events = {};
			}
			var handlers = element.events[type];
			if(!handlers) {
				handlers = element.events[type] = {};
				if (element["on" + type]) {
					handlers[0] = element["on" + type];
				}
			}
			handlers[handler.$$guid] = handler;
			element["on" + type] = e.handleEvent;
		}
	},

	remove : function(element, type, handler) {
		if(element.removeEventListener) {
			element.removeEventListener(type, handler, false);
		} else {
			if(element.events && element.events[type]) {
				delete element.events[type][handler.$$guid];
			}
		}
	},

	handleEvent : function(event) {
		var returnValue = true;
		event = event || e.fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
		var handlers = this.events[e.type];
		for(var i in handlers) {
			this.$$handleEvent = handlers[i];
			if(this.$$handleEvent(event) === false) {
				returnValue = false;
			}
		}
		return returnValue;
	},

	fixEvent : function(event) {
		e.preventDefault = e.preventDefault;
		e.stopPropagation = e.stopPropagation;
		return event;
	},

	preventDefault : function() {
		this.returnValue = false;
	},

	stopPropagation : function() {
		this.cancelBubble = true;
	},
	
	onDomReady : function(f) {
		if(!this._readyCallbacks) {
			var domReady = this._domReady;
			if(domReady.done) { return f(); }
			if (document.addEventListener) {
				document.addEventListener("DOMContentLoaded", domReady, false);
			}
			/*@cc_on @*/
			/*@if (@_win32) {
				var proto = "src='javascript:void(0)'";
				if (location.protocol == "https:") { proto = "src=//0"; }
				document.write("<scr"+"ipt id=__ie_onload defer " + proto + "><\/scr"+"ipt>");
				document.getElementById("__ie_onload").onreadystatechange = function() {
					if (this.readyState == "complete") { domReady(); }
				};
			}
			/*@end @*/
			if(/WebKit/i.test(navigator.userAgent)) {
				this._timer = setInterval(function() {
					if(/loaded|complete/.test(document.readyState)) { domReady(); }
				}, 10);
			}
			e.add(window,'load',domReady);
			e._readyCallbacks = [];
		}
		e._readyCallbacks.push(f);
	},
	
	_domReady : function() {
		if(arguments.callee.done) { return; }
		arguments.callee.done = true;
		if(e._timer) {
			clearInterval(e._timer);
		}
		e._readyCallbacks.forEach(function(f) { f() });
		e._readyCallbacks = null;
	},
	
	unload : function() {
		if(!e.observers) { return; }
		e.observers.forEach(function(e) {
			e.remove.apply(Event,e);
		});
	},
	
	onload : function(func) {
		var oldonload = window.onload;
		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function() {
				oldonload();
				func();
			};
		}
	}
};

if(typeof XMLHttpRequest == "undefined") {
	var XMLHttpRequest = function(){
		return new ActiveXObject(navigator.userAgent.indexOf("MSIE 5") >= 0 ? "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP");
	};
}

var ejax = {
	options : {
		type :'get',
		url : '',
		vars : '',
		timeout : 5000,
		onComplete : function(){},
		onError : function(){},
		onSuccess : function(){},
		onStart : function(){},
		data : ''
	},
	requestDone : false,
	run : function(options) {
		Object.extend(this.options,options);
		
		var ajax = new XMLHttpRequest();
		ajax.open(this.options.type,(this.options.vars) ? this.options.url + '?' + this.options.vars : this.options.url,true);
		
		this.timeout();
		
		ajax.onreadystatechange = function(){
			if(ajax.readyState == 4 && !this.requestDone) {
				if(this.success(ajax)) {
					this.options.onSuccess(this.data(ajax,this.options.type));
				} else {
					this.options.onError();
				}
				this.options.onComplete.delay(5);
				ajax = null;
			}
		}.bind(this);
		
		this.options.onStart();
		ajax.send(null);
	},
	
	timeout : function() {
		setTimeout(function(){
			this.requestDone = true;
		}, this.options.timeout);
	},

	success : function(r) {
		try {
			return !r.status && location.protocol == "file:"
			|| (r.status >= 200 && r.status < 300 )
			|| r.status == 304 || navigator.userAgent.indexOf("Safari") >= 0 && typeof r.status == "undefined";
		} catch(e) {}
		return false;
	},

	data : function(r,type) {
		var ct = r.getResponseHeader("content-type");
		var data = !type && ct && ct.indexOf("xml") >= 0;
		data = type == "xml" || data ? r.responseXML : r.responseText; // xml
		if(type == "script") { eval.call( window, data ); } // js
		return data; // html or text
	}
};

e.jax = bindMethod(ejax,ejax.run);

new function() {
	var b = navigator.userAgent.toLowerCase();
	e.browser = {
		safari: /webkit/.test(b),
		opera: /opera/.test(b),
		msie: /msie/.test(b) && !/opera/.test(b),
		mozilla: /mozilla/.test(b) && !/(compatible|webkit)/.test(b)
	};
}

if(e.browser.msie) {
	e.add(window, 'unload', e.unload);
}

////////////////////////////////////////////////////////////////////////////////////////////////////