AWP.Map = OpenLayers.Class(OpenLayers.Map, {
	defaultCenter: new OpenLayers.LonLat(-110, 54.5),
	defaultZoomLevel: 4,
	proj_4326: new OpenLayers.Projection("EPSG:4326"),
	proj_900913: new OpenLayers.Projection("EPSG:900913"),
    Z_INDEX_BASE: {
        BaseLayer: 100,
        Overlay: 250,
        Feature: 500,
        Popup: 750,
        Control: 1000
    },
	initialize: function (div) {
		var options = {
			controls: [],
			projection: this.proj_900913,
			units: "m",
			numZoomLevels: 19,
			maxResolution: AWP.cfg.RESOLUTION,
			maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
		}
		OpenLayers.Map.prototype.initialize.call(this, div, options);
		this.id = 'AWP-map-id';
	},
	/**
	 * 2009-10-19
	 *   initial Map controls and layers for AWP
	 */
	init: function() {
		this.addLayers(AWP.Layer.array);
		this.addLayers([new AWP.Layer.Vector({name: "Vector Features"})]);
		//this.addLayers([new OpenLayers.Layer.Vector("Selection Features")]);
		
		
		var center = (AWP.cfg.defaultCenter || this.defaultCenter).transform(this.proj_4326, this.proj_900913);
		var zoomLevel = AWP.cfg.defaultZoomLevel || this.defaultZoomLevel;
		this.setCenter(center, zoomLevel);
		
		
		// 2009-07-03, Ma: this control always makes CPU run 100% 
		//this.addControl(new AWP.Control.MousePosition());
		//this.addControl(new OpenLayers.Control.LayerSwitcher());
		this.addControl(new OpenLayers.Control.KeyboardDefaults());
		this.addControl(new AWP.Control.ScaleLine());
		this.addControl(new AWP.Control.Search());
		this.addControl(new AWP.Control.SelectFeature(this.getLayerByName("Vector Features")));
		this.addControl(new AWP.Control.PanZoomBar());
		
		
		new AWP.Control.Information();
		var panel = new OpenLayers.Control.Panel({
			div: document.getElementById("panelControl")
		});
		panel.addControls([
			new OpenLayers.Control.Button({
				displayClass: 'AWPControlHome',
				title: 'Home View',
				trigger: OpenLayers.Function.bind(function() {
					var center = AWP.cfg.defaultCenter || this.defaultCenter;
					var zoomLevel = AWP.cfg.defaultZoomLevel || this.defaultZoomLevel;
					this.setCenter(center, zoomLevel);
				}, this)
			}),
			/**
			 * Enable "zoomWheelEnabled", asked by Spencer
			 */
			new OpenLayers.Control.Navigation({title: 'Pan map'/*, zoomWheelEnabled: false*/}),
			new AWP.Control.Measure(),
			new OpenLayers.Control.ZoomBox({title: "Zoom map"})
			//new AWP.Control.Identify(),
		]);
		panel.defaultControl = panel.getControlsByClass('OpenLayers.Control.Navigation')[0];
		this.addControl(panel);
		
		/*var panel = new OpenLayers.Control.Panel({
			div: document.getElementById("panelButton")
		});
		panel.addControls(new AWP.Control.Button());
		this.addControl(panel, new OpenLayers.Pixel(1, 320));*/
	},
	initAWPAdmin: function(x, y) {
		// 添加 /js/config.js 中配置的图层
		this.addLayers(AWP.Layer.array);
		// 添加可响应鼠标事件的 features 所在图层，以及控制响应的 AWP.Control.SelectFeature
		this.addLayer(new AWP.Layer.Vector({name: "Interactive Vector Feature Layer"}));
		this.addControl(new AWP.Control.SelectFeature(this.getLayerByName("Interactive Vector Feature Layer"))).activate();
		
		// 设置地图中心点和缩放级别
		if (x && y) {
			var center = new OpenLayers.LonLat(x, y);
		} else {
			var center = (AWP.cfg.defaultCenter || this.defaultCenter).transform(this.proj_4326, this.proj_900913);
		}
		var zoomLevel = AWP.cfg.defaultZoomLevel || this.defaultZoomLevel;
		this.setCenter(center, zoomLevel);
		
		// 2009-07-03, Ma: this control always makes CPU run 100% 
		this.addControl(new AWP.Control.MousePosition({
			element: document.getElementById('position')
		}));
		this.addControl(new AWP.Control.ScaleLine());
		this.addControl(new AWP.Control.PanZoomBar());
		// 
		var controlIdentify = this.addControl(new AWP.Control.Identify({layer: this.getLayerByName("Interactive Vector Feature Layer")}));
		if (x && y) {
			controlIdentify.markPlace(center);
		}
		
		// 添加右上角的功能按钮
		var panel = new OpenLayers.Control.Panel({
			div: document.getElementById("panelControl")
		});
		panel.addControls([
			new OpenLayers.Control.Button({
				displayClass: 'AWPControlHome',
				title: 'Home View',
				trigger: OpenLayers.Function.bind(function() {
					var center = AWP.cfg.defaultCenter || this.defaultCenter;
					var zoomLevel = AWP.cfg.defaultZoomLevel || this.defaultZoomLevel;
					this.setCenter(center, zoomLevel);
				}, this)
			}),
			/**
			 * Enable "zoomWheelEnabled", asked by Spencer
			 */
			new OpenLayers.Control.Navigation({title: 'Pan map'/*, zoomWheelEnabled: false*/}),
			new AWP.Control.Measure(),
			new OpenLayers.Control.ZoomBox({title: "Zoom map"})
			//new AWP.Control.Identify(),
		]);
		panel.defaultControl = panel.getControlsByClass('OpenLayers.Control.Navigation')[0];
		this.addControl(panel);
	},
	/**
	 * 2009-10-19
	 *   initial Map controls and layers for SEAWA
	 */
	initSEAWA: function() {
		this.addLayers(AWP.Layer.array);
		this.addLayers([new AWP.Layer.Vector({name: "Vector Features"})]);
		
		if (AWP.cfg.seawaExtent) {
			var feature = new OpenLayers.Format.WKT().read(AWP.cfg.seawaExtent);
			var bounds = feature.geometry.getBounds();
			/**
			 * @date 2010-08-19 #82 Requirement
			 * Please make the default level of magnification (zoom) one level more detailed. 
			 */
			AWP.cfg.defaultZoomLevel = this.getZoomForExtent(bounds) + 1;
			AWP.cfg.defaultCenter = bounds.getCenterLonLat();
			if (AWP.cfg.SEAWA == 'seawa') {
				AWP.cfg.defaultCenter.lat -= bounds.getHeight() * 0.2;
			}
		} else {
			(AWP.cfg.defaultCenter || this.defaultCenter).transform(this.proj_4326, this.proj_900913);
		}
		
		var center = AWP.cfg.defaultCenter || this.defaultCenter;
		var zoomLevel = AWP.cfg.defaultZoomLevel || this.defaultZoomLevel;
		this.setCenter(center, zoomLevel);
		
		//this.addControl(new AWP.Control.MousePosition());
		//this.addControl(new OpenLayers.Control.KeyboardDefaults());
		this.addControl(new AWP.Control.ScaleLine());
		this.addControl(new AWP.Control.SelectFeature(this.getLayerByName("Vector Features")));
		this.addControl(new AWP.Control.PanZoomBar());
		
		
		//new AWP.Control.Information();
		var panel = new OpenLayers.Control.Panel({
			div: document.getElementById("panelControl")
		});
		panel.addControls([
			new OpenLayers.Control.Button({
				displayClass: 'AWPControlHome',
				title: 'Home View',
				trigger: OpenLayers.Function.bind(function() {
					var center = AWP.cfg.defaultCenter || this.defaultCenter;
					var zoomLevel = AWP.cfg.defaultZoomLevel || this.defaultZoomLevel;
					this.setCenter(center, zoomLevel);
				}, this)
			}),
			new OpenLayers.Control.Navigation({title: 'Pan map'/*, zoomWheelEnabled: false*/}),
			new AWP.Control.Measure(),
			new OpenLayers.Control.ZoomBox({title: "Zoom map"})
			//new AWP.Control.Identify(),
			/**
			 *
			 */
			//new AWP.Control.GoogleEarth({title: "Launch Basin Explorer"})
		]);
		panel.defaultControl = panel.getControlsByClass('OpenLayers.Control.Navigation')[0];
		this.addControl(panel);
		
		
		/**
		 * UserContent 相关初始化
		 * @date 2010-08-19 #82 需求：去掉 Member Contents
		 *
		var userContent = AWP.userContent;
		// UserContent 的 Features 所在层
		var layer = new OpenLayers.Layer.Vector("Editable");
		this.addLayer(layer);
		// 如果 Feature 有修改，激活 SaveFeature Control
		layer.events.register("afterfeaturemodified", userContent, userContent.onAfterFeatureModified);
		layer.events.register("sketchcomplete", userContent, userContent.onSketchcomplete);
		
		// 控制 UserContent 的 Features 的鼠标悬浮、点击事件
		var control = new AWP.Control.SelectFeature(layer);
		this.addControl(control);
		control.activate();
		control.id = 'editable_selectFeature';
		*/
		if (AWP.user && !AWP.user.guest) {
			/**
			 * @date 2010-08-19 #82 需求：去掉 Member Contents
			 *
			var panel = new OpenLayers.Control.Panel({
				id: 'edit_bar',
				div: document.getElementById('edit_bar')
			});
	        panel.addControls([
				new AWP.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {
					title: 'Draw Polygon',
					displayClass: 'olControlDrawFeaturePolygon'
				}),
				new AWP.Control.DrawFeature(layer, OpenLayers.Handler.Path, {
					title: 'Draw Path',
					displayClass: 'olControlDrawFeaturePath'
				}),
				new AWP.Control.DrawFeature(layer, OpenLayers.Handler.Point, {
					title: 'Draw Point',
					displayClass: 'olControlDrawFeaturePoint'
				}),
				new AWP.Control.ModifyFeature(layer, {
					title: "Modify Features",
					displayClass: "olControlModifyFeature"
				}),
				new OpenLayers.Control.Navigation({title: "Navigate"}),
				new AWP.Control.SaveFeature(layer, {
					title: "Save Created/Modified Feature",
					displayClass: "AWPControlSaveFeature",
					onSave: OpenLayers.Function.bind(userContent.onClickSaveFeatures, userContent)
				})
	        ]);
	        this.addControl(panel);
	        */
	        
			/*var snap = new OpenLayers.Control.Snapping({
				layer: vlayer,
				targets: [vlayer],
				greedy: false
			});
			snap.activate();*/
		}
	},
	/**
	 * 2010-07-14
	 *   initial AWP Water Data
	 */
	iniAWPWatertData: function() {
		this.addLayers(AWP.Layer.array);
		
		// 设置地图中心点和缩放级别
		var center = (AWP.cfg.defaultCenter || this.defaultCenter).transform(this.proj_4326, this.proj_900913);
		var zoomLevel = AWP.cfg.defaultZoomLevel || this.defaultZoomLevel;
		this.setCenter(center, zoomLevel);
		
		this.addControl(new OpenLayers.Control.PanZoom());
		this.addControl(new OpenLayers.Control.Navigation({title: 'Pan map'/*, zoomWheelEnabled: false*/}));
		
//		var layerPlacemark = new OpenLayers.Layer.Markers("Place Marker");
//		this.addLayers([layerPlacemark]);
//		
//		var size	= new OpenLayers.Size(21, 25);
//		var offset	= new OpenLayers.Pixel(-(size.w/2), -15);
//		var icon	= new OpenLayers.Icon(AWP.cfg.baseURL + 'image/marker.png', size, offset);
//		var marker	= new OpenLayers.Marker(center, icon);
//		layerPlacemark.addMarker(marker);
//		layerPlacemark.setOpacity(0.5);
	},
	addControl: function(control) {
		OpenLayers.Map.prototype.addControl.apply(this, arguments);
		return control;
	},
	/**
	 * 重写这个方法是为了避免添加某个层出现异常时导致程序中止
	 */
	addLayers: function(layers) {
		// 添加可以设置默认显示其他 Google Map 的功能
		var default_google_map = null;
		for (var i = 0, len = layers.length; i < len; i++) {
			if (AWP.cfg.SEAWA_GOOGLE_MAP_DEFAULT == layers[i].layerId) {
				default_google_map = layers[i];
				break;
			}
		}
		if (default_google_map) {
			default_google_map.checked = true;
			this.addLayer(default_google_map);
		}
		
		for (var i = 0, len = layers.length; i < len; i++) {
			if (layers[i] == default_google_map) {
				continue;
			}
			try {
				this.addLayer(layers[i]);
			} catch (e) {
				;
			}
		}
	},
	getLayerByName: function(name) {
        var foundLayer = null;
        for (var i = 0, len = this.layers.length; i < len; i++) {
            var layer = this.layers[i];
            if (layer.name == name) {
                foundLayer = layer;
                break;
            }
        }
        return foundLayer;
    },
	getResolutions: function() {
        if (this.baseLayer != null) {
            return this.baseLayer.resolutions;
        }
        return [];
	},
	setLayerZIndex: function (layer, zIdx) {
		var type;
		
		if (layer.isBaseLayer) {
			type = 'BaseLayer';
		} else if (layer instanceof AWP.Layer.Markers) {
			type = 'Feature';
		} else {
			type = 'Overlay';
		}
		
		layer.setZIndex(this.Z_INDEX_BASE[type]	+ zIdx);
	},
	setPopupToTop: function(popup) {
		var zIndex = this.Z_INDEX_BASE['Popup'];
        for (var i = 0, len = this.popups.length; i < len; i++) {
			if (this.popups[i] != popup) {
				this.popups[i].div.style.zIndex = zIndex + i;
			}
		}
		popup.div.style.zIndex = zIndex + this.popups.length;
    },
	addOverlay: function(overlay) {
		if (this.baseLayer instanceof OpenLayers.Layer.Google) {
			var gmap = this.baseLayer.mapObject;
			gmap.addOverlay(overlay);
		}
	}
});
