var fs = {
    /* ---class related--- */
    getElementsByClassNameItemName: function(strItemName) {
        return this.getElementsByClassName(strItemName + ':[A-Za-z0-9-]+')
    }
    ,
    getElementClassNameItemValue: function(elm, strItemName) {
        return elm.className.match(new RegExp('(\\s|^)' + strItemName + ':([A-Za-z0-9-]+)(\\s|$)'))[2];
    }
    ,
    getElementsByClassName: function(strClass,elmParent,strTag) {
        var arrClassElements = [];/*store and return matched elements*/
        var elmParent = elmParent || document;
        var strTag = strTag || '*';

        var elmTagNames = elmParent.getElementsByTagName(strTag);
        var intElmLen = elmTagNames.length;
        var reClass = new RegExp('(^|\\s)'+strClass+'(\\s|$)');
        for (i=0, j=0; i<intElmLen; i++) {
            if (reClass.test(elmTagNames[i].className)) {
                arrClassElements[j] = elmTagNames[i];
                j++;
            }
        }
        return arrClassElements;
    }
    ,
    hasClass: function(ele,cls) {
        return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
    }
    ,
    addClass: function(ele,cls) {
        if (!this.hasClass(ele,cls)) ele.className += " "+cls;
    }
    ,
    removeClass: function(ele,cls) {
        if (this.hasClass(ele,cls)) {
            var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
            ele.className=ele.className.replace(reg,' ');
        }
    },
    /* ---event related--- */
    addEvent: null,
    removeEvent: null,
    /* ---url related--- */
    getUrlBase: function(sUrl) {
        return sUrl.split('?')[0];
    },
    getContainingFolder:function(sArgUrl){
        var sUrl = sArgUrl||window.location.href;
        var sNewUrl = sUrl.substring(0, sUrl.lastIndexOf('/'));
        return sNewUrl;
    },
    getUrlParameter: function(sName, sArgUrl) {
        var sUrl = sArgUrl || window.location.href;
        var sUrlParam = sUrl.split('?')[1];
        if (typeof(sUrlParam) != 'undefined') {
            var aNameValue = sUrlParam.split('&')
            for (var i in aNameValue) {
                if (decodeURIComponent(aNameValue[i].split('=')[0]) == sName) {
                    return decodeURIComponent(aNameValue[i].split('=')[1]);
                }
            }
        }
    },
    setUrlParameter: function(sName, sValue, sArgUrl) {
        var sUrl = sArgUrl || window.location.href;
        var sNameEncoded = encodeURIComponent(sName);
        var sValueEncoded = encodeURIComponent(sValue);
        var sUrlToReturn = null;
        if (sUrl.indexOf('?') == -1) {
            sUrlToReturn  = [sUrl,'?',sName,'=',sValue].join('');
        } else {
            var sUrlBase = sUrl.split('?')[0];
            var sUrlParam = sUrl.split('?')[1];
            if (sUrlParam.indexOf(sNameEncoded + '=') == -1) {
                sUrlToReturn = [sUrlBase,'?',sUrlParam,'&',sName,'=',sValue].join('');
            } else {
                sUrlParam = sUrlParam.replace(new RegExp('('+sNameEncoded+')=[^&$]*','g'), [sNameEncoded,'=',sValueEncoded].join(''));
                sUrlToReturn = [sUrlBase,'?',sUrlParam].join('');
            }
        }

        return sUrlToReturn;
    },
    addCallback: function(obj, strFuncName, callback) {
        /* create array to store callback functions, if not already created */
        var strCallbackArrayName = strFuncName.concat('CallbackArray');

        /* create an array to store callback functions whenever the interested
        function is being invoke */
        if(typeof obj[strCallbackArrayName] == 'undefined'){
            /* create array to store callbacks related to the function in interest*/
            obj[strCallbackArrayName] = [];
            /* assign the original function to a new function name, push it in the array */
            var strOriFuncName = strFuncName.concat('Ori');
            obj[strOriFuncName] = obj[strFuncName];
            /* references to function */
            var funcTempFunc = obj[strOriFuncName];
            var arrCallbackArray = obj[strCallbackArrayName];
            arrCallbackArray.push(function(){
                funcTempFunc.apply(obj, arguments);
            });
            /* modify the old function */
            obj[strFuncName] = function(){
                for(var i=0; i<arrCallbackArray.length; i++){
                    arrCallbackArray[i].apply(obj, arguments);
                }
            }
        }

        obj[strCallbackArrayName].push(callback);
    }
    ,
    staticExtend: function(oParent, oChild) {
        for (var attribute in oParent) {
            if (!oChild[attribute]) {
                oChild[attribute] = oParent[attribute];
            }
        }
    }
    ,
    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=/";
    }
    ,
    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;
    }
    ,
    eraseCookie: function(name) {
        fs.createCookie(name,"",-1);
    }
    ,
    getWindowsVersion: function() {
        var userAgent = navigator.userAgent;
        var windowsVersion = "UNKNOWN";
        if (userAgent.indexOf("Windows NT 5.0") > -1) {
            windowsVersion = "2K";
        } else if (userAgent.indexOf("Windows NT 5.1") > -1) {
            windowsVersion = "XP";
        } else if (userAgent.indexOf("Windows NT 6.0") > -1) {
            windowsVersion = "VISTA";
        }
        return windowsVersion;
    }
    ,
    getBrowserVersion: function() {
        var userAgent = navigator.userAgent;
        var browserVersion = "UNKNOWN";
        if (userAgent.indexOf("Firefox/3")) {
            browserVersion = '3';
        } else if (userAgent.indexOf("Firefox/2")) {
            browserVersion = '2';
        } else if (userAgent.indexOf("Firefox/1")) {
            browserVersion = '1';
        } else if (userAgent.indexOf("MSIE 6.0")) {
            browserVersion = '6';
        } else if (userAgent.indexOf("MSIE 7.0b")) {
            browserVersion = '7b';
        } else if (userAgent.indexOf("MSIE 7.0")) {
            browserVersion = '7';
        } else if (userAgent.indexOf("MSIE 8.0")) {
            browserVersion = '8';
        }

        return browserVersion;
    }
    ,
    isFirefox: function() {
        if (navigator.userAgent.indexOf('Firefox') > 0) {
            return true;
        } else {
            return false;
        };
    }
    ,
    isIE: function() {
        if (navigator.userAgent.indexOf('MSIE') > 0) {
            return true;
        } else {
            return false;
        };
    }
    ,
    getRequestByIframe: function(sName, sUrl) {
        var oRef ={'iframeText':null, 'onready':null, 'body':null};
        var sContent = '';
        if (document.getElementById(sName) === null) {
            var eIframe = document.createElement('IFRAME');
            eIframe.src = sUrl;
            eIframe.id = sName;
            eIframe.style.width = '0px';
            eIframe.style.height = '0px';
            eIframe.style.display = 'none';
            document.getElementsByTagName('body')[0].appendChild(eIframe);

            /* After script loads, assign value */
            if ( typeof eIframe.onreadystatechange != 'undefined') {
                eIframe.onreadystatechange = function(){
                    if ( eIframe.readyState == 'complete') {
                        oRef.iframeText = fs.getIframeDocument(sName).body.firstChild.firstChild !== null ? fs.getIframeDocument(sName).body.firstChild.firstChild.nodeValue : null;
                        oRef.body = fs.getIframeDocument(sName).body;
                        //eIframe.parentNode.removeChild(eIframe);
                        oRef.onready();
                    }
                };
                return oRef;
            } else if ( typeof eIframe.contentWindow != 'undefined') {
                eIframe.contentWindow.onload = function(){
                    oRef.iframeText = fs.getIframeDocument(sName).body.firstChild.firstChild !== null ? fs.getIframeDocument(sName).body.firstChild.firstChild.nodeValue : null;
                    oRef.body = fs.getIframeDocument(sName).body;
                    //eIframe.parentNode.removeChild(eIframe);
                    oRef.onready();
                };
                return oRef;
            }
        } else {
        }
    }
    ,
    getIframeDocument: function(osFrame) {
        var oFrame = null;
        if (typeof(osFrame) == 'object') {
            oFrame = osFrame;
        } else if (typeof(osFrame) == 'string') {
            oFrame = document.getElementById(osFrame);
        }
        var oDoc = oFrame.contentDocument;
        if (oDoc == undefined || oDoc == null) {
            oDoc = oFrame.contentWindow.document;
        }
        return oDoc;
    }
}

/* addEvent function assignation */
if (document.addEventListener) {
    fs.addEvent = function(element, type, handler) {
        element.addEventListener(type, handler, false);
    };
} else if (document.attachEvent) {
    fs.addEvent = function(element, type, handler) {
        element.attachEvent('on' + type, handler);
    };
} else {
    fs.addEvent = new Function;
}

/* removeEvent function assignation */
if (document.removeEventListener) {
    fs.removeEvent = function(element, type, handler) {
        element.removeEventListener(type, handler, false);
    };
} else if (document.detachEvent) {
    fs.removeEvent = function(element, type, handler) {
        element.detachEvent('on' + type, handler);
    };
} else {
    fs.removeEvent = new Function;
}
