/**
 * 自定义List对象，模仿java中的ArrayList
 */
var YList = function() {
    (function(yl) {
        var array = new Array();
        // 0：表示最新状态， 非0 表示有更改状态
        yl.status = 0;
        // 添加一项
        yl.add = function(obj) {
            if (obj != undefined) {
                array.push(obj);
                yl.status++;
            } else {
                throw new Error('无效参数');
            }
            return yl;
        };
        // 刷新List,去除undefined和null
        yl.fush = function() {
            var len = array.length;
            var temp = null;
            for ( var i = 0; i < len; i++) {
                for ( var j = i + 1; j < len; j++) {
                    if (array[i] == undefined || array[i] == null) {
                        temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
                ;
            }
            ;
            for ( var i = 0; i < len; i++) {
                if (array[i] == undefined || array[i] == null) {
                    array.length = i;
                    break;
                }
            }
            yl.status = 0;
            return yl;
        };
        // 获取总数量
        yl.size = function() {
            if (yl.status > 0) {
                yl.fush();
                yl.status = 0;
            }
            return array.length;
        };
        // 获取某一项值
        yl.get = function(index) {
            if (typeof (index) != 'number') {
                throw new Error('无效参数');
            } else if (index < 0 || index >= array.length) {
                throw new Error('索引值超出范围');
            } else {
                return array[index];
            }
        };
        // 移出某一项
        yl.remove = function(index) {
            if (typeof (index) != 'number') {
                throw new Error('无效参数');
            } else if (index < 0 || index >= array.length) {
                throw new Error('索引值超出范围');
            } else {
                array[index] = undefined;
                yl.status++;
            }
            return yl;
        };
        // 清空List
        yl.clear = function() {
            array.length = 0;
            yl.status = 0;
            return yl;
        };
    })(this);
}

/**
 * 自定义Map对象，模仿java中的 HashMap
 */
var YMap = function() {
    (function(ym) {
        var map = function(k, v) {
            this.key = k;
            this.value = v;
        };

        ym.list = new YList();
        // 获取总数量
        ym.size = function() {
            return ym.list.size();
        };
        // 往容器中填充对象
        ym.put = function(k, v) {
            if (k != undefined && k != null) {
                var mp = new map(k, v);
                ym.list.add(mp);
            } else {
                throw new Error('无效参数');
            }
            return ym;
        };

        // 移出某项
        ym.remove = function(k) {
            if (k != undefined && k != null) {
                for ( var i = 0; i < ym.list.size(); i++) {
                    var mp = ym.list.get(i);
                    if (mp != null && mp.key == k) {
                        ym.list.remove(i);
                        ym.list.fush();
                    }
                }
            } else {
                throw new Error('无效参数');
            }
            return ym;
        };

        // 根据key值获取对象
        ym.get = function(k) {
            var result = null;
            if (k != undefined && k != null) {
                for ( var i = 0; i < ym.size(); i++) {
                    var mp = ym.list.get(i);
                    if (mp != null && mp.key == k) {
                        result = mp.value;
                        break;
                    }
                }
            } else {
                throw new Error('无效参数');
            }
            return result;
        };
        // 移出所有项
        ym.removeAll = function() {
            ym.list.clear();
            return ym;
        };
        // 判断是否存在K项
        ym.contant = function(k) {
            var result = false;
            if (k != undefined && k != null) {
                for ( var i = 0; i < ym.size(); i++) {
                    var mp = ym.list.get(i);
                    if (mp != null && mp.key == k) {
                        result = true;
                        break;
                    }
                }
            } else {
                throw new Error('无效参数');
            }
            return result;
        };
        // 获取到所有Key集合
        ym.keySet = function() {
            var arry = new Array();
            for ( var i = 0; i < ym.size(); i++) {
                var mp = ym.list.get(i);
                if (mp != undefined && mp != null) {
                    arry.push(mp.key);
                }
            }
            return arry;
        };
        // 获取到所有value集合
        ym.valueSet = function() {
            var arry = new Array();
            for ( var i = 0; i < ym.size(); i++) {
                var mp = ym.list.get(i);
                if (mp != undefined && mp != null) {
                    arry.push(mp.value);
                }
            }
            return arry;
        };
    })(this);
};
var utils = {
			
    is: function(value, type){
        return Object.prototype.toString.call(value) === "[object " + type + "]";
    },
    
    format: function(){
        var res = arguments[0],
            l = arguments.length;
        if(res && l > 1){
            for(var i = 1; i < l; i++){
                res = res.replace('{' + (i - 1) + '}', arguments[i]);
            }
        }
        return res;
    },
    
    formatByJson: function(str, json){
        if(this.is(json, 'Object')){
            for(var key in json){
                str = str.replace(new RegExp("\{" + key + "\}", "g"), json[key]);
            }
        }
        return str;
    },

    formatDate : function(dateTime, fmt){
    	if(!dateTime) {
            return dateTime;
        }
    	
        fmt = fmt || "yyyy-MM-dd hh:mm:ss";

        if(utils.is(dateTime, "String")) {
            dateTime = this.parseDate(dateTime);
        }
        
        if(/^[0-9]+$/i.test(dateTime)){
        	dateTime = new Date(dateTime);
    	}

        if(!utils.is(dateTime, "Date")) {
            return dateTime;
        }

        var o = {
            "M+" : dateTime.getMonth() + 1,
            "d+" : dateTime.getDate(),
            "h+" : dateTime.getHours(),
            "m+" : dateTime.getMinutes(),
            "s+" : dateTime.getSeconds(),
            "q+" : Math.floor((dateTime.getMonth()+3)/3), 
            "S"  : dateTime.getMilliseconds() 
        };

        if(/(y+)/.test(fmt)) {
            fmt=fmt.replace(RegExp.$1, (dateTime.getFullYear()+"").substr(4 - RegExp.$1.length));
        }

        for(var k in o) {
            if(new RegExp("("+ k +")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
            }
        }

        return fmt;
    },
    
    formatDateNum : function(datenum, fmt){
    	if(datenum && datenum.length >= 14){
    		var year = datenum.substr(0, 4),
    			month = datenum.substr(4, 2),
    			date = datenum.substr(6, 2),
    			hour = datenum.substr(8, 2),
    			minute = datenum.substr(10, 2),
    			second = datenum.substr(12, 2);
    		datenum = this.format("{0}-{1}-{2} {3}:{4}:{5}", year, month, date, hour, minute, second);
    	}
    	return this.formatDate(datenum, fmt);
    },

    parseDate: function(text){
    	if(/[0-9]+T[0-9]+/g.test(text)){
    		var d = new Date(text);
    		if(_.isNaN(d.getFullYear())){
    	        var rx = /^(\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2})/g;
    	        var p = rx.exec(text) || [];
    	        if(p[1]){
    	        	var index = p[1].indexOf('.');
    	        	if(index != -1){
    	        		p[1] = p[1].substring(0, index);
    	        	}
    	        	var days = p[1].replace('T', ' ').replace(/\-/g, ' ').replace(/:/g, ' ');
    	        	days = days.split(' ');
    	        	//                             年                                                                月                                           日                         
    	        	d = new Date(Date.UTC(parseInt(days[0]), parseInt(days[1]) - 1, parseInt(days[2])
    	        			//           时                                                          分                                                              秒
    	        			, parseInt(days[3]), parseInt(days[4]), parseInt(days[5])));  	
    	        }
    	        return d;
    	    }
    		return d;
    	} else if(/ CST [0-9]+/g.test(text)){
    		var d = new Date(text);
	        var rx = {
	        	"Jan": "01", "Feb": "02", "Mar": "03", "Apr": "04", "May": "05", "Jun": "06",
	        	"Jul": "07", "Aug": "08", "Sep": "09", "Oct": "10", "Nov": "11", "Dec": "12"
	        };
	        var p = text.split(' ') || [];
	        if(p[1]){
	        	var h = p[3].split(":");
	        	d = new Date(parseInt(p[5]), parseInt(rx[p[1]]) - 1, parseInt(p[2])
        			//           时                                                          分                                                              秒
        			, parseInt(h[0]), parseInt(h[1]), parseInt(h[2])); 
	        }
	        return d;
    	}
    	if(/^[0-9]+$/i.test(text)){
    		return new Date(text);
    	}
        var dt = text.split(" "),
            hh = 0,mm = 0,ss = 0,
            matchD,year,month,dd,hmsStr,hms,ymdStr = dt[0];
        if(dt.length == 2) {
            hmsStr = dt[1];
        }

        if(matchD = ymdStr.match(/^(\d{4})\D(\d{1,2})\D(\d{1,2})$/)){
            year = matchD[1];
            month = matchD[2];
            dd = matchD[3];
        }else{
            if(ymdStr.length === 8){
                year = ymdStr.substring(0,4);
                month = ymdStr.substring(4,6);
                dd = ymdStr.substring(6,8);
            }
        }
        if(hmsStr){
            hms = hmsStr.match(/^(\d{2})\D(\d{2})\D(\d{2})$/);
            hh = hms[1];
            mm = hms[2];
            ss = hms[3];
        }
        return new Date(year,month-1,dd,hh,mm,ss);
    },

    /**
     * 创建UUID
     * @param Number l 长度
     * @param Number r
     */
    UUID: function(l, r) {
        var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
                .split('');
        var createUUID = function(len, radix) {
            var chars = CHARS, uuid = [], i;
            radix = radix || chars.length;
            if (len) {
                // Compact form
                for (i = 0; i < len; i++)
                    uuid[i] = chars[0 | Math.random() * radix];
            } else {
                // rfc4122, version 4 form
                var r;
                // rfc4122 requires these characters
                uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
                uuid[14] = '4';
                // Fill in random data. At i==19 set the high bits of clock sequence
                // as
                // per rfc4122, sec. 4.1.5
                for (i = 0; i < 36; i++) {
                    if (!uuid[i]) {
                        r = 0 | Math.random() * 16;
                        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                    }
                }
            }
            return uuid.join('');
        };
        return createUUID(l, r);
    },
    
    /**
     * 获取参数值，若没有则给定默认值
     * @param {JSON} ops
     * @param {String} field
     * @param {Object} val
     * @param {String} type 类型：Object、Function、String、Number、Date、Array、Boolean、Window
     */
    getOptionValue: function(ops, field, val, type) {
        ops = ops == undefined || ops == null ? {} : ops;
        if (type) {
            if (ops[field] != undefined && Object.prototype.toString.call(ops[field]) !== ('[object ' + type + ']')) {
                throw new Error('无效参数');
            } else {
                val = ops[field] == undefined ? val : ops[field];
            }
        } else {
            val = ops[field] == undefined ? val : ops[field];
        }
        return val;
    },

    stopEvent: function(e){
        try{
            if(e){
                e.stopPropagation();
                e.preventDefault();
            }
        }catch(ex){}				
    },

    screenWidth: function(){
        return window.desktop.width();
    },
    screenHeight: function(){
        return window.desktop.height();
    },
    unicode4ToAnsi: function(data){
		if(!data) return data;
		var arr = data.match(/&#[0-9]+;/g);
		var str = "";
		for(var i = 0; i < arr.length; i++){
			if(!arr[i]) {continue;}
			var value = arr[i];
			value = value.replace("&#", "");
			value = value.replace(";", "");
			str = String.fromCharCode(value.toString(10));
			data = data.replace(arr[i], str)
		}
		return data;
	}
	,ansiToUnicode4: function(data){
		if(!data) return data;
		var arr = data.split("");
		var str = "";
		for(var i = 0; i < arr.length; i++){			
			str += "&#" + arr[i].charCodeAt(0) + ";";
		}
		return str;
	}
	,paramsToUnicode4: function(p, arr){
		for(var i = 0; i < arr.length; i++){
			if(p[arr[i]]){
				p[arr[i]] = this.ansiToUnicode4(p[arr[i]]);
			}
		}
		return p;
	}
	,paramsToAnsi: function(p, arr){
		for(var i = 0; i < arr.length; i++){
			if(p[arr[i]]){
				p[arr[i]] = this.unicode4ToAnsi(p[arr[i]]);
			}
		}
		return p;
	}
};

var methodIndex = 0;
function CallServer (cmd, param){
    var id = ++methodIndex;
    var mname = "__method_" + id;
    window[mname] = null;
    _call_server("synccall", JSON.stringify({
        "id": ""+id,
        "cmd": cmd,
        "param": param
    }));
    return new Promise ((resolve,reject) => {
       var inter = setInterval(() => {
            if(!!window[mname]){
                var res = window[mname];
                delete window[mname];
                window[mname] = null;
                clearInterval(inter);
                resolve(res);
                return;
            }
        }, 10);
   })
 }