/*
 * @author: Alexander Myadzel <aem@teletype.ru>
 * @modified: n/a
 *
 */
 
function removeClassName(oElement, sClassToRemove)
{
	if (hasClassName(oElement, sClassToRemove)) {
		var sCurrentClass = oElement.className || "";
		sClassToRemove = sClassToRemove.replace(/\-/g, "\\-");
		var oRegExp = new RegExp("(^|\\s)?" + sClassToRemove + "($|\\s)?");
		oElement.className = normalizeSpace(sCurrentClass.replace(oRegExp, "$1$2"));
	}
}

function addClassName(oElement, sClassToAdd)
{
	if (!hasClassName(oElement, sClassToAdd)) {
		var sCurrentClass = oElement.className || "";
		oElement.className = sCurrentClass + (sCurrentClass ? " " : "") + sClassToAdd;
	}
}

function hasClassName(oElement, sClassToTest)
{
	var sClassName = sClassToTest.replace(/\-/g, '\\-');
	return oElement.className && oElement.className.match('(^|\\s)' + sClassName + '(\\s|$)');
}



function normalizeSpace(s)
{
	s = s.replace(/\s+/, " ");
	s = s.replace(/^\s+/, "");
	s = s.replace(/\s+$/, "");
	return s;
}

function cleanNode(oNode)
{
	while (oNode.firstChild) {
		oNode.removeChild(oNode.firstChild);
	}
	return oNode;
}

function trim(sValue)
{
    var sValue = sValue.toString();
    return sValue.replace(/^\s+/, '').replace(/\s+$/, '');
}


function inArray(needle, haystack, strict)
{
	for (var i = 0; i < haystack.length; i++) {
		if (strict && haystack[i] === needle) {
			return true;
		}
		
		if (haystack[i] == needle) {
			return true;
		}
	}

	return false;
}


function constrain(mInit, mMin, mMax)
{
    var mReturn = mInit;
    if (mInit < mMin) {
        mReturn = mMin;
    } else if (mInit > mMax) {
        mReturn = mMax;
    }
    return mReturn;
}

function getEventKeyCode(oEvent)
{
    return oEvent.keyCode || oEvent.which || null;    
}

function stopEvent(oEvent)
{
    var oElement = getEventElement(oEvent);

    oEvent.returnValue = false;
    if (oEvent.preventDefault) {
        oEvent.preventDefault();
    }
    
    oEvent.cancelBubble = true;
    if (oEvent.stopPropagation) {
        oEvent.stopPropagation();
    }
}

function addEvent(oElement, sEvent, sCallback, bCapture)
{
    if (oElement.attachEvent) {
        oElement.detachEvent('on' + sEvent, sCallback);
        oElement.attachEvent('on' + sEvent, sCallback);
    } else if (oElement.addEventListener) {
        oElement.addEventListener(sEvent, sCallback, bCapture);
    } else {
        oElement['on' + sEvent] = sCallback;
    }
    return oElement;
}

function removeEvent(oElement, sEvent, sCallback, bCapture)
{
    if (oElement.detachEvent) {
        oElement.detachEvent('on' + sEvent, sCallback);
    } else if (oElement.removeEventListener) {
        oElement.removeEventListener(sEvent, sCallback, bCapture);
    } else {
        oElement['on' + sEvent] = null;
    }
    return oElement;
}

function getEvent(oEvent)
{
    return oEvent || window.event;
}

function getEventElement(oEvent)
{
    var oElement = oEvent.srcElement || oEvent.target;
    
    if (oElement.nodeType == 3) {
        oElement = oEvent.oElement.parentNode;
    }
    
    return oElement;
}

function getRelatedTarget(oEvent)
{
	if (oEvent.type == 'mouseover') {
		return oEvent.relatedTarget || oEvent.fromElement;
	} else if (oEvent.type == 'mouseout') {
		return oEvent.relatedTarget || oEvent.toElement;
	} 
	return null;
}

function unescapeHTML(sValue)
{
    var sValue = sValue.toString();
    return sValue.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#39;/g, '\'').replace(/&amp;/g, '&');
}


function getElementById(sId)
{
    return $$(sId);
}

function $$(sId)
{
    return document.getElementById(sId);
}

function getParentByClassName(oElement, sClassName) {
	var oParent = oElement.parentNode;
	while (oParent && oParent.parentNode && !hasClassName(oParent, sClassName)) {
        oParent = oParent.parentNode;
    }
    return oParent;
}

function getElementsByClassName(sClassName, oParentElement)
{
    var oParentElement = oParentElement || document;
    
    if (document.getElementsByClassName) { 
        //https://developer.mozilla.org/en/DOM/document.getElementsByClassName
        return oParentElement.getElementsByClassName(sClassName); 
    } 
    
    var aReturnElements = [];
    var sClassName = sClassName.replace(/\-/g, '\\-');
    var aElements = oParentElement.all ? oParentElement.all : oParentElement.getElementsByTagName('*');

    for (var i = 0; i < aElements.length; i++) {
        if (aElements[i].className.match('(^|\\s)' + sClassName + '(\\s|$)')) {
            aReturnElements.push(aElements[i]);
        }
    }

    return aReturnElements;
}

function getAncestorOrSelfByClassName(oElement, sClassName) {
	var oParent = oElement;
	while (oParent && oParent.parentNode && !hasClassName(oParent, sClassName)) {
        oParent = oParent.parentNode;
    }
	return hasClassName(oParent, sClassName) ? oParent : null;
}

function getOffset(oElement)
{
    var iTop = 0;
    var iLeft = 0;

    while (oElement.tagName != 'HTML' && oElement.tagName != 'BODY')
    {
        iTop += oElement.offsetTop;
        iLeft += oElement.offsetLeft;
            
        oElement = oElement.offsetParent;
    }
    
    iTop += oElement.offsetTop;
    iLeft += oElement.offsetLeft;
    
    return {
        'top': iTop, 
        'left': iLeft
    }
}

function getNextIndex(iPlanIndex, iLength)
{
    if (iPlanIndex >= iLength) {
        iPlanIndex = 0;
    } else if (iPlanIndex < 0) {
        iPlanIndex = iLength - 1;
    }
    return iPlanIndex;
}

function getParentElement(oElement, sParentNodeName)
{
	var oParent = oElement.parentNode;
	while (oParent.nodeName.toLowerCase() != sParentNodeName.toLowerCase()) {
		oParent = oParent.parentNode;
	}

	return oParent;
}

function getParentElementOrSelf(oElement, sParentNodeName)
{
	return oElement.nodeName.toLowerCase() != sParentNodeName.toLowerCase() ? getParentElement(oElement, sParentNodeName) : oElement;
}


function getRightCase(iNumber, aWords)
{
	var sNumber = "0" + iNumber.toString();
	
	var iLast = parseInt(sNumber.slice(-1));
	var iTens = parseInt(sNumber.slice(-2).substring(0, 1));

	var sNominative = aWords[0];
	var sGenitiveSingular = aWords[1];
	var sGenitivePlural = aWords[2];

	if (iTens == 1) {
		return sGenitivePlural;
	} else if (iLast == 1) {
		return sNominative;
	} else if (iLast > 0 && iLast < 5) {
		return sGenitiveSingular;
	} else {
		return sGenitivePlural;
	}
}

function getInt(mValue)
{
    var iValue = parseFloat((mValue + '').replace(/[,]+/g, '.').replace(/[^-\d\.]+/g, ''));
    return isNaN(iValue) ? 0 : iValue;
}

function removeClassName(oElement, sClassToRemove)
{
	var sCurrentClass = oElement.className || "";
	sClassToRemove = sClassToRemove.replace(/\-/g, "\\-");
	var oRegExp = new RegExp("(^|\\s)?" + sClassToRemove + "($|\\s)?");
	oElement.className = sCurrentClass.replace(oRegExp, "");
}

function addClassName(oElement, sClassToAdd)
{
	removeClassName(oElement, sClassToAdd);
	var sCurrentClass = oElement.className || "";
	oElement.className = sCurrentClass + (sCurrentClass ? " " : "") + sClassToAdd;
}


if (!Array.prototype.diff) {
	Array.prototype.diff = function(aDiff)
	{
		if (!aDiff.length) {
			return this;
		}
		var a = [], i = 0, l = this.length;
		for (; i < l; i++) {
			if (aDiff.indexOf(this[i]) == -1) {
				a.push(this[i]);
			}
		}
		return a;
	}
}


function getRightCase(iNumber, aWords)
{
	var sNumber = '0' + iNumber.toString();
	
	var iLast = parseInt(sNumber.slice(-1));
	var iTens = parseInt(sNumber.slice(-2).substring(0, 1));

	var sNominative = aWords[0];
	var sGenitiveSingular = aWords[1];
	var sGenitivePlural = aWords[2];

	if (iTens == 1) {
		return sGenitivePlural;
	} else if (iLast == 1) {
		return sNominative;
	} else if (iLast > 0 && iLast < 5) {
		return sGenitiveSingular;
	} else {
		return sGenitivePlural;
	}
}

function getParentElement(oElement, sParentNodeName)
{
	var oParent = oElement.parentNode;
    while (oParent && oParent.parentNode && oParent.nodeName.toLowerCase() != sParentNodeName.toLowerCase()) {
        oParent = oParent.parentNode;
    }
    return oParent;
}

function isValidKeyForSuggest(iKeyCode)
{
	return !((iKeyCode == 9) || (iKeyCode == 13) // tab, enter
		|| (iKeyCode == 16) || (iKeyCode == 17) // shift, ctl
		|| (iKeyCode >= 18 && iKeyCode <= 20) // alt, pause/break,caps lock
		|| (iKeyCode == 27) // esc
		|| (iKeyCode >= 33 && iKeyCode <= 35) // page up,page down,end
		|| (iKeyCode >= 36 && iKeyCode <= 38) // home,left,up
		|| (iKeyCode == 40) // down
		|| (iKeyCode >= 36 && iKeyCode <= 40) // home,left,up, right, down
		|| (iKeyCode >= 44 && iKeyCode <= 45) // print screen,insert
	);
}





