var isDOM=document.getElementById; //DOM1 browser (MSIE 5+, Netscape 6, Opera 5+)
var isOpera = isOpera5= window.opera && isDOM; //Opera 5+
var isMSIE=document.all && document.all.item && !isOpera; //Microsoft Internet Explorer 4+
var isMSIE5=isDOM && isMSIE; //MSIE 5+
var isMozilla=isDOM && navigator.appName=="Netscape"; //Mozilla eee Netscape 6.*

/* -------------------------------------------------------------------------------------- */
/* Service Functions         															  */
/* -------------------------------------------------------------------------------------- */

if(!window.addNamespace) {
	window.addNamespace = function(ns) {
		var nsParts = ns.split(".");
		var root = window;

		for(var i=0; i<nsParts.length; i++) {
			if(typeof root[nsParts[i]] == "undefined")
				root[nsParts[i]] = {};
			root = root[nsParts[i]];
		}
	}
}

var Class = {
	create: function() {
		return function() {
			this.initialize.apply(this, arguments);
		}
	}
}

Object.extend = function(destination, source) {
	for (property in source) destination[property] = source[property];
	return destination;
}

Function.prototype.bind = function(object) {
	var __method = this;
	return function() {
		return __method.apply(object, arguments);
	}
}

Function.prototype.bindAsEventListener = function(object) {
var __method = this;
	return function(event) {
		__method.call(object, event || window.event);
	}
}

function $() {
	if (arguments.length == 1) return get$(arguments[0]);
	var elements = [];
	$c(arguments).each(function(el){
		elements.push(get$(el));
	});
	return elements;

	function get$(el){
		if (typeof el == 'string') el = document.getElementById(el);
		return el;
	}
}


/* -------------------------------------------------------------------------------------- */
/* JS Objects extensions      															  */
/* -------------------------------------------------------------------------------------- */

Object.extend(Array.prototype, {
	each: function(func) {
		for(var i=0;ob=this[i];i++) func(ob, i);
	}
}, false);

//Object.extend(Array.prototype, {
//	push: function(o) {
//		this[this.length] = o;
//	}
//}, false);

/* copies array */
function $c(array){
	var nArray = [];
	for (i=0;el=array[i];i++) nArray.push(el);
	return nArray;
}

document.getElementsByClassName = function(className) {
	return Element.getElementsByClassName(document, className);
}

document.getSelectionText = function() {
	var txt = '';
	
	if (window.getSelection)
	{ txt = window.getSelection(); }
	else if (document.getSelection)
	{ txt = document.getSelection(); }
	else if (document.selection)
	{ txt = document.selection.createRange().text; }
	else 
		return;

	return txt;
}

String.format = function(s){
	for(var i=1; i<arguments.length; i++)
		s = s.replace("{" + (i -1) + "}", arguments[i]);
	return s;
}

Object.extend(String.prototype, {
	endsWith:	function(s){ return (this.substr(this.length - s.length) == s); },
	startsWith: function(s){ return (this.substr(0, s.length) == s); },
	trimLeft:	function() { return this.replace(/^\s*/,""); },
	trimRight:	function() { return this.replace(/\s*$/,"");	},
	trim:		function() { return this.trimRight().trimLeft(); }
}, false);


/* -------------------------------------------------------------------------------------- */
/* Namespace 'Response'      															  */
/* -------------------------------------------------------------------------------------- */
window.addNamespace('Response');

Response.redirect = function(url) {
	window.location.href = url;
	return false;
}

/* -------------------------------------------------------------------------------------- */
/* Namespace 'Element'      															  */
/* -------------------------------------------------------------------------------------- */

window.addNamespace('Element');

Element.isVisible = function(element) {
	element = $(element);
	return Element.getCSSProperty(element, 'display') != 'none';
};

Element.remove = function(element) {
	element = $(element);
	return element.parentNode.removeChild(element);
};
	
Element.hasClassName = function(element, className) {
	element = $(element);
	var classes = element.className.split(/\s+/);
	for(var i = 0; i < classes.length; i++)
		if(classes[i] == className) return true
    return false
};

Element.addClassName = function(element, className) {
	element = $(element);
	Element.removeClassName(element, className);
	element.className += ' ' + className;
};
  
Element.removeClassName = function(element, className) {
	element = $(element);
	if (!element) return;
	var newClassName = '';
	element.className.split(' ').each(function(cn, i){
		if (cn != className){
			if (i > 0) newClassName += ' ';
			newClassName += cn;
		}
	});
	element.className = newClassName;
};

Element.toggleClassName = function(element, className, add) {
	element = $(element);
	
	if (add == null)
		add = ! Element.hasClassName(element, className);
	
	if (add)
		Element.addClassName(element, className);
	else
		Element.removeClassName(element, className);
};

Element.cleanWhitespace = function(element) {
	element = $(element);
	$c(element.childNodes).each(function(node){
		if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) Element.remove(node);
	});
};

Element.find = function(element, what) {
	element = $(element)[what];
	while (element.nodeType != 1) element = element[what];
	return element;
};
	
Element.getBounds = function (el) {
	el = $(el);
	
	var left = el.offsetLeft;  var top = el.offsetTop;
	for (var parent = el.offsetParent; parent; parent = parent.offsetParent)
	{ left += parent.offsetLeft;	top += parent.offsetTop; }
	
	return {left: left, top: top, width: el.offsetWidth, height: el.offsetHeight, right: left + el.offsetWidth, bottom: top + el.offsetHeight};
};
	 
Element.getCSSProperty = function (oNode, sProperty){
	if(document.defaultView)
		return document.defaultView.getComputedStyle(oNode, null).getPropertyValue(sProperty);
	else if(oNode.currentStyle)
	{
		for(var reExp = /-([a-z])/; reExp.test(sProperty); sProperty = sProperty.replace(reExp, RegExp.$1.toUpperCase()));
		return oNode.currentStyle[sProperty];
	}
	else return null;
};
	
Element.getElementsByClassName = function (node, classname) {
	node = $(node);
	var a = [];
	var re = new RegExp("(^|\\s)" + classname + "(\\s|$)");
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
};
	
Element.removeChildren = function(p) {
	p = $(p);
	while(p.firstChild)
		p.removeChild(p.firstChild);
};
	
Element.show = function(el) {
	el = $(el);
	var value = 'block';
	var tn = el.tagName.toLowerCase();
	if (tn == 'span' || tn  == 'strong' || tn  == 'a' || tn  == 'input' )
		value = 'inline';
	
	el.style.display = value;
};
	
Element.toggle = function(el, vis) {
	el = $(el);
	
	if (vis == null)
		vis = el.style.display == 'none';
	
	if (vis)
		Element.show(el);
	else
		Element.hide(el);
};
		
Element.hide = function(el) {
	el = $(el);
	el.style.display = 'none';
};
	
Element.setOpacity = function(el, opacity) {
	el = $(el);
	if (opacity == 0 && el.style.visibility != "hidden") 
		el.style.visibility = "hidden";
	else if (el.style.visibility != "visible") 
		el.style.visibility = "visible";
	
	if (window.ActiveXObject) 
		el.style.filter = "alpha(opacity=" + opacity*100 + ")";
	
	el.style.opacity = opacity;
};

Element.getOffset = function(el) {
	var valueT = 0, valueL = 0;
	do {
		valueT += element.offsetTop  || 0;
		valueL += element.offsetLeft || 0;
		element = element.offsetParent;
	} while (element);

	return [valueL, valueT];
}

/* -------------------------------------------------------------------------------------- */
/* Cookies functions 																	  */
/* -------------------------------------------------------------------------------------- */
var Cookie = Class.create();
Object.extend(Cookie,
{
	get: 	function( name )
	{
		var start = document.cookie.indexOf( name + "=" );
		var len = start + name.length + 1;
		if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
			return null;
		}
		if ( start == -1 ) return null;
		var end = document.cookie.indexOf( ";", len );
		if ( end == -1 ) end = document.cookie.length;
		return unescape( document.cookie.substring( len, end ) );
	},

	set: 	function ( name, value, expires, path, domain, secure )
	{
		var today = new Date();
		today.setTime( today.getTime() );
		if ( expires ) {
			expires = expires * 1000 * 60 * 60 * 24;
		}
		var expires_date = new Date( today.getTime() + (expires) );
		document.cookie = name+"="+escape( value ) +
			( ( expires ) ? ";expires="+expires_date.toGMTString() : "" ) + /* expires.toGMTString() */
			( ( path ) ? ";path=" + path : "" ) +
			( ( domain ) ? ";domain=" + domain : "" ) +
			( ( secure ) ? ";secure" : "" );
	},

	remove:	function ( name, path, domain )
	{
		if ( getCookie( name ) ) document.cookie = name + "=" +
				( ( path ) ? ";path=" + path : "") +
				( ( domain ) ? ";domain=" + domain : "" ) +
				";expires=Thu, 01-Jan-1970 00:00:01 GMT";
	}
});

/* -------------------------------------------------------------------------------------- */
/* http://dean.edwards.name/weblog/2005/10/add-event/									  */
/* -------------------------------------------------------------------------------------- */

function addEvent(element, type, handler) {
	if (!handler.$$guid) handler.$$guid = addEvent.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] = handleEvent;
};
addEvent.guid = 1;

function removeEvent(element, type, handler) {
	if (element.events && element.events[type]) {
		delete element.events[type][handler.$$guid];
	}
};

function handleEvent(event) {
	var returnValue = true;
	event = event || fixEvent(window.event);
	event.element = event.target || event.srcElement;
	var handlers = this.events[event.type];
	for (var i in handlers) {
		this.$$handleEvent = handlers[i];
		if (this.$$handleEvent(event) === false) {
			returnValue = false;
		}
	}
	return returnValue;
};

function fixEvent(event) { event.preventDefault = fixEvent.preventDefault; event.stopPropagation = fixEvent.stopPropagation; event.element = event.target || event.srcElement; return event;  };
fixEvent.preventDefault = function() { this.returnValue = false; };
fixEvent.stopPropagation = function() { this.cancelBubble = true;};

if (!window.Event) { var Event = new Object(); }

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46
 });


/* -------------------------------------------------------------------------------------- */
/* Function for creating DOM elements 													  */
/* -------------------------------------------------------------------------------------- */
var domEl = function(e,c,a,p,x) {
	if(e||c) {
		if (c)
			c=(typeof c=='string'||(typeof c=='object'&&!c.length))?[c]:c;	
		e=(!e&&c.length==1)?document.createTextNode(c[0]):e;	
		var n = (typeof e=='string') ? document.createElement(e) : !(e && e===c[0])? e.cloneNode(false): e.cloneNode(true);	
		if(e.nodeType!=3) {
			if (c)
			{
			c[0]===e?c[0]='':'';
			for(var i=0,j=c.length;i<j;i++) 
				typeof c[i] == 'string' ? n.appendChild(document.createTextNode(c[i])) : n.appendChild(c[i].cloneNode(true));
			}
			
			if(a) {for(var i=(a.length-1);i>=0;i--) a[i][0]=='class'?n.className=a[i][1]:n.setAttribute(a[i][0],a[i][1]);}
		}
	}
	if(!p)return n;
	p=(typeof p=='object'&&!p.length)?[p]:p;
	for(var i=(p.length-1);i>=0;i--) {
		if(x){while(p[i].firstChild)p[i].removeChild(p[i].firstChild);
			if(!e&&!c&&p[i].parentNode)p[i].parentNode.removeChild(p[i]);}
		if(n) p[i].appendChild(n.cloneNode(true));
	}	
}

function MM_preloadImages() { 
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}