/* alias для document.getElementById() */
function $(id){
	return document.getElementById(id);
}

/* trim если его нету (IE) */
if(typeof String.prototype.trim !== 'function') {
  String.prototype.trim = function() {
    return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  }
}

/* indexOf если его нету (IE) */
if(!Array.indexOf){
  Array.prototype.indexOf = function(obj){
   for(var i=0; i<this.length; i++){
    if(this[i]==obj){
     return i;
    }
   }
   return -1;
  }
}


/* Добавить CSS в HEAD документа */
function addStyleProperties(cssStr){
	var head = document.getElementsByTagName('head')[0];
	var styleSheets = head.getElementsByTagName('style');
	var styleSheet = null;
	if (styleSheets.length){
		styleSheet = styleSheets[styleSheets.length-1];
	} else {
		styleSheet = document.createElement("style");
		styleSheet.setAttribute("type", "text/css");
		head.appendChild(styleSheet);
	}

	if(styleSheet.styleSheet){ // IE
		styleSheet.styleSheet.cssText = cssStr;
	} else { // w3c
		styleSheet.appendChild(document.createTextNode(cssStr));
	}
}

/* Получение числа (первого встреившегося) из любой строки */
function toInteger(str) {
	return str.match(/\d+/g)[0];
}

/* Отладочная функция */
function dalert(msg){
	if($('dalert')){
		$('dalert').innerHTML += msg + '<br />';
	}
}

function scrollPageTo(id){
	location.hash = id;
}

/*****************************
**   Event listeners
******************************/
function checkEvent(oEvt){
	oEvt=(oEvt) ? oEvt : ( (window.event) ? window.event : null );
	if(oEvt && oEvt.srcElement && !window.opera)
		oEvt.target=oEvt.srcElement;
	return oEvt;
}

function addEvent(objElement, strEventType, ptrEventFunc) {
	if (objElement.addEventListener)
		objElement.addEventListener(strEventType, ptrEventFunc, false);
	else if (objElement.attachEvent)
		objElement.attachEvent('on' + strEventType, ptrEventFunc);
}

function removeEvent(objElement, strEventType, ptrEventFunc) {
	if (objElement.removeEventListener) objElement.removeEventListener(strEventType, ptrEventFunc, false);
		else if (objElement.detachEvent) objElement.detachEvent('on' + strEventType, ptrEventFunc);
}


/*****************************
**   ClassNames funcs
******************************/
function switchClass( objNode, strCurrClass, strNewClass ) {
	if ( matchClass( objNode, strNewClass ) ) replaceClass( objNode, strCurrClass, strNewClass );
		else replaceClass( objNode, strNewClass, strCurrClass );
}

var rclass = /[\n\t]/g,
	rspace = /\s+/;


function removeClass( objNode, strCurrClass ) {
	replaceClass( objNode, '', strCurrClass );

	if ( strCurrClass ) {
		var classNames = (strCurrClass).split(rspace);
		var className = (" " + objNode.className + " ").replace(rclass, " ");
		for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
			className = className.replace(" " + classNames[c] + " ", " ");
		}

		objNode.className = className.trim();
	} else {
		objNode.className = "";
	}
}

function addClass( objNode, strNewClass ) {
	replaceClass( objNode, strNewClass, '' );

	if ( !objNode.className ) {
		objNode.className = strNewClass;
	} else {
		var classNames = strNewClass.split(rspace);
		var className = " " + objNode.className + " ", setClass = objNode.className;
		for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
			if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
				setClass += " " + classNames[c];
			}
		}
		objNode.className = setClass.trim();
	}
}

function replaceClass( objNode, strNewClass, strCurrClass ) {
	var strOldClass = strNewClass;
	if ( strCurrClass && strCurrClass.length ){
		strCurrClass = strCurrClass.replace( /\s+(\S)/g, '|$1' );
		if ( strOldClass.length ) strOldClass += '|';
		strOldClass += strCurrClass;
	}
	objNode.className = objNode.className.replace( new RegExp('(^|\\s+)(' + strOldClass + ')($|\\s+)', 'g'), '$1' );
	objNode.className += ( (objNode.className.length)? ' ' : '' ) + strNewClass;
}

function matchClass( objNode, strCurrClass ) {
	return ( objNode && objNode.className.length && objNode.className.match( new RegExp('(^|\\s+)(' + strCurrClass + ')($|\\s+)') ) );
}



/*****************************
**     Nodes funcs
******************************/
function getAncestorByClassName( oCurrentElement, sClassName, sTagName ) {
	var oCurrent = oCurrentElement.parentNode;
	while ( oCurrent.parentNode ) {
		if ( matchClass( oCurrent, sClassName ) && ( !sTagName || oCurrent.tagName.toLowerCase() == sTagName.toLowerCase() ) ) return oCurrent;
		oCurrent = oCurrent.parentNode;
	}
}

function getElementsByClassName(objParentNode, strNodeName, strClassName){
	//return _('.' + strClassName, objParentNode);
	var nodes = objParentNode.getElementsByTagName(strNodeName);
	if(!strClassName){
		return nodes;
	}
	var nodesWithClassName = [];
	for(var i=0; i<nodes.length; i++){
		if(matchClass( nodes[i], strClassName )){
			//nodesWithClassName.push(nodes[i]);
			nodesWithClassName[nodesWithClassName.length] = nodes[i];
		}
	}
	return nodesWithClassName;
}

function getParentByClassName(element, className){
	var currentElement = element;
	while(currentElement.parentNode && !matchClass(currentElement.parentNode, className)){
		currentElement = currentElement.parentNode;
		if (currentElement.tagName.toLowerCase() == 'body') {
			return null;
			break;
		}
	}
	return currentElement.parentNode;
}

function getParentByTagName(element, tagName){
	var currentElement = element;
	while(currentElement.parentNode && currentElement.parentNode.tagName.toLowerCase() != tagName){
		currentElement = currentElement.parentNode;
		if (currentElement.tagName.toLowerCase() == 'body') {
			return null;
			break;
		}
	}
	return currentElement.parentNode;
}


function getElementsByClassNameFirstLevel(objParentNode, strNodeName, strClassName){
	var nodes = objParentNode.getElementsByTagName(strNodeName);

	if(!strClassName){
		var nodesFirstLevel = [];
		for(var i=0; i<nodes.length; i++){
			var parent = getParentByTagName(nodes[i], strNodeName);
			var parentOfParent = getParentByTagName(objParentNode, strNodeName);
			if(! parent ||
				parentOfParent && parent == parentOfParent){
				nodesFirstLevel[nodesFirstLevel.length] = nodes[i];
			}
		}
		return nodesFirstLevel;

	} else {
		var nodesWithClassNameFirstLevel = [];
		for(var i=0; i<nodes.length; i++){
			var parent = getParentByClassName(nodes[i], strClassName);
			var parentOfParent = getParentByClassName(objParentNode, strClassName);
			if(matchClass(nodes[i], strClassName) &&
				(! parent ||
					(parentOfParent && parent == parentOfParent)
				)){
				nodesWithClassNameFirstLevel[nodesWithClassNameFirstLevel.length] = nodes[i];
			}
		}
		return nodesWithClassNameFirstLevel;
	}
}


/*****************************
**  Функции позиционирования
******************************/
function getPageY( oElement ) {
	var iPosY = oElement.offsetTop;
	//alert([oElement.className || oElement.tagName, oElement.offsetTop]);
	while ( oElement.offsetParent != null ) {
		oElement = oElement.offsetParent;
		iPosY += oElement.offsetTop;

		//alert([oElement.className || oElement.tagName, oElement.offsetTop]);
		if (oElement.tagName == 'BODY') break;
	}
	return iPosY;
}

function getPageX( oElement ) {
	var iPosX = oElement.offsetLeft;
	while ( oElement.offsetParent != null ) {
		oElement = oElement.offsetParent;
		iPosX += oElement.offsetLeft;
		if (oElement.tagName == 'BODY') break;
	}
	return iPosX;
}

function getMousePosition(e) {
	if (e.pageX || e.pageY){
		var posX = e.pageX;
		var posY = e.pageY;
	}else if (e.clientX || e.clientY) 	{
		var posX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		var posY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}
	return {x:posX, y:posY}
}



/*****************************
** Cookies quirksmode.org
******************************/
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}


/*****************************
**   AJAX
******************************/

/*
	url - откуда загружаем
	ajaxCallBackFunction - что вызываем по завершении загрузки
	params - параметры в виде объекта или массива
	callObject - методом какого объекта является ajaxCallBackFunction (если это метод, а не глобальная фунция)
*/
function ajaxGet(
		url,
		ajaxCallBackFunction,
		params,
		callObject,
		ajaxCallBackErrorFunction) {
	// branch for native XMLHttpRequest object
	if (window.XMLHttpRequest) {
		var ajaxObject = new XMLHttpRequest();
		ajaxObject.onreadystatechange = function(){
			ajaxHandler(
				ajaxObject,
				ajaxCallBackFunction,
				params,
				callObject,
				ajaxCallBackErrorFunction);
		};
		ajaxObject.open("GET", url, true);
		ajaxObject.send(null);
	// branch for IE/Windows ActiveX version
	} else if (window.ActiveXObject) {
		var ajaxObject = new ActiveXObject("Microsoft.XMLHTTP");
		if (ajaxObject) {
			ajaxObject.onreadystatechange = function(){
				ajaxHandler(
					ajaxObject,
					ajaxCallBackFunction,
					params,
					callObject,
					ajaxCallBackErrorFunction);
			};
			ajaxObject.open("GET", url, true);
			ajaxObject.send();
		}
	}
}

function ajaxPost(
		url,
		data,
		ajaxCallBackFunction,
		params,
		callObject,
		ajaxCallBackErrorFunction) {
	var ajaxObject = null;

	if (window.XMLHttpRequest) { // branch for native XMLHttpRequest object
		ajaxObject = new XMLHttpRequest();
	} else if (window.ActiveXObject) { // branch for IE/Windows ActiveX version
		var ajaxObject = new ActiveXObject("Microsoft.XMLHTTP");
	}
	if(ajaxObject){
		ajaxObject.onreadystatechange = function(){
			ajaxHandler(
				ajaxObject,
				ajaxCallBackFunction,
				params,
				callObject,
				ajaxCallBackErrorFunction);
		}
		ajaxObject.open("POST", url, true);
		ajaxObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		ajaxObject.setRequestHeader("Content-length", data.length);
		ajaxObject.setRequestHeader("Connection", "close");
		ajaxObject.send(data);
	}
}


function ajaxHandler(
		ajaxObject,
		ajaxCallBackFunction,
		params,
		callObject,
		ajaxCallBackErrorFunction){
	// only if req shows "complete"
	if (ajaxObject.readyState == 4) {
		// only if "OK"
		if (ajaxObject.status == 200) {
			// ...processing statements go here...
			ajaxCallBackFunction.call(callObject, ajaxObject, params);
		} else {
			if(ajaxCallBackErrorFunction){
				ajaxCallBackErrorFunction.call(callObject, ajaxObject);
			} else {
				alert("Возникла ошибка в получении XML данных:\n" + ajaxObject.statusText);
			}
		}
	}
}





/******************************
** Inheritance
******************************/

/* Class inheritance */
Function.prototype.inheritsFrom = function(BaseClass) { // thanks to Kevin Lindsey for this idea
	var Inheritance = function() {};
	Inheritance.prototype = BaseClass.prototype;

	this.prototype = new Inheritance();
	this.prototype.constructor = this;
	this.superClass = BaseClass;
}


if(!Function.prototype.call) { // emulating 'call' function for browsers not supporting it (IE5)
	Function.prototype.call = function() {
		var oObject = arguments[0];
		var aArguments = [];
		var oResult;
		oObject.fFunction = this;
		for (var i = 1; i < arguments.length; i++) {
			aArguments[aArguments.length] = 'arguments[' + i + ']';
		}
		eval('oResult = oObject.fFunction(' + aArguments.join(',') + ')');
		oObject.fFunction = null;
		return oResult;
	}
};


/* Object inheritance */
/*
Object.extendObject = function(destination, source) {
	for (var property in source){
		if(typeof source[property] == 'object' &&
			source[property] != null &&
			source[property].constructor.toString().indexOf('function Array()') == -1 &&
			source[property].constructor.toString().indexOf('function RegExp()') == -1){

			destination[property] = {};
			Object.extendObject(destination[property], source[property]);
		} else {
			destination[property] = source[property];
		}
	}
	return destination;
};
*/

Object.extendObject = function(destination, source){
	for (var property in source) {
		destination[property] = source[property];
	}
	return destination;
};

