/**
 * Usage: some API to help coded
 */

var SYSHelp = {
    /* prototype继承 */
    extendClass: function(subClass, superClass){
        function F(){};
        F.prototype = superClass.prototype;
        subClass.prototype = new F();
        subClass.prototype.constructor = subClass;
    },
	/* 合并对象属性 */
	mergeObject: function(fromObject, toObject, isCover/* 是否覆盖 */){
		isCover = typeof isCover == 'boolean' ? isCover : true;
		for(var k in fromObject){
			if(isCover || typeof toObject[k] == 'undefined'){
				toObject[k] = fromObject[k];
			}
		}
	},
    /* 将nodeList转化为数组 */
    convertToArray: function(nodeList){
        var array = null;
        try{
            array = Array.prototype.slice.call(nodeList, 0);
        }catch (e){
            array = [];
            for(var i=0,len=nodeList.length;i<len;i++){
                array.push(nodeList[i]);
            };
        };
        return array;
    },
    /* 函数绑定 */
    bind: function(method, context){
        var args = Array.prototype.slice.call(arguments, 2);
        return function(){
            var innerArgs = Array.prototype.slice.call(arguments),
                finalArgs = args.concat(innerArgs);
            method.apply(context, finalArgs);
        };
    },
    /* 将大数据格式化为数组，方便数组分块 */
    formatChunkToData: function(data, oneGroupNum, method, context, finisher){
        var array = [];
        if(!(data instanceof Array)){
            data = this.convertToArray(data);
        };

        while(data.length > 0){
            array.push(data.splice(0, oneGroupNum));
        };
        this.chunk(array, method, context, this.bind(finisher, context));
    },
    /* 无序数组分块 */
    chunk: function(array, method, context, finisher){
        (function(){
            var item = array.shift();
            method.call(context, item);
            if(array.length > 0){
                setTimeout(arguments.callee, 100);
            }else{
                (typeof finisher == 'function') && finisher();
            };
        })();
    },
    /* 判断是否为字符串 */
    isString: function(x) {
        return Object.prototype.toString.call(x) === "[object String]";
    },
    /* 判断是否为空白 */
    isWhitespace: function(x) {
    if (false === this.isString(x)) x = x.toString();
        var regex = /^\s*$/;
        return regex.test(x);
    },
    /* 去掉字符串两边空白 */
    trim: function(x) {
        if (false === this.isString(x)) x = x.toString();
        if (String.prototype.trim) return x.trim();
        var trimLeft, trimRight;
        if (this.isWhitespace("\xA0")) {
            trimLeft = /^\s+/;
            trimRight = /\s+$/;
        } else {
            // IE doesn't match non-breaking spaces with \s, thanks jQuery.
            trimLeft = /^[\s\xA0]+/;
            trimRight = /[\s\xA0]+$/;
        }
        return x.replace(trimLeft, "").replace(trimRight, "");
    },
    /* 获取class正则表达式字符串 */
    getRegOfClassStr: function(className, className2){
        var regStr;
        if (this.isWhitespace("\xA0")) {
            regStr = '\\s+' + className + '|' + className + '\\s+';
            if(className2){
                regStr += '|\\s+' + className2 + '|' + className2 + '\\s+';
            };
        }else{
            regStr = '[\\s\\xA0]+' + className + '|' + className + '[\\s\\xA0]+';
            if(className2){
                regStr += '|[\\s\\xA0]+' + className2 + '|' + className2 + '[\\s\\xA0]+';
            };
        };
        return new RegExp(regStr, 'ig');
    },
    /* 添加class */
    addClass: function(node, className){
        var theClass, reg;
        if(!node) return;
        if(node.length > 0){ /* node为数组或NodeList */
            for(var i= 0,len=node.length;i<len;i++){
                node[i].className += ' ' + className;
            };
        }else{
            if(node.length === 0) return;
            theClass = this.trim(node.className),
            className = this.trim(className);

            if(theClass !== className){
                reg = this.getRegOfClassStr(className);
                if(!reg.test(theClass)){
                    node.className = theClass + ' ' + className;
                };
            };
        };
    },
    /* 移除class */
    removeClass: function(node, className, className2){
        var reg, theClass;
        className = this.trim(className);

        if(!node) return;

        if(className2){
            className2 = this.trim(className2);
            reg = this.getRegOfClassStr(className, className2);
        }else{
            reg = this.getRegOfClassStr(className);
        };

        if(node.length > 0){ /* node为数组或NodeList */
            for(var i= 0,len=node.length;i<len;i++){
                theClass = this.trim(node[i].className);
                if(theClass === className || theClass === className2){
                    node[i].className = '';
                }else{
                    node[i].className = theClass.replace(reg, '');
                };
            };
        }else{
            if(node.length === 0) return;
            theClass = this.trim(node.className),
            className = this.trim(className);
            if(className2){
                className2 = this.trim(className2);
            }

            if(theClass === className || theClass === className2){
                node.className = '';
            }else{
                node.className = theClass.replace(reg, '');
            };
        };
    },
    /* 判断是否存在某class */
    hasClass: function(node, className){
        var reg, theClass;
        theClass = this.trim(node.className);
        if(theClass === className){
            return true;
        };

        reg = this.getRegOfClassStr(className);
        return reg.test(theClass);
    },
    /* 用toggle的方式设置class */
    toggleClass: function(node, className){
        this.hasClass(node, className) ? this.removeClass(node, className) : this.addClass(node, className);
    },
    /* 获取某一class的元素 */
    getElementsByClassName: function(node, className){
        if(arguments.length == 1){
            node = document;
        };

        if(node.getElementsByClassName){
            return node.getElementsByClassName(className);
        }else{
            var nodeList = [], nodeListTmp, i, len,
                reg = this.getRegOfClassStr(className);

            nodeListTmp = node.getElementsByTagName('*');
            for(i=0,len=nodeListTmp.length;i<len;i++){
                if(className === nodeListTmp[i].className || reg.test(nodeListTmp[i].className)){
                    nodeList.push(nodeListTmp[i]);
                };
            };

            return nodeList;
        };
    },
    /* 添加DOM监听器 */
    addEventListener: function(node, type, listener, context){

        if(context){
            listener = this.bind(listener, context);
        };

        if(node.addEventListener){
            node.addEventListener(type, listener, false);
        }else if(node.attachEvent){
            node.attachEvent('on'+type, listener);
        }else{
            node['on'+type] = listener;
        };
    },
    /* 移除DOM监听器 */
    removeEventListener: function(node, type, listener){
        if(node.removeEventListener){
            node.removeEventListener(type, listener);
        }else if(node.dispatchEvent){
            node.dispatchEvent('on'+type, listener);
        }else{
            node['on'+type] = null;
        };
    },
    /* 获取事件对象 */
    getEvent: function(e){
        return e || event;
    },
    /* 获取事件发生对象 */
    getTarget: function(e){
        return e.target || e.srcElement;
    },
    isEmptyObject: function(obj){
        if(Object.prototype.toString.apply(obj)!=='[object Object]') return false;
        for(var property in obj){
            if(obj.hasOwnProperty(property)) return false;
        };
        return true;
    },
    createXHR: function(){
        if(typeof XMLHttpRequest != 'undefined'){
            return function(){
                return new XMLHttpRequest();
            };
        }else if(typeof ActiveXObject != 'undefined'){
            return function(){
                if(typeof arguments.callee.activeXString != 'string'){
                    var xhrVersions = ['MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'],
                        i, len;
                    for(i=0,len=xhrVersions.length;i<len;i++){
                        try{
                            new ActiveXObject(xhrVersions[i]);
                            arguments.callee.activeXString = xhrVersions[i];
                            break;
                        }catch(e){};
                    };
                };
                return new ActiveXObject(arguments.callee.activeXString);
            };
        }else{
            return function(){
                alert('您的浏览器不支持XMLHTTP');
            };
        };
    }(),
    formatUrlParam: function(data){
        var key,
            datas = [];
        for(key in data){
            datas.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
        };
        return datas.join('&');
    },
    ajax: function(options){
        var xhr = options.xhr || this.createXHR(),
            key, data = null,
            url = options.url,
            method = options.method.toLocaleLowerCase(),
            async = typeof options.async == 'boolean' ? options.async : true;

        if(options.data){
            data = this.formatUrlParam(options.data);
            if(method == 'get'){
                url += (url.indexOf('?') == -1 ? '?' : '&') + data;
            };
        };

        if(options.nocache){
            //xhr.setRequestHeader('Expires', 'Thu, 25 Apr 1997 15:04:44 GMT');
            url += (url.indexOf('?') == -1 ? '?' : '&') + 'current_time=' + new Date().getTime();
        };

        xhr.open(method, url, async);

        if(options.headers){
            for(key in options.headers){
                xhr.setRequestHeader(key, options.headers[key]);
            };
        };

        if(method == 'post'){
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        };

        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
                typeof options.callback == 'function' && options.callback(xhr.responseText, xhr.status);
                /*
                if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                    options.callback(xhr.responseText, xhr.status);
                }else{
                    alert('ajax请求失败，错误码：' + xhr.status);
                };
                */
            };
        };
        xhr.send(data);
    },
    /* 元素是否在数组内 */
    inArray: function(item, array){
        var i,len;
        if(Array.prototype.indexOf){
            return array.indexOf(item) > -1 ? true : false;
        }else{
            for(i=0,len=array.length;i<len;i++){
                if(item === array[i]){
                    return true;
                };
            };
            return false;
        };
    },
    /* 元素在数组或NodeList中的索引 */
    getIndex: function(item, array){
        var i,len;
        for(i=0,len=array.length;i<len;i++){
            if(item === array[i]){
                return i;
            };
        };
    },
    /* 获取键盘事件的charCode */
    getCharCode: function(event){
         return (typeof event.keyCode == 'number' ? event.keyCode : event.charCode);
    },
    /* 组织默认动作 */
    preventDefault: function(event){
        event.preventDefault ? event.preventDefault() : event.returnValue = false;
    },
    /* 获取元素的相对窗口的位置 */
    getOffest: function(node){
        var offsetLeft = node.offsetLeft,
            offsetTop = node.offsetTop,
            current = node.offsetParent;
        while (current !== null){
            offsetLeft += current.offsetLeft,
                offsetTop += current.offsetTop,
                current = current.offsetParent;
        }
        return {offsetLeft: offsetLeft, offsetTop: offsetTop};
    },
    /* 获取鼠标事件发生时，鼠标的坐标位置 */
    getPageXY: function(event){
        var pageX = event.pageX,
            pageY = event.pageY;

        if(pageX === undefined){
            pageX = event.clientX + (document.body.scrollLeft ||
                document.documentElement.scrollLeft),
                pageY = event.clientY + (document.body.scrollHeight ||
                    document.documentElement.scrollHeight);
        };
        return {pageX: pageX, pageY: pageY};
    },
    /* 单向get通信 */
    imgPing: function(url, data){
        var img = new Image();

        data = this.formatUrlParam(data);
        url += (url.indexOf('?') != -1 ? '&' : '?') + data;
        img.src = url;
    }
};