/*-------------------------------------------------------------------------------------*/
/**
 * The only function that is outsite the xmUtil object
 */
function $_(obj)
{
    if (typeof obj == 'object' && obj !== null) return obj;
    if (typeof obj == 'string') return document.getElementById(obj);
    return false;
}

/*-------------------------------------------------------------------------------------*/
/**
 *
 */

var xmUtils = new function()
{
    this.isObject = function (x)
    {
        return typeof x == "object" && x !== null;
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isNumber = function (x)
    {
        return typeof x == "number";
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isArray = function (x)
    {
        return typeof x == 'object' && x !== null && x.constructor == Array;
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isBool = function (x)
    {
        return typeof x == "boolean";
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isString = function (x)
    {
        return typeof x == "string";
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isStringEmpty = function (x)
    {
        return (typeof x == "string") && (x == "");
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isUndefined = function (x)
    {
        return typeof x == "undefined";
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isUndefOrNull = function (x)
    {
        return typeof x == "undefined" || x === null;
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isFunction = function (x)
    {
        return typeof x == "function";
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.serializeArray = function (aArray)
    {
        var k, serialized = "";
        for (k in aArray)
            serialized += encodeURIComponent(aArray[k]) + "&";
        return serialized;
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.unserializeArray = function (aString)
    {
        if (!xmUtils.isString(aString)) return [];

        var k, elements = aString.split("&");

        for (k in elements)
            elements[k] = decodeURIComponent(elements[k]);

        return elements;
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.toInt = function (num, def, radix)
    {
        return isNaN(num) ? (isNaN(def) ? 0 : parseInt(def)) : parseInt(num, radix ? radix : 10);
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.createCookie = function (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=/";
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.readCookie = function (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;
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.eraseCookie = function (name)
    {
        xmUtils.createCookie(name, "", -1);
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.getElementX = function (obj, endObject, considerPosition, considerIfThisObjectIsAChild)
    {
        var curleft = 0, sPosition;
        if (obj.offsetParent)
        {
            while (obj.offsetParent && obj != endObject)
            {
                curleft += obj.offsetLeft;
                obj = obj.offsetParent;
                if (!obj.offsetParent && xmUtils.getStyleProp(obj, 'position') == 'fixed') { curleft += obj.offsetLeft; }
                if (considerPosition && (!considerIfThisObjectIsAChild || xmUtils.isChildOf(considerIfThisObjectIsAChild, obj))) {
                    sPosition = xmUtils.getStyleProp(obj, 'position');
                    if (sPosition == 'relative' || sPosition == 'absolute') break;
                }
            }
        }
        else if (typeof obj.x != "undefined")
            curleft += obj.x;
        return curleft;/* + (is_ie ? 12 : 0);*/
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.getElementY = function (obj, endObject, considerPosition, considerIfThisObjectIsAChild)
    {
        var curtop = 0, sPosition;
        if (obj.offsetParent)
        {
            while (obj.offsetParent && obj != endObject)
            {
                curtop += obj.offsetTop;
                obj = obj.offsetParent;
                if (!obj.offsetParent && xmUtils.getStyleProp(obj, 'position') == 'fixed') { curtop += obj.offsetTop; }
                if (considerPosition && (!considerIfThisObjectIsAChild || xmUtils.isChildOf(considerIfThisObjectIsAChild, obj))) {
                    sPosition = xmUtils.getStyleProp(obj, 'position');
                    if (sPosition == 'relative' || sPosition == 'absolute') break;
                }
            }
        }
        else if (typeof obj.y != "undefined")
            curtop += obj.y;
        return curtop;/* + (is_ie ? 17 : 0);*/
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.getChildNodesList = function (aObj, aOutput, tag, recursive)
    {
        if (typeof aObj != 'object' || aObj === null) return;
        var child = aObj.firstChild;
        if (!child) return;
        tag = typeof tag == 'string' ? tag : "";

        do
        {
            if (tag == "" || (child.nodeType != 3 && child.tagName && child.tagName.toLowerCase() == tag))
                aOutput[aOutput.length] = child;
            if (child.firstChild && recursive == true)
                xmUtils.getChildNodesList(child, aOutput, tag, recursive);
            child = child.nextSibling;
        }
        while (child);
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.arraySearch = function (aArray, aNeedle)
    {
        if (!xmUtils.isArray(aArray)) return false;

        var key;
        for (key in aArray)
            if (aArray[key] === aNeedle)
                return key;
        return false;
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.isMouseIn = function (obj)
    {
        if (!xmUtils.isObject(obj))
            return false;

        oX = xmUtils.getElementX(obj);
        oY = xmUtils.getElementY(obj);
        oW = obj.offsetWidth;
        oH = obj.offsetHeight;
        if (xmGlobalEvents.mousePos.x <= (oX + oW) &&
            xmGlobalEvents.mousePos.x >= oX &&
            xmGlobalEvents.mousePos.y <= (oY + oH) &&
            xmGlobalEvents.mousePos.y >= oY)
        return true; else return false;
    };

    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.bubbleEvent = function (aEvent, aBubble)
    {
        if (!aEvent)
            if (!(aEvent = window.event)) return;

        aEvent.cancelBubble = !aBubble;

        if (aEvent.stopPropagation && !aBubble)
            aEvent.stopPropagation();
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.clearDocumentSelection = function ()
    {
        if (document.selection)
            if (document.selection.clear)
                document.selection.clear();

        if (window.getSelection)
        {
            if (window.getSelection().removeAllRanges)
                window.getSelection().removeAllRanges();
        }
        else
        {
            if (document.getSelection)
                if (document.getSelection().removeAllRanges)
                    document.getSelection().removeAllRanges();
        }

        if (document.clearSelection)
            document.clearSelection();
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.centerWindow = function (wnd, bFixed)
    {
        wnd = $_(wnd);

        if (!wnd) return;

        xmUtils.centerWindowH(wnd, bFixed);
        xmUtils.centerWindowV(wnd, bFixed);
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.centerWindowV = function (wnd, bFixed)
    {
        wnd = $_(wnd);

        if (!wnd) return;

        var x = Math.floor((xmUtils.getDocumentDimensions().w  - wnd.offsetWidth)  / 2);
        wnd.style.left = ((x < 0) ? 0 : x) + (bFixed ? 0 : xmUtils.getDocumentScroll().x) + "px";
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.centerWindowH = function (wnd, bFixed)
    {
        wnd = $_(wnd);

        if (!wnd) return;

        var y = Math.floor((xmUtils.getDocumentDimensions().h - wnd.offsetHeight) / 2);
        wnd.style.top  = ((y < 0) ? 0 : y) + (bFixed ? 0 : xmUtils.getDocumentScroll().y)  + "px";
    };


    this.center = function(oNode)
    {
        oNode = $($_(oNode));
        if (!oNode.length) return;
        var oDocDims = xmUtils.getDocumentDimensions(),
            oDocScroll = xmUtils.getDocumentScroll(),
            bIsFixed = oNode.css('position') == 'fixed',
            x = Math.floor((oDocDims.w - oNode[0].offsetWidth) / 2),
            y = Math.floor((oDocDims.h - oNode[0].offsetHeight) / 2);

        oNode[0].style.left = ((x < 0) ? 0 : x) + (bIsFixed ? 0 : oDocScroll.x) + "px";
        oNode[0].style.top = ((y < 0) ? 0 : y) + (bIsFixed ? 0 : oDocScroll.y) + "px";
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.getDocumentDimensions = function ()
    {
        if (self.innerWidth)
        {
            return {
                w : self.innerWidth,
                h : self.innerHeight
            }
        }
        else if (document.documentElement && document.documentElement.clientWidth)
        {
            return {
                w : document.documentElement.clientWidth,
                h : document.documentElement.clientHeight
            }
        }
        else if (document.body)
        {
            return {
                w : document.body.clientWidth,
                h : document.body.clientHeight
            }
        }

        return { w : 0, h : 0 }
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.getDocumentScroll = function ()
    {
        var scrOfX = 0, scrOfY = 0;

        if( typeof( window.pageYOffset ) == 'number' )
        {
            return {
                y : window.pageYOffset,
                x : window.pageXOffset
            }
        }
        else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) )
        {
            return {
                y : document.body.scrollTop,
                x : document.body.scrollLeft
            }
        }
        else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) )
        {
            return {
                y : document.documentElement.scrollTop,
                x : document.documentElement.scrollLeft
            }
        }

        return { x : 0, y : 0 }
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.encodeURLParam = function (param)
    {
        if (param === null | xmUtils.isUndefined(param))
            return '';
        return encodeURIComponent(param);
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    var _stylePropertiesTranslation = {};
    if (!document.hasAttributes)
        _stylePropertiesTranslation = {
            'margin-top' : 'marginTop',
            'margin-right' : 'marginRight',
            'margin-bottom' : 'marginBottom',
            'margin-left' : 'marginLeft',
            'float' : 'styleFloat',
            'z-index' : 'zIndex'
        };
    this.getStyleProp = function(element, property)
    {
        var element = $_(element),
            value = null;
        if (element === null) return null;
        property = typeof _stylePropertiesTranslation[property] == 'undefined' ? property : _stylePropertiesTranslation[property];
        if (typeof element.currentStyle != 'undefined') {
            value = element.currentStyle[property];
        } else if (document.defaultView && document.defaultView.getComputedStyle) {
            return document.defaultView.getComputedStyle(element, null).getPropertyValue(property);
        }
        return value;
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.htmlSpecialChars = function (aString)
    {
        return (aString + "").replace('&','&amp;').replace('<', '&lt;').replace('>','&gt;');
    };


    var __atSign = '(malpa)', __dotSign = "(kropka)";
    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.decodeEmailLink = function (aElement)
    {
        if (!(aElement = $_(aElement))) return;
        aElement.innerHTML = aElement.innerHTML.replace(new RegExp(xmUtils.regExpEscape(__atSign),'ig'), '@').replace(new RegExp(xmUtils.regExpEscape(__dotSign),'ig'), '.');
        aElement.href = aElement.href.replace(new RegExp(xmUtils.regExpEscape(encodeURIComponent(__atSign)),'ig'), '@').replace(new RegExp(xmUtils.regExpEscape(encodeURIComponent(__dotSign)),'ig'), '.');
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.decodeEmailLinks = function ()
    {
        $("a[href^='mailto:']").each(function() { xmUtils.decodeEmailLink(this); });
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.regExpEscape = function (exp, sDelimiter)
    {
        if (!xmUtils.isString(exp)) return "";
        if (!sDelimiter) sDelimiter = '/';
        var specials = [sDelimiter, '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
        var re = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
        return exp.replace(re, '\\$1');
    };


    /*-------------------------------------------------------------------------------------*/
    /**
     *
     */
    this.getObjFromArrayById = function (aObjArray, aId)
    {
        var i;
        for (i in aObjArray)
            if (aObjArray[i].id == aId)
                return aObjArray[i];

        return false;
    };


    /*-------------------------------------------------------------------------------------*/
    this.setOpacity = function (aElement, aOpacity)
    {
        $(aElement).css('opacity', aOpacity);
    };


    /*-------------------------------------------------------------------------------------*/
    this.getOpacity = function (aElement)
    {
        return parseFloat($(aElement).css('opacity'));
    };


    /*-------------------------------------------------------------------------------------*/
    this.getWindowInnerHeight = function ()
    {
        return xmUtils.getSiteH();
    };


    /*-------------------------------------------------------------------------------------*/
    this.getWindowInnerWidth = function ()
    {
        return xmUtils.getSiteW();
    };


    /*-------------------------------------------------------------------------------------*/
    this.getSiteH = function ()
    {
        return Math.max(Math.max(window.document.body.offsetHeight, window.innerHeight ? window.innerHeight : window.document.documentElement.clientHeight), window.document.documentElement.scrollHeight);
    };


    /*-------------------------------------------------------------------------------------*/
    this.getSiteW = function ()
    {
        return Math.max(window.innerWidth ? window.innerWidth : window.document.documentElement.clientWidth, window.document.documentElement.scrollWidth);
    };


    /*-------------------------------------------------------------------------------------*/
    this.getWindowInnerH = function ()
    {
        return window.innerHeight ? window.innerHeight : window.document.documentElement.clientHeight;
    };


    /*-------------------------------------------------------------------------------------*/
    this.getWindowInnerW = function ()
    {
        return window.innerWidth ? window.innerWidth : window.document.documentElement.clientWidth;
    };


    /*-------------------------------------------------------------------------------------*/
    this.getWindowInnerRect = function ()
    {
        return {
            w : xmUtils.getWindowInnerW(),
            h : xmUtils.getWindowInnerH(),
            x : window.document.documentElement.scrollLeft,
            y : window.document.documentElement.scrollTop
        }
    };


    /*-------------------------------------------------------------------------------------*/
    this.getMouseSector = function ()
    {
        var wRect = xmUtils.getWindowInnerRect(),
            mouseRelX = xmGlobalEvents.mousePos.x - wRect.x,
            mouseRelY = xmGlobalEvents.mousePos.y - wRect.y,
            xBorder = wRect.w / 2,
            yBorder = wRect.h / 2;

        return mouseRelX < xBorder ? (mouseRelY < yBorder ? 1 : 3) : (mouseRelY < yBorder ? 2 : 4);
    };


    /*-------------------------------------------------------------------------------------*/
    this.checkEmailSyntax = function (aEmail)
    {
        return /^\s*[a-z0-9]+[\w\-\.]*@([\w\-]+\.)+[a-z]+\s*$/i.test(aEmail);
    };


    /*-------------------------------------------------------------------------------------*/
    this.showHideElement = function (aElement)
    {
        try
        {
            aElement = $_(aElement);
            aElement.style.display = aElement.style.display == "none" ? "" : "none";
        }
        catch (e) {}
    };


    /*-------------------------------------------------------------------------------------*/
    this.stringToHash = function (aString, aSeparator, bDecode)
    {
        if (xmUtils.isUndefined(aSeparator))
            aSeparator = ',';

        var data = aString.split(aSeparator), param, hash = [],
            i;
        for (i in data)
        {
            if (typeof data[i] != "string")
                continue;

            param = data[i].split('=');
            if (bDecode)
                 hash[decodeURIComponent(param[0])] = decodeURIComponent(param[1]);
            else hash[param[0]] = param[1];
        }

        return hash;
    };

    /*-------------------------------------------------------------------------------------*/
    this.replaceCharAt = function (aString, aIndex, aReplacement)
    {
        return "".concat(
            aString.substring(0, aIndex),
            aReplacement,
            aString.substring(aIndex + 1, aString.length));
    };

    /*-------------------------------------------------------------------------------------*/
    this.getUpperFolder = function (aFolder)
    {
        var folders = aFolder.split('/'),
            result = '';

        for (var i = 0; i < folders.length - 2; i++)
            if (folders[i] != '')
                result += folders[i] + '/';

        return result;
    };


    /*-------------------------------------------------------------------------------------*/
    this.lTrim = function ( value )
    {
        var re = /\s*((\S+\s*)*)/;
        return value.replace(re, "$1");

    };


    /*-------------------------------------------------------------------------------------*/
    this.rTrim = function( value )
    {
        var re = /((\s*\S+)*)\s*/;
        return value.replace(re, "$1");
    };


    /*-------------------------------------------------------------------------------------*/
    this.trim = function( value )
    {
        return xmUtils.lTrim(xmUtils.rTrim(value));
    };


    /*-------------------------------------------------------------------------------------*/
    this.fileName = function( aPath )
    {
        var pathParts = aPath.split(/\\|\//);
        return pathParts[pathParts.length - 1];
    };


    /*-------------------------------------------------------------------------------------*/
    this.fileExtension = function( aPath )
    {
        var pathParts = aPath.split('.');
        return pathParts[pathParts.length - 1];
    };


    /*-------------------------------------------------------------------------------------*/
    this.moveOptions = function( aSource, aDestination )
    {
        aSource = $_(aSource);
        aDestination = $_(aDestination);

        if (!aSource || !aDestination) return false;

        for (var i = aSource.length - 1; i >= 0; i--)
        {
            if (!aSource.options[i].selected) continue;
            aDestination.options[aDestination.options.length] = new Option(aSource.options[i].text, aSource.options[i].value);
            aSource.options[i] = null;
        }

        return true;
    };


    /*-------------------------------------------------------------------------------------*/
    this.executeScriptTags = function(aContainer, aStringContent)
    {
        if (xmUtils.isString(aStringContent))
        {
            aContainer = document.createElement('span');
            aContainer.innerHTML = aStringContent;
        }
        else aContainer = $_(aContainer);

        if(!aContainer) return;

        var elements = [];
        xmUtils.getChildNodesList(aContainer, elements, 'script', true);

        var i;
        for (i in elements)
        {
            if (!xmUtils.isObject(elements[i])) continue;
            try
            {
                if (elements[i].src != '')
                {
                    var newElement = document.createElement('script');
                    elements[i].parentNode.appendChild(newElement);
                    newElement.src = elements[i].src;
                    elements[i].parentNode.removeChild(elements[i]);
                }
                window.eval(elements[i].innerHTML);
            }
            catch (e) { continue; }
        }
    };


    /*-------------------------------------------------------------------------------------*/
    this.createXHRObject = function()
    {
        if(window.XMLHttpRequest)
        {
            try {
                return new XMLHttpRequest();
            } catch(e) {
                return false;
            }
        }
        else if(window.ActiveXObject)
        {
            var xhrVersions = new Array(
                'MSXML2.XMLHTTP.6.0',
                'MSXML2.XMLHTTP.5.0',
                'MSXML2.XMLHTTP.4.0',
                'MSXML2.XMLHTTP.3.0',
                'MSXML2.XMLHTTP',
                'Microsoft.XMLHTTP'
            );

            for (var i = 0; i < xhrVersions.length && !this.fXhr; i++)
            {
                try
                {
                    return new ActiveXObject(xhrVersions[i]);
                }
                catch (e) { continue; }
            }
        }
        return false;
    };


    /*-------------------------------------------------------------------------------------*/
    this.removePrecedentSlash = function(aPath)
    {
        if (aPath.charAt(0) == '/' || aPath.charAt(0) == '\\')
            return aPath.substr(1, aPath.length);
        return aPath;
    };


    /*-------------------------------------------------------------------------------------*/
    this.validateTextAreaLength = function(aEvent, aTextArea, aMaxLength)
    {
        aEvent = (aEvent) ? aEvent : window.event;

        var ctrlKeys = {
            37 : 1, // left
            38 : 1, // up
            39 : 1, // right
            40 : 1, // down
            8  : 1, // backspace
            46 : 1, // delete
            9  : 1, // tab
            33 : 1, // pgUp
            34 : 1, // pgDown
            17 : 1, // ctrl
            18 : 1, // alt
            20 : 1, // caps
            16 : 1, // shift
            35 : 1, // home
            36 : 1, // end
            44 : 1  // printSrc
         }, i, keyCode;

        if (aEvent.keyCode)
             keyCode = aEvent.keyCode;
        else keyCode = aEvent.which;

        try
        {
            if (aTextArea.value.length > aMaxLength)
            {
                return (keyCode in ctrlKeys);
            }
            return true;
        }
        catch (e)
        {
            return true;
        }
    };


    /*-------------------------------------------------------------------------------------*/
    this.toggleFormElements = function(aParent, aEnable, aRememberState)
    {
        $('input,textarea,button').each(function() {
            if (aRememberState)
            {
                if (aEnable)
                     elements[i][j]._beforeEnableState = elements[i][j].disabled;
                else elements[i][j]._beforeDisableState = elements[i][j].disabled;
            }
            elements[i][j].disabled =
                aEnable ?
                    (xmUtils.isUndefined(elements[i][j]._beforeDisableState) ? true : elements[i][j]._beforeDisableState )
                    :
                    (xmUtils.isUndefined(elements[i][j]._beforeEnableState) ? false : elements[i][j]._beforeEnableState);
        });
    };


    /*-------------------------------------------------------------------------------------*/
    this.getZIndex = function(aElement, aDefault, aDefaultOnAuto)
    {
        var index = $(aElement).css('z-index');
        if (index == 'auto' && aDefaultOnAuto)
            return aDefault;
        return isNaN(index.toString()) ? aDefault : parseInt(index);
    };


    /*-------------------------------------------------------------------------------------*/
    this.getElementCaretPos = function (aElement)
    {
        var iCaretPos = 0;
        aElement = $_(aElement);

        if (document.selection)
        {
            aElement.focus ();
            var oSel = document.selection.createRange ();
            oSel.moveStart ('character', -aElement.value.length);
            iCaretPos = oSel.text.length;
        }
        else
            if (aElement.selectionStart || aElement.selectionStart == '0')
                iCaretPos = aElement.selectionStart;

        return (iCaretPos);
    };


    /*-------------------------------------------------------------------------------------*/
    this.setElementCaretPos = function (aElement, aCaretPos)
    {
        aElement = $_(aElement);
        if (aElement.createTextRange)
        {
            var range = aElement.createTextRange();
            range.collapse(true);
            range.moveEnd('character', aCaretPos);
            range.moveStart('character', aCaretPos);
            range.select();
        }
        else if (aElement.selectionStart || aElement.selectionStart == '0')
        {
            aElement.selectionStart = aCaretPos;
            aElement.selectionEnd = aCaretPos;
            aElement.focus();
        }
    };


    /*-------------------------------------------------------------------------------------*/
    this.inputFilter = new function()
    {
        this._maskChars = {
            '9' : {
                exp : /[0-9]{1}/,
                alt : '_'
            },

            'A' : {
                exp : /[a-z]{1}/i,
                alt : '_'
            },

            'L' : {
                exp : /[a-z]{1}/i,
                alt : '_',
                trans : function(aChar) { return aChar.toLowerCase() }
            },

            'U' : {
                exp : /[a-z]{1}/i,
                alt : '_',
                trans : function(aChar) { return aChar.toUpperCase() }
            }
        };

        this._keys = {
            arrows : {
                37 : 1, // left
                38 : 1, // up
                39 : 1, // right
                40 : 1  // down
            },
            erase : {
                8  : 1, // backspace
                46 : 1  // delete
            },
            allowed : {
                9  : 1, // tab
                33 : 1, // pgUp
                34 : 1, // pgDown
                17 : 1, // ctrl
                18 : 1, // alt
                20 : 1, // caps
                16 : 1, // shift
                35 : 1, // home
                36 : 1, // end
                44 : 1, // printSrc,
                144: 1  // numlock
            }
        };


        /*-------------------------------------------------------------------------------------*/
        this.applyTo = function(aInput, aMask, aResult, aNoMatchReplacements)
        {
           if (!(aInput = $_(aInput)))
                return;

           var maskChar, displayMask = aMask;

           for (maskChar in xmUtils.inputFilter._maskChars)
                displayMask = displayMask.replace(new RegExp(maskChar, 'g'), xmUtils.inputFilter._maskChars[maskChar].alt);

           this.validateInput(aMask, aInput);
           aInput._xminputfilter = {
                mask : aMask,
                result : aResult,
                noMatchAlts : aNoMatchReplacements
           };

           var handler = new Function('event', "return xmUtils.inputFilter.execFilterEvent(window.event ? window.event : event)");
           if (window.opera)
                aInput.onkeypress = handler;
           else aInput.onkeydown = handler;

           var firstEditable = -1;
           while (!xmUtils.inputFilter._maskChars[aMask.charAt(++firstEditable)]);

           aInput.onfocus = new Function("xmUtils.setElementCaretPos(this, " + firstEditable + ")");
        };


        /*-------------------------------------------------------------------------------------*/
        this.execFilterEvent = function(aEvent)
        {
            if (!(input = aEvent.target || aEvent.srcElement))
                return;

            var mask;

            if (!input._xminputfilter || !xmUtils.isString(mask = input._xminputfilter.mask))
                return;

            input.onkeyup = null;

            if (window.opera && input.onkeydown)
            {
                input.onkeypress = input.onkeydown;
                input.onkeydown = null;
                return true;
            }

            var keyCode = aEvent.keyCode || aEvent.which,
                keyChar = String.fromCharCode(keyCode),
                caretPos = xmUtils.getElementCaretPos(input),
                maskChar = mask.charAt(caretPos),
                isPrintable = new RegExp('[0-9a-z]{1}', 'i'),
                deleteCharacterIndex = 0;

            if (xmUtils.inputFilter._keys.allowed[keyCode] || xmUtils.inputFilter._keys.arrows[keyCode])
                return true;

            if (isPrintable.test(keyChar))
            {
                if (caretPos >= mask.length)
                    return false;

                caretPos = xmUtils.inputFilter.validateInput(mask, input, caretPos);
                maskChar = mask.charAt(caretPos);

                if (!xmUtils.inputFilter._maskChars[maskChar])
                    return false;

                if (xmUtils.inputFilter._maskChars[maskChar].exp.test(keyChar))
                {
                    deleteCharacterIndex = caretPos;
                    if (mask.length > (caretPos + 1) && !xmUtils.inputFilter._maskChars[mask.charAt(caretPos + 1)])
                        caretPos = xmUtils.inputFilter.validateInput(mask, input, caretPos + 1);
                    else caretPos++;

                    input.value = xmUtils.replaceCharAt(input.value, deleteCharacterIndex, '');
                    input.value = input.value.substr(0, mask.length);
                    xmUtils.setElementCaretPos(input, deleteCharacterIndex);

                    if (xmUtils.isFunction(xmUtils.inputFilter._maskChars[maskChar].trans))
                         input.onkeyup = new Function(
                            "this.value = xmUtils.replaceCharAt(this.value, " + (deleteCharacterIndex) + ", '" + xmUtils.inputFilter._maskChars[maskChar].trans(keyChar) + "');"+
                            "xmUtils.setElementCaretPos(this, " + caretPos + ");");
                    else input.onkeyup = new Function("xmUtils.setElementCaretPos(this, " + caretPos + ")");

                    return true;
                }

                return false;
            }

            if (xmUtils.inputFilter._keys.erase[keyCode])
            {
                if (window.opera)
                {
                    input.value = input.value.substr(0, mask.length + (caretPos == mask.length ? 0 : -1));
                    input.onkeyup = new Function('event',
                        "xmUtils.inputFilter.validateInput('" + mask + "', this);"+
                        "xmUtils.setElementCaretPos(this, " + (caretPos + (keyCode == 8 ? -1 :0)) + ");");
                    return true;
                }
                else
                {
                    if (keyCode == 46)
                    {
                        if (xmUtils.inputFilter._maskChars[mask.charAt(caretPos)] && input.value.charAt(caretPos) != '')
                            input.value = xmUtils.replaceCharAt(input.value, caretPos, xmUtils.inputFilter._maskChars[mask.charAt(caretPos)].alt);
                    }
                    else if (keyCode == 8)
                    {
                        while (!xmUtils.inputFilter._maskChars[mask.charAt(caretPos - 1)] && caretPos >= 0)
                            caretPos--;
                        if (input.value.charAt(caretPos - 1) != '')
                            input.value = xmUtils.replaceCharAt(input.value, --caretPos, xmUtils.inputFilter._maskChars[mask.charAt(caretPos)].alt);
                    }
                    input.value = input.value.substr(0, mask.length);
                    xmUtils.setElementCaretPos(input, caretPos);
                }
            }

            return false;
        };


        /*-------------------------------------------------------------------------------------*/
        this.validateInput = function(aMask, aInput, aStartPos)
        {
            var maskChar;

            if (xmUtils.isUndefined(aStartPos))
            {
                aStartPos = -1;
                while (aMask.length > ++aStartPos)
                {
                    maskChar = aMask.charAt(aStartPos);

                    if (!xmUtils.inputFilter._maskChars[maskChar])
                         aInput.value = xmUtils.replaceCharAt(aInput.value, aStartPos, maskChar);
                    else if (!xmUtils.inputFilter._maskChars[maskChar].exp.test(aInput.value.charAt(aStartPos)))
                         aInput.value = xmUtils.replaceCharAt(aInput.value, aStartPos, xmUtils.inputFilter._maskChars[maskChar].alt);
                }
            }
            else
                while (aMask.length > aStartPos && !xmUtils.inputFilter._maskChars[aMask.charAt(aStartPos)])
                    aInput.value = xmUtils.replaceCharAt(aInput.value, aStartPos, aMask.charAt(aStartPos++));

            return aStartPos;
        };
    };


    /*-------------------------------------------------------------------------------------*/
    this.toASCIString = function (aString)
    {
        var search = [
                'ą','Ą',
                'ć','Ć',
                'ę','Ę',
                'ł','Ł',
                'ń','Ń',
                'ó','Ó',
                'ś','Ś',
                'ż','Ż',
                'ź','Ź'
            ],
            replace = [
                'a','A',
                'c','C',
                'e','E',
                'l','L',
                'n','N',
                'o','O',
                's','S',
                'z','Z',
                'z','Z'
            ];

        for (var i = 0; i < search.length; i++)
            aString = aString.replace(search[i], replace[i]);

        return aString;
    };


    /*-------------------------------------------------------------------------------------*/
    this.ksort = function (aArray, aByNumbers)
    {
        var keysArray = [];
        for (var i in aArray)
            keysArray.push([i, aArray[i]]);

        keysArray.sort(aByNumbers ? function(a , b){ return a[0] - b[0] } : null);
        aOutput = [];

        for (var i in keysArray)
            aOutput[keysArray[i][0]] = keysArray[i][1];

        return aOutput;
    };


    /*-------------------------------------------------------------------------------------*/
    this.extendObject = function(oExtendedObject, oBaseObject)
    {
        if (typeof oBaseObject != 'object' || oBaseObject === null) return;

        if (oExtendedObject.__parent)
            xmUtils.extendObject(oExtendedObject.__parent, oBaseObject);
        else oExtendedObject.__parent = {};

        for (var iIndex in oBaseObject)
        {
            if (oBaseObject[iIndex] instanceof Function)
                oExtendedObject.__parent[iIndex] = oBaseObject[iIndex];
            oExtendedObject[iIndex] = oBaseObject[iIndex];
        }
    };


    /*-------------------------------------------------------------------------------------*/
    this.makeURIString = function(xURIParams, bEncode)
    {
        var sType = typeof xURIParams;
        if (sType == 'string') return xURIParams;
        if (sType == 'object' && xURIParams !== null)
        {
            var aURIParams = [];
            for (var sKey in xURIParams)
                if (bEncode)
                    aURIParams.push(encodeURIComponent(sKey) + '=' + encodeURIComponent(xURIParams[sKey]));
                else aURIParams.push(sKey + '=' + xURIParams[sKey]);
            return aURIParams.join('&');
        }
        return '';
    };


    /*-------------------------------------------------------------------------------------*/
    this.getJSONObject = function(sJSON)
    {
        var oObject;
        try {
            oObject = window.eval('oObject = ' + sJSON);
        } catch (e) {
            return {};
        }
        return oObject;
    };


    /*-------------------------------------------------------------------------------------*/
    this.dockToObject = function(oDockedObject, oTarget, iDockedObjectCorner, iTargetCorner, iDeltaX, iDeltaY)
    {
        oDockedObject = $_(oDockedObject);
        oTarget = $_(oTarget);

        oDockedObject.style.top = oDockedObject.style.left = '-99999px';

        if (iDockedObjectCorner < 1 || iDockedObjectCorner > 4)
            iDockedObjectCorner = 1;

        if (iTargetCorner < 1 || iTargetCorner > 4)
            iTargetCorner = 1;

        var iTargetX = this.getElementX(oTarget, null, true, oDockedObject),
            iTargetY = this.getElementY(oTarget, null, true, oDockedObject),
            iDX = (iDockedObjectCorner % 2) ? 0 : -oDockedObject.offsetWidth,
            iDY = (iDockedObjectCorner <= 2) ? 0 : -oDockedObject.offsetHeight;

        iTargetX += (iTargetCorner % 2) ? 0 : oTarget.offsetWidth;
        iTargetY += (iTargetCorner <= 2) ? 0 : oTarget.offsetHeight;

        oDockedObject.style.left = (iTargetX + iDX + (isNaN(iDeltaX) ? 0 : iDeltaX)) + 'px';
        oDockedObject.style.top = (iTargetY + iDY + (isNaN(iDeltaY) ? 0 : iDeltaY)) + 'px';
    };


    /*-------------------------------------------------------------------------------------*/
    this.sprintf = function(sFormat, aArguments)
    {
        if (xmUtils.isObject(aArguments)) {
            for (var i = 0; i < aArguments.length; i++)
                sFormat = sFormat.replace('%s', aArguments[i]);
        }
        else {
            for (var i = 1; i < arguments.length; i++)
                sFormat = sFormat.replace('%s', arguments[i]);
        }
        return sFormat;
    };

    /*-------------------------------------------------------------------------------------*/
    this.submitForm = function(oForm, bDontSend)
    {
        oForm = $_(oForm);
        if (!oForm) return;
        if (typeof oForm.onsubmit != 'function' || oForm.onsubmit()) {
            if (!bDontSend) oForm.submit();
            return true;
        }
    };

    /*-------------------------------------------------------------------------------------*/
    this.stripTags = function(sHTML)
    {
        return sHTML.replace(/(<[^>]*>)/g, '');
    };

    /*-------------------------------------------------------------------------------------*/
    this.getNodeText = function(oNode) {
        var text = oNode.textContent || oNode.text || oNode.innerText; return text ? text : '';
    };

    /*-------------------------------------------------------------------------------------*/
    this.isChildOf = function(oNode, oParent) {
        while (oNode) {
            if (oNode.parentNode === oParent) return true;
            oNode = oNode.parentNode;
        }
        return false;
    };
};

/*HTMLElement.prototype.xmSetOpacity = function(iOpacity){ xmUtils.setOpacity(this, iOpacity); return this; };
HTMLElement.prototype.xmGetOpacity = function(){ return xmUtils.getOpacity(this, iOpacity); };
HTMLElement.prototype.xmIsMouseIn = function(){ return xmUtils.isMouseIn(this); };
HTMLElement.prototype.xmGetX = function(){ return xmUtils.getElementX(this); };
HTMLElement.prototype.xmGetY = function(){ return xmUtils.getElementY(this); };
HTMLElement.prototype.xmCenterWindow = function(bFixed){ xmUtils.centerWindow(bFixed); return this; }; */

String.prototype.xmTrim = function(){ return xmUtils.trim(this); };
String.prototype.xmLTrim = function(){ return xmUtils.lTrim(this); };
String.prototype.xmRTrim = function(){ return xmUtils.rTrim(this); };
String.prototype.xmSprintf = function(){ return xmUtils.sprintf(this, arguments); };
String.prototype.xmToHash = function(sSeparator, bDecode){ return xmUtils.stringToHash(this, sSeparator, bDecode); };
String.prototype.xmStripTags = function(){ return xmUtils.stripTags(this); };
String.prototype.xmHtmlSpecialChars = function(){ return xmUtils.htmlSpecialChars(this); };

if (!xmTemplatesStorage) {
    var xmTemplatesStorage = [];
}
