/* ------------------------------------------------------------------
 * List of all methods in this file
 * ------------------------------------------------------------------
- addEvent
- removeEvent
- handleEvent
- fixEvent

- Element
- Element.removeChildren
- Element.show
- Element.hide
- Element.toggle

- String.format

- startup
*/ 

/* Events -----------------------------------------------------------
 * written by Dean Edwards, 2005
 * with input from Tino Zijdel
 * http://dean.edwards.name/weblog/2005/10/add-event/
 * ------------------------------------------------------------------
 */
function addEvent(element, type, handler) {
	element = $(element);
	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; return event; };
fixEvent.preventDefault = function() { this.returnValue = false; };
fixEvent.stopPropagation = function() { this.cancelBubble = true;};

if (!window.Event) { var Event = new Object(); }

/* -----------------------------------------------------------------------------------------------------------*/

var isDOM=document.getElementById; //DOM1 browser (MSIE 5+, Netscape 6, Opera 5+)
var isOpera=isOpera5=window.opera && isDOM; //Opera 5+
var isOpera6=isOpera && window.print; //Opera 6+
var isOpera7=isOpera && document.readyState; //Opera 7+
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 или 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);
}

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.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.fade = function(elementID) {
	Fat.fade_element(elementID);
};
	
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.validate = function(el) {
	el = $(el);
	var isValid = true;
	var validators = Element.getElementsByClassName(el, 'validator');
	for(var i = 0; i < validators.length; i++)
	{
		var v = validators[i];
		var isV = eval('('+v.getAttribute('validate')+')()');
		
		if (! isV)
			isValid = false;
		
		Element.toggle(v, ! isV);
	}	
	
	return isValid;
};
	
Element.getRadioGroupValue = function(el, name) {
	el = $(el);
	var result = '';
	var inputz = el.getElementsByTagName('input');
	for(var i = 0; i < inputz.length; i++)
	{
		var input = inputz[i];
		if (input.type == 'radio' && input.name == name && input.checked)
		{
			result = input.getAttribute('value');	
		}
	}
	
	return result;
};

var Position = {
	cumulativeOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
		} while (element);
		return [valueL, valueT];
	}
};

/* 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));
	}	
}

/* -------------------------------------------------------------------------------------- */
/* Namespace 'Cookie'	      															  */
/* -------------------------------------------------------------------------------------- */
window.addNamespace('Cookie');
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 ) );
};

Cookie.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" : "" );
};

Cookie.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";
};


/* Serializes object o into XML	*/
Object.serialize = function (o, inner) {
	var result = '';	
	if (! inner)
		result += '<?xml version="1.0"?><object>'; 
	
	if (typeof o == 'string')
		result += o;
	
	else if (typeof o == 'boolean')
		result += o;
	
	else if (typeof o == 'number')
		result += ''+number+'';
	
	else if (typeof o == 'object')
	{
		if (o instanceof Array)
		{
			result += '<array>';
			
			for(var i in o)
				result += '<item>'+Object.serialize(o[i], true)+'</item>';
			
			result += '</array>';
		}
		else if (o instanceof Object)
		{
			for(var i in o)
				result += '<'+i+'>'+Object.serialize(o[i], true)+'</'+i+'>';
		}
	}
	
	if (! inner)
		result += '</object>';
	
	return result;
}
	
/* -------------------------------------------------------------------------------------- */
/* Namespace 'WindowUtilities' Taken from window.js 0.65								  */
/* -------------------------------------------------------------------------------------- */
addNamespace('WindowUtilities');

WindowUtilities.getPageScroll = function() {
	var yScroll;

	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
		yScroll = document.documentElement.scrollTop;
	} else if (document.body) {// all other Explorers
		yScroll = document.body.scrollTop;
	}
	return  {'y' : yScroll};
};

	// getPageSize()
	// Returns array with page width, height and window width, height
	// Core code from - quirksmode.org
	// Edit for Firefox by pHaez
WindowUtilities.getPageSize = function() {
	var xScroll, yScroll;

	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}

	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	

	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}

	return {'pageWidth' : pageWidth, 'pageHeight' : pageHeight, 'windowWidth' : windowWidth, 'windowHeight' : windowHeight}; 
};


/* Mouse coordinates */
mousex = 0;
mousey = 0;
addEvent(window, 'load', function() { 
	addEvent(document, 'mousemove', function(e){
		if(isMSIE || isOpera7){
			mousex=e.clientX+document.body.scrollLeft;
			mousey=e.clientY+document.body.scrollTop;
			return true;
		}else if(isOpera){
			mousex=e.clientX;
			mousey=e.clientY;
			return true;
		}else if(isMozilla){
			mousex = e.pageX;
			mousey = e.pageY;
			return true;
		}
	
	});
});

/* Loads stylesheet via url */
function addStyleSheet(url)
{
  var style;
  if (typeof url == 'undefined')
  {
    style = document.createElement('style');
  }
  else
  {
    style = document.createElement('link');
    style.rel = 'stylesheet';
    style.type = 'text/css';
    style.href = url;
  }
  document.getElementsByTagName('head')[0].appendChild(style);
}

/* Startup---------------------------------------------------------------------------------------------------*/

addEvent(window, 'load', function() {
	if (document.getElementById) {
		var alltags = document.all? document.all : document.getElementsByTagName("*");
		for (i=0; i < alltags.length; i++) {
		  if (alltags[i].className == "emailCloak") {
			var oldText = alltags[i].firstChild;
			var emailAddress = alltags[i].firstChild.nodeValue;
			var user = emailAddress.substring(0, emailAddress.indexOf("("));
			var website = emailAddress.substring(emailAddress.indexOf(")")+1, emailAddress.length);
			var newText = user+"@"+website;
			var a = document.createElement("a");
			a.href = "mailto:"+newText;
			var address = document.createTextNode(newText);
			a.appendChild(address);
			alltags[i].replaceChild(a,oldText);
		  }
		}
	}
});
