(function($, BMap, window) {
	var sensorNames = {
		"e1": ["PM2.5", "ug/m3"],
		"e2": ["PM10", "ug/m3"],
		"e3": ["颗粒物0.3", "PCS/0.1L"],
		"e4": ["颗粒物2.5", "PCS/0.1L"],
		"e5": ["甲醛", "mg/m3"],
		"e6": ["湿度", "%"],
		"e7": ["温度", "℃"],
		"e8": ["氧气", "%"],
		"e9": ["氯气", "mg/m3"],
		"e10": ["一氧化碳", "mg/m3"],
		"e11": ["二氧化硫", "ug/m3"],
		"e12": ["光照", "Lux"],
		"e13": ["噪音", "dB"],
		"e14": ["氨气", "mg/m3"],
		"e15": ["臭氧", "ug/m3"],
		"e16": ["二氧化氮", "ug/m3"],
		"e17": ["挥发有机气体", "PPB"],
		"e18": ["风速", "m/s"],
		"e19": ["二氧化碳", "mg/m3"]
	}
	var showSensorKeys=["e1","e2","e10","e11","e15","e16"];
	var moralMap = {};
	var baiduMap = null;
	/*
	 * 根据mac地址获取version
	 */
	// moralMap.getVersion = function(mac){
	// 	var version = null;
	// 	$.ajax({
	// 		type:"get",
	// 		url:"getversion?mac="+mac,
	// 		async:false,
	// 		success:function(jsonData){
	// 			if(jsonData!=null&&typeof jsonData=='object'){
	// 				version = jsonData['version'];
	// 			}
	// 		}
	// 	});
	// 	return version;
	// }
	/*
	 * 百度地图初始化
	 */
	moralMap.mapInit = function() {
	    var defaultParam = {
            minZoom: 12,
            maxZoom: 20
        };
	    if(!!arguments[1]) {
         $.extend(defaultParam,arguments[1]);
        }
		baiduMap = new BMap.Map("mapCanvas",defaultParam); // 创建Map实例,设置地图允许的最小/大级别
		var map = baiduMap;
		var mapStyle = {
			features: ["road", "building", "water", "land"], //隐藏地图上的poi
			style: "normal" //设置地图风格为高端黑 
		}
		map.setMapStyle(mapStyle);
        var showZoom = !!arguments[2]
        && arguments[2] <=defaultParam.maxZoom
        && arguments[2] >= defaultParam.minZoom?arguments[2]:12;
        var address = arguments[0];
        var regoinNames = address.split(" ");
        var cityName = regoinNames.length>1?regoinNames[1]:regoinNames[0];
        map.setCurrentCity(cityName);
            // 将地址解析结果显示在地图上,并调整地图视野
            // 创建地址解析器实例
            var myGeo = new BMap.Geocoder();
            myGeo.getPoint(address, function(point){
                if (point) {
                    map.centerAndZoom(point, showZoom);
                }else{
                    alert("您选择地址没有解析到结果!");
                }
            }, cityName);
		//增加导航控件
		map.enableScrollWheelZoom(true);
		var navigation = new BMap.NavigationControl({
			anchor: BMAP_ANCHOR_BOTTOM_RIGHT,
			type: BMAP_NAVIGATION_CONTROL_LARGE
		});
		map.addControl(navigation);
	}
	moralMap.closeSearchBox = function() {
		moralMap["_searchBoxKey"] = Math.random();
		$(".search_box").css("display", "none");
	}
	//延时开启
	moralMap.openSearchBox = function() {
		key = Math.random();
		moralMap["_searchBoxKey"] = key;
		setTimeout(function() {
			if(moralMap["_searchBoxKey"] == key) {
				$(".search_box").css("display", "block");
			}
		}, 1500);
	}
	/*
	 * ----------------适配方法------------------------
	 */
	moralMap.addEventListener = function(type, fn) {
		baiduMap.addEventListener(type, function() {
			if(type == "zoomstart") {
				moralMap._zoomStartHandle();
			} else if(type == "zoomend") {
				moralMap._zoomEndHandle();
			}
			fn.apply(baiduMap, arguments);
		});
	}
	moralMap._zoomStartHandle = function() {
		baiduMap.closeInfoWindow();
		moralMap.startZoom(baiduMap.getZoom());
	}
	moralMap._zoomEndHandle = function() {
		if($(".search_box").css("display") == "none") {
			moralMap.openSearchBox();
		}
		var endZoom = baiduMap.getZoom();
		var startZoom = moralMap.startZoom();
		//刷新key防止延迟加载
		//	   var key = moralMap.lazyKeyer();
		var confine = moralMap.getZoomConfine();
		if(endZoom > startZoom) {
			//放大超过边界
			if(endZoom >= confine && startZoom <= confine) {
				//清空控件
				moralMap.layer("equipments");
				moralMap.clearOverlays();
			}
		} else {
			//缩小超过边界
			if(endZoom != startZoom && startZoom >= confine && endZoom < confine) {
				//清空控件
				moralMap.layer("monitorpoints");
				moralMap.clearOverlays();
			}
		}
	}
	moralMap.layer = (function() {
		var _layers = ["equipments", "monitorpoints"];
		var _layer = "monitorpoints";
		return function(layer) {
			if(layer == undefined) {
				return _layer;
			} else {
				for(var i in _layers) {
					if(layer == _layers[i]) {
						_layer = layer;
					}
				}
			}
		}
	})();
    // 坐标适配器
    moralMap.Bounds = function (baiduBounds) {
    	if(!!baiduBounds){
            this.northeastLng = baiduBounds.xl.lng;//东北角经度,大一点
            this.northeastLat = baiduBounds.xl.lat;//东北角纬度,大一点
            this.southwestLng = baiduBounds.Ol.lng;//西南角经度坐标,小一点
            this.southwestLat = baiduBounds.Ol.lat;//西南角经度坐标,小一点
		}else{
            this.northeastLng = null;//东北角经度,大一点
            this.northeastLat = null;//东北角纬度,大一点
            this.southwestLng = null;//西南角经度坐标,小一点
            this.southwestLat = null;//西南角经度坐标,小一点
		}
    }
	moralMap.getBounds = function() {
		return new moralMap.Bounds(baiduMap.getBounds()); //即时bounds;
	}
	moralMap.getMaxBounds = function() {
		var key = "_" + moralMap.layer() + "_bounds";
		return this[key];
	}
	moralMap.setMaxBounds = function(bs) {
		var key = "_" + moralMap.layer() + "_bounds";
		var _bounds = !!this[key]?this[key]:new moralMap.Bounds(); //累积数据
		//记录最大边界
		_bounds.northeastLng = _bounds.northeastLng || bs.northeastLng;
		_bounds.northeastLat = _bounds.northeastLat || bs.northeastLat;
		_bounds.southwestLng = _bounds.southwestLng || bs.southwestLng;
		_bounds.southwestLat = _bounds.southwestLat || bs.southwestLat;
		_bounds.northeastLng = bs.northeastLng > _bounds.northeastLng ? bs.northeastLng: _bounds.northeastLng;
		_bounds.northeastLat = bs.northeastLat > _bounds.northeastLat ? bs.northeastLat: _bounds.northeastLat;
		_bounds.southwestLng = bs.southwestLng < _bounds.southwestLng ? bs.southwestLng: _bounds.southwestLng;
		_bounds.southwestLat = bs.southwestLat < _bounds.southwestLat ? bs.southwestLat: _bounds.southwestLat;
		this[key] = _bounds;
	}
	moralMap.isOverBounds = function() {
		var isOver = false;
		var _bounds = moralMap.getMaxBounds(); //累计数据
		var bs = moralMap.getBounds(); //实际数据
		if(!_bounds) {
			isOver = true;
			moralMap.setMaxBounds(bs);
		} else {
			    isOver = (bs.northeastLng > _bounds.northeastLng
						|| bs.northeastLat > _bounds.northeastLat
						|| bs.southwestLng < _bounds.southwestLng
						|| bs.southwestLat < _bounds.southwestLat);
			  if(isOver){
                  moralMap.setMaxBounds(bs);
			  }
		}
		return isOver;
	}
	moralMap.addOverlay = function(overlay) {
		if(overlay.getMap() != baiduMap) {
			// setTimeout(function(){
				baiduMap.addOverlay.call(baiduMap, overlay);
			// },10);
            baiduMap.addOverlay.call(baiduMap, overlay);
		}
	}
	moralMap.addOverlays = function(overlays) {
		if(overlays != null && typeof overlays == 'object') {
			for(var i in overlays) {
				moralMap.addOverlay(overlays[i]);
			}
		}
	}
	moralMap.removeOverlay = function(overlay) {
        // baiduMap.removeOverlay(overlay);
		baiduMap.removeOverlay.apply(baiduMap, arguments);
	}
	moralMap.removeOverlays = function(overlays) {
        if(overlays != null && typeof overlays == 'object') {
            for (var i in overlays) {
                moralMap.removeOverlay(overlays[i]);
            }
        }
	}
	moralMap.getOverlays = function() {
		var overLays = baiduMap.getOverlays.apply(baiduMap, arguments)
		var moralMarker = [];
		for(var i in overLays) {
			if(overLays[i] instanceof BMap.Overlay) {
				moralMarker.push(overLays[i]);
			}
		}
		return moralMarker;
	}
	moralMap.clearCloseInfoWindow = function () {
        if(!!moralMap["_closeInfoWinTimer"]){
            clearTimeout(moralMap["_closeInfoWinTimer"]);
            moralMap["_closeInfoWinTimer"] = null;
        }
    }
	moralMap.openInfoWindow = function() {
        moralMap.clearCloseInfoWindow();
        baiduMap.openInfoWindow.apply(baiduMap, arguments);; //开启信息窗口
	}
	moralMap.closeInfoWindow = function() {
        var timer = setTimeout(function () {
            baiduMap.closeInfoWindow.apply(baiduMap, arguments);
            moralMap["_closeInfoWinTimer"] = null;
        },1200);
        moralMap["_closeInfoWinTimer"] = timer;
	}
	moralMap.clearOverlays = function() {
		baiduMap.clearOverlays();
	}
	moralMap.startZoom = (
		function() {
			var _zoom = null;
			return function(z) {
				if(z == undefined) {
					return _zoom;
				} else {
					_zoom = z;
				}
			}
		}
	)();
	moralMap.lazyKeyer = (function() {
		var _key = null;
		return function(key) {
			if(key == undefined) {
				_key = Math.random();
				return _key;
			} else {
				return _key == key;
			}
		};
	})();
	moralMap.getUtf8Length = function(str) {
		return str.replace(/[\u0391-\uFFE5]/g, "cc").length;
	}
	//弹窗处理
	moralMap.showPopupbox = function(id) {
		setTimeout(function () {
            $(id).css('display', 'block');
        },1);
	}
	moralMap.closePopupbox = function(id) {
		   $(id).css('display', 'none');
	}
	moralMap.isPopupBoxShow = function(id) {
		return $(id).css('display') == 'block';
	}
	moralMap.onItermClick = function(index,select) {
		var row = moralMap.getPopupEqu(index);
        if(row['mac']==null){
            alert("mac项未配置,请联系管理员设置");
            return;
        }
		var equ = {
            methodName : 'chart'== select ?'showChart':'showDeviceMonitor',
			name: row['name'],
			mac: (row['mac']).toLowerCase(),
			longitude: row['longitude'],
			latitude: row['latitude'],
            monitorPointId: row['monitorPointId'],
            version:row['deviceVersion']['version']
		};
		!!select?equ['monitorPointId'] = row["monitorPointId"]:null;
		var equStr = JSON.stringify(equ);
        if(window["console"]!=undefined){
            console.log(equStr);
        }
        if(!!window['external']&&!!window['external']['callWin']){
            window['external'].callWin(equStr);
        }else{
			    if(!!select&&select==='chart'&&!!window['external']&&!!window['external']['showChartInfo']){
                    window['external'].showChartInfo(equStr);
                }else if(!!window['external']&&!!window['external']['showMonitorInfo']){
                    window['external'].showMonitorInfo(equStr);
                }else{
                    alert(equStr);
                }
		}
	}
	moralMap.setPopupEqus = function(arr) {
		moralMap["_equs"] = arr;
	}
	moralMap.getPopupEquMacs = function() {
		var macs = [];
		if(moralMap["_equs"] != null) {
			for(var i in moralMap["_equs"]) {
				var equ = moralMap["_equs"][i];
				macs.push(equ["mac"]);
			}
		}
		return macs;
	}
	moralMap.getPopupEqu = function(index) {
		if(typeof moralMap["_equs"] === 'object') {
			return moralMap["_equs"][index];
		}
		throw "equs is empty";
	}
	//{id:必填,url:,pagesize:}
	//list加载
	moralMap.initListView = function(option) {
		var listView = {
			load: function(url) {
				if(url != undefined) {
					$.extend(option, {
						"url": url
					});
				}
				option["pageNo"] = 1;
				_load(option);
			}
		};
		listView["option"] = option;
		listView.refreshState = function(equstates) {
			if(equstates != null) {
				for(var i in equstates) {
					var equstate = equstates[i];
					var mac = equstate["mac"];
					var state = equstate["state"];
					var id_select = "#listview_state_" + mac;
					var stateObj = _getStateMap(state);
					var stateClass = stateObj["state"];
					var stateName = stateObj["stateName"];
					if(!$(id_select).hasClass(state)) {
						$(id_select).attr("class", stateClass);
						$(id_select).text(stateName);
					}
				}
			}
		}
		function _getStateMap(s) {
			var state;
			var stateName;
			switch(parseInt(s)) {
				case 0:
					state = 'state00';
					stateName = '正常';
					break;
				case 1:
					state = 'state01';
					stateName = '轻度';
					break;
				case 2:
					state = 'state02';
					stateName = '中度';
					break;
				case 3:
					state = 'state03';
					stateName = '严重';
					break;
				case 4:
					state = 'state04';
					stateName = '维保';
					break;
			}
			return {
				"state": state,
				"stateName": stateName
			};
		}
		function _load(option) {
			if(option['url'] != null && option['url'] != "") {
				var pageSize = option["pageSize"] || 20;
				var pageNo = option["pageNo"] || 1;
				var url = option['url'];
				url += "&pageNo=" + pageNo;
				url += "&pageSize=" + pageSize;
				console.log(url);
				$.ajax({
					type: "get",
					cache: false,
					url: url,
					async: true,
					success: function(res) {
						if(res!=null&&res.total!=null) {
							var rows = res.data;
							if(rows==null||rows.length == 0) {
								$(option['id']).html("没有查询到任何数据!");
								return;
							}
							//储存设备信息
							moralMap.setPopupEqus(rows);
							var outHtml = "
";
							for(var i = 0; i < rows.length; i++) {
								var e = rows[i];
								var state = 'state01';
								var stateName = '';
								var s = e['state'] == undefined ? 0 : e['state'];
								var stateObj = _getStateMap(s);
								state = stateObj["state"];
								stateName = stateObj["stateName"];
								var name = e['name'];
								if(moralMap.getUtf8Length(name) > 22) {
									var stop1 = 0;
									for(var stop1_i = 0, len = 0; stop1_i < name.length; stop1_i++) {
										len += ((name.charCodeAt(stop1_i) & 0xff00) != 0) ? 2 : 1;
										stop1 = stop1_i;
										if(len > 8) break;
									}
									var stop2 = 0;
									for(var stop2_i = name.length - 1, len = 0; stop2_i >= 0; stop2_i--) {
										len += ((name.charCodeAt(stop2_i) & 0xff00) != 0) ? 2 : 1;
										stop2 = stop2_i;
										if(len > 10) break;
									}
									name = name.substring(0, stop1) + "..." + name.substring(stop2, name.length);
								}
								var li = " "
									+"" + stateName + "" +
									" "
									+"" + stateName + "" +
									"- " + name + " 
";
								outHtml += li;
							}
							outHtml += "
";
							var total = res['total'];
							var totalPage = Math.ceil(total / pageSize);
							if(totalPage > 1) {
								outHtml += "";
							}
							$(option['id']).html(outHtml);
							if(totalPage > 1) {
								$("#page").paging({
									pageNo: pageNo,
									totalPage: totalPage,
									totalSize: total,
									callback: function(num) {
										//先清空内容
										$(option['id']).html("");
										option["pageNo"] = num;
										_load(option);
									}
								})
							}
						}
					}
				});
			}
		}
		return listView;
	}
	moralMap.MoralMarker = function(option) {
		var _option = option;
		var _pointObj = new BMap.Point(_option['longitude'], _option['latitude']);
		var _iconObj = _getMapIcon(_option["state"]);
		this._point = _pointObj;
		//获取MapIcon私有方法
		function _getMapIcon(state) {
			state = state == null ? 0 : state;
			var icon = _option["icon"];
			//var url = icon["stateIcons"][state];
			var url = icon["url"] + state + ".png";
			return new BMap.Icon(url, new BMap.Size(icon["width"], icon["height"]), {
				imageSize: new BMap.Size(icon["width"], icon["height"])
			});
		}
		this.constructor.call(this, _pointObj, {
			icon: _iconObj,
			enableMassClear: true
		})
		//事件注册
		var eventType = ['click'];
		for(var index in eventType) {
			var eventName = eventType[index];
			if(_option[eventName] != undefined && typeof _option[eventName] == "function") {
				var fn = _option[eventName];
				this.addEventListener(eventName, function() {
					//将arguments转换成数组
					var args = Array.prototype.slice.call(arguments);
					fn.apply(this, args);
				});
			}
		}
		return $.extend(this, {
			refreshState: function(state) {
				//状态发生变化的时候刷新 图标
				if(_option['state'] != state){
                    _option['state'] = state;
                    var iconObj = _getMapIcon(state);
                    this.setIcon(iconObj);
				}
			},
			getOption: function() {
				return _option;
			},
			setOption: function(option) {
				_option = option;
			}
		})
	}
	//new BMap.Marker()这种写法IE7会报错,很奇葩
	moralMap.MoralMarker.prototype = new BMap.Marker();
	//监控点对象 包装Mark对象
	moralMap.Monitorpoint = function(option) {
		if(monitorPointStates){
			for(var i in monitorPointStates){
		    	var state = monitorPointStates[i];
		    	if(state.id == option.id){
		    		option.state = state.state;
		    	}
			}
		}
		var icon = {};
		icon["stateIcons"] = ["/img/ico00.png", "/img/ico01.png", "/img/ico02.png", "/img/ico03.png", "/img/ico04.png"];
		icon["url"] = "/img/ico0";
		icon["width"] = 50;
		icon["height"] = 50;
		option["icon"] = icon;
		var moralMarker = new moralMap.MoralMarker(option);
		//	    var mark =new BMap.Marker(pointObj,{icon:iconObj});
		//==================infoWindow-start============================
		var infoWindow = (function() {
			//生成信息框
			var winOpts = {
				width: 110, // 信息窗口宽度
				height: 80, // 信息窗口高度
				title: getTitleOutHtml(), // 信息窗口标题
				offset: new BMap.Size(-8,-5) //设置信息窗偏移
			}
			function getTitleOutHtml() {
				//title太长用引号...
				var title = (option["name"] == null) ? "" : option["name"];
				if(title.length > 13) {
					title = title.slice(0, 13) + "...";
				}
				var titleOutHtml = "";
				titleOutHtml += "";
				titleOutHtml += title + "
";
				return titleOutHtml;
			}
			function getAdressOutHtml() {
				var address = (option["address"] == null) ? "" : option["address"];
				if(address.length > 18) {
					address = address.slice(0, 18) + "...";
				}
				var adressOutHtml = "";
				adressOutHtml += "";
				adressOutHtml += "| 地址: | ";
				adressOutHtml += address + " ";
				adressOutHtml += " | 
";
                //adressOutHtml += "| 实时数据>> | 
";
                adressOutHtml += "
";
				titleOutHtml += title + "
";
				return titleOutHtml;
			}
			function getAdressOutHtml() {
				var address = (option["address"] == null) ? "" : option["address"];
				if(address.length > 18) {
					address = address.slice(0, 18) + "...";
				}
				var adressOutHtml = "";
				adressOutHtml += "";
				adressOutHtml += "| 地址: | ";
				adressOutHtml += address + " ";
				adressOutHtml += " | 
";
                adressOutHtml += "
";
				titleOutHtml += title + "
";
				return titleOutHtml;
			}
			return new BMap.InfoWindow("", winOpts);
		})();
		var dataHandle = {
			_getDataOutHtml: function(data) {
			    if(data==null||data["state"]==4){
					return "
设备正在维护升级,暂时没有数据!
";
				}
				var mac = data['mac'];
				var itme_mac_key = "item-" + mac + "-" + key;
				var dataOutHtml = "";
				for(var key in data) {
					if($.inArray(key,showSensorKeys)!=-1) {
						var dataValue = data[key];
						var name = sensorNames[key][0];
						var unit = sensorNames[key][1];
						var itme_state = dataHandle._getSensorState(data, key);
//						var itme_name_mac_key = "item-name-" + mac + "-" + key;
						var itme_data_mac_key = "item-data-" + mac + "-" + key;
						var item = "- ";
                        item += ""+name+" ";
                        item += ""+dataValue+"";
                        item += ""+unit+"";
						item += "
";
						dataOutHtml += item;
					}
				}
				dataOutHtml += "