if (!AWP.Control) AWP.Control = {};

AWP.Control.Search = OpenLayers.Class(OpenLayers.Control, {
	geocoder: null,
	layerAddressMarker: null,
	layerProximityMarker: null,
	vectorProximity: null,
	EVENT_TYPES: ["addressFound"],
	
	freetextStore: null,
	freetextGrid: null,
	realtimeStore: null,
	realtimeGrid: null,
	
	/**
	 * 记录查询方式，用以决定是否在无地理数据时返回初始视点
	 * 	searchByKeywords	返回
	 *	searchByAdress		不返回
	 *	others				暂定不返回
	 */
	searchMethod: null,
	
    initialize: function() {
		OpenLayers.Control.prototype.initialize.apply(this, arguments);
		
		OpenLayers.Event.observe(
			document.getElementById('awp-form-location'),
			"submit",
            OpenLayers.Function.bindAsEventListener(this.searchLocation, this)
		);
		
		OpenLayers.Event.observe(
			document.getElementById('awp-form-keywords'),
			"submit",
            OpenLayers.Function.bindAsEventListener(this.searchByKeywords, this)
		);
		
		OpenLayers.Event.observe(
			document.getElementById('awp-form-address'),
			"submit",
            OpenLayers.Function.bindAsEventListener(this.searchByAddress, this)
		);
		
		OpenLayers.Event.observe(
			document.getElementById('awp-form-ats'),
			"submit",
            OpenLayers.Function.bindAsEventListener(this.searchByATS, this)
		);
		
		OpenLayers.Event.observe(
			document.getElementById('awp-form-lonlat'),
			"submit",
            OpenLayers.Function.bindAsEventListener(this.searchByLonlat, this)
		);
		
		OpenLayers.Event.observe(
			document.getElementById('awp-form-click'),
			"submit",
            OpenLayers.Function.bindAsEventListener(this.searchByClick, this)
		);
		
		OpenLayers.Event.observe(
			document.getElementById('awp-form-placename'),
			"submit",
            OpenLayers.Function.bindAsEventListener(this.searchByPlaceName, this)
		);
		
		this.geocoder = new GClientGeocoder();
    },
	searchLocation: function() {
		this.searchMethod = 'location';
		
		if (this.layerAddressMarker) {
			this.layerAddressMarker.clearMarkers();
		} else {
			this.layerAddressMarker = new OpenLayers.Layer.Markers("Address marker");
			this.map.addLayers([this.layerAddressMarker]);
		}
		
		var address = document.getElementById("location").value;
		this.geocoder.getLocations(address, OpenLayers.Function.bind(this.markeLocation, this));
	},
	markeLocation: function(result) {
		if (result.Status.code == G_GEO_SUCCESS) {
			var count = result.Placemark.length;
			/*if (count > 1) {
				var places = [];
				for (var i = 0; i < count; i++) {
					var p = result.Placemark[i].Point.coordinates;
					var point = new GLatLng(p[1], p[0]);
					var addrs = result.Placemark[i].address;
					places[i] = addrs + " " + point + "\n";
				}
				alert("Found:\n" + places);
			}*/
			
			var p = result.Placemark[0].Point.coordinates;
			var lonlat = new OpenLayers.LonLat(p[0], p[1]);
			var xy = lonlat.clone().transform(this.map.proj_4326, this.map.proj_900913);
			
			this.map.setCenter(xy);
			this.drawAddressMarker(xy);
		} else {
			var reason = "Code " + result.Status.code;
			alert('Could not find "' + address + '" ' + reason);
		}
	},
	selectedLi: function(id) {
		var ul = typeof id == 'string' ? document.getElementById('ul-step1') : id;
		
		var selection = '', lis = ul.getElementsByTagName('li');
		for (var i = 0; i < lis.length; i++) {
			if (lis[i].getElementsByTagName('input')[0] && lis[i].getElementsByTagName('input')[0].checked) {
				selection = lis[i].getElementsByTagName('label')[0].innerHTML;
				break;
			}
		}
		
		return selection;
	},
	findLayer: function() {
		var layerTitle = this.selectedLi('ul-step1');
		
		var layerId;
		if (layerTitle == 'Realtime Data') {
			layerId = 'station_join2';
		} else if (layerTitle == 'Water Information') {
			layerId = 'helen_edit';
		} else if (layerTitle == 'A Basin') {
			layerId = 'sub_pf';
		}
		
		return AWP.Layer.items[layerId] || false;
	},
	searchByKeywords: function(keywords) {
		this.searchMethod = 'keywords';
		AWP.mainPanel.getComponent('south').expand();
		
		keywords = typeof keywords == 'string' ? keywords : document.getElementById('awp-keywords').value;
		
		var layer = this.findLayer();
		if (layer) layer.findByKeywords(keywords);
	},
	searchByAddress: function() {
		this.searchMethod = 'adress';
		
		if (this.layerAddressMarker) {
			this.layerAddressMarker.clearMarkers();
		} else {
			this.layerAddressMarker = new OpenLayers.Layer.Markers("Address marker");
			this.map.addLayers([this.layerAddressMarker]);
		}
		
		var address = document.getElementById("address").value;
		if (address) this.geocoder.getLocations(address, OpenLayers.Function.bind(this.markeAddress, this));
	},
	markeAddress: function(result) {
		if (result.Status.code == G_GEO_SUCCESS) {
			var places = {};
			for (var i = 0, count = result.Placemark.length; i < count; i++) {
				var place = result.Placemark[i];
				places[place.address] = place;
			}
			//AWP.addLog('search' + AWP.addressList.length, count + ' found');
			var addressList = document.getElementById('address-list');
			addressList.style.listStyleType = 'decimal';
			addressList.style.listStylePosition = 'inside';
			
			var html = [], total = 0;
			for (var address in places) {
				total++;
				var place = places[address], p = place.Point.coordinates;
				html.push('<li><a href="javascript:void(0)"'
					+ ' onclick="AWP.searchByCircle(' + p[0] + ', ' + p[1]
					+ ')">' + place.address + '</a></li>');
			}
			
			addressList.innerHTML = html.join('');
			
			var strong = document.getElementById('address-title');
			strong.style.display = 'block';
			strong.style.fontWeight = 'bold';
			strong.style.marginTop = '5px';
			strong.innerHTML = 'Total ' + total + ' results found:';
			
			if (total == 1) {
				var xy = new OpenLayers.LonLat(p[0], p[1]);
				xy = xy.transform(this.map.proj_4326, this.map.proj_900913);
				var r = this.proximity();
				
				var layer = this.findLayer(), area = 0;
				if (layer.layerId == 'helen_edit') {
					area = this.areaLimit('area-limitation');
				}
				AWP.mainPanel.expandSouth(this.zoomByCircle, this, [xy, r, area]);
			}
		} else {
			var reason = "Code " + result.Status.code;
			alert('Could not find ' + reason);
		}
	},
	searchByATS: function() {
		this.searchMethod = 'ats';
		
		var sec = document.getElementById('sec').value;
		var twp = document.getElementById('twp').value;
		var rge = document.getElementById('rge').value;
		var mer = document.getElementById('mer').value;
		
		if (this.layerAddressMarker) {
			this.layerAddressMarker.clearMarkers();
		} else {
			this.layerAddressMarker = new OpenLayers.Layer.Markers("Address marker");
			this.map.addLayers([this.layerAddressMarker]);
		}
		
		OpenLayers.Request.GET({
			url: AWP.cfg.serviceURL
				+ 'action=searchATS'
				+ '&sec=' + sec
				+ '&twp=' + twp
				+ '&rge=' + rge
				+ '&mer=' + mer
				+ '&format=json',
			success: function(response) {
				try {
					var json = eval('(' + response.responseText + ')');
				} catch (e) {
					alert(e + '\n\n' + response.responseText);
					return
				}
				var atsRows = json.rows;
				
				var atsList = document.getElementById('ats-list');
				atsList.style.listStyleType = 'decimal';
				atsList.style.listStylePosition = 'inside';
				
				var total = atsRows.length;
				if (total > 0) {
					var html = [], feature, features = [], layer = AWP.Layer.items['section_project'];
					for (var i = 0, len = atsRows.length; i < len; i++) {
						var ats = atsRows[i];
						
						feature = layer.awp_wkt.read(ats.the_geom);
						feature.fid = layer.layerId + '.' + ats.gid;
						features.push(feature);
						html.push('<li><a href="javascript:void(0)"'
							+ 'onmouseover="AWP.Layer.overFeature(\'' + feature.fid + '\')"'
							+ 'onmouseout="AWP.Layer.outFeature(\'' + feature.fid + '\')"'
							+ '>' + ats.descriptor + '</a></li>');
					}
					atsList.innerHTML = html.join('');
					
					layer.displayFeatures(features);
				}
				
				var strong = document.getElementById('ats-title');
				strong.style.display = 'block';
				strong.style.fontWeight = 'bold';
				strong.style.marginTop = '5px';
				strong.innerHTML = 'Total ' + atsRows.length + ' results found:';
				
				if (total == 1) {
					var layer2 = this.findLayer(), area = 0;
					if (layer2.layerId == 'helen_edit') area = this.areaLimit('area-limitation');
					/**
					 * 因为 southPanel 处于常打开状态，所以不必再使用 expandSouth 方法通过注册 expand 事件来执行
					 * @date 2010-03-31
					 */
					//AWP.mainPanel.expandSouth(layer2.findByFeature, layer2, [layer.layers, atsRows[0].gid, area]);
					layer2.findByFeature(layer.layers, atsRows[0].gid, area);
				}
			},
			failure: function() {alert('sorry')},
			scope: this
		});
		//AWP.mainPanel.expandSouth(this.searchByATS, this, [sec, twp, rge, mer]);
	},
	searchByLonlat: function() {
		this.searchMethod = 'lonlat';
		
		if (this.layerAddressMarker) {
			this.layerAddressMarker.clearMarkers();
		} else {
			this.layerAddressMarker = new OpenLayers.Layer.Markers("Address marker");
			this.map.addLayers([this.layerAddressMarker]);
		}
		
		var lon = document.getElementById('lon').value;
		var lat = document.getElementById('lat').value;
		var lonlat = new OpenLayers.LonLat(lon, lat);
		if (document.getElementsByName('lonlat-unit')[0].checked) {
			lonlat = lonlat.transform(this.map.proj_4326, this.map.proj_900913);
		}
		
		var proximity = this.proximity("proximity-lonlat");
		var area = this.areaLimit("area-limitation");
		
		AWP.mainPanel.expandSouth(this.zoomByCircle, this, [lonlat, proximity, area]);
	},
	searchByClick: function() {
		this.searchMethod = 'click';
		
		if (this.layerAddressMarker) {
			this.layerAddressMarker.clearMarkers();
		} else {
			this.layerAddressMarker = new OpenLayers.Layer.Markers("Address marker");
			this.map.addLayers([this.layerAddressMarker]);
		}
		
		var lon = document.getElementById('lon2').value;
		var lat = document.getElementById('lat2').value;
		var lonlat = new OpenLayers.LonLat(lon, lat);
		lonlat.transform(AWP.map.proj_4326, AWP.map.proj_900913);
		
		var proximity = this.proximity("proximity-click");
		var area = this.areaLimit("area-limitation");
		
		AWP.mainPanel.expandSouth(this.zoomByCircle, this, [lonlat, proximity, area]);
	},
	searchByPlaceName: function() {
		this.searchMethod = 'placename';
		
		if (this.layerAddressMarker) {
			this.layerAddressMarker.clearMarkers();
		} else {
			this.layerAddressMarker = new OpenLayers.Layer.Markers("Address marker");
			this.map.addLayers([this.layerAddressMarker]);
		}
		
		var keywords = document.getElementById('placename').value;
		OpenLayers.Request.GET({
			url: AWP.cfg.serviceURL
				+ 'action=searchPlaceName'
				+ '&keywords=' + keywords
				+ '&format=json',
			success: function(response) {
				try {
					var json = eval('(' + response.responseText + ')');
				} catch (e) {
					alert(e + '\n\n' + response.responseText);
					return
				}
				var places = json.rows;
				
				var placenameList = document.getElementById('placename-list');
				placenameList.style.listStyleType = 'decimal';
				placenameList.style.listStylePosition = 'inside';
				
				var html = [], total = 0, feature, features = [], layer = AWP.Layer.items['toponym'];
				for (var i = 0, len = places.length; i < len; i++) {
					var place = places[i], xy = new OpenLayers.LonLat(place.x, place.y);
					
					feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(place.x, place.y));
					feature.fid = layer.layerId + '.' + place.gid;
					features.push(feature);
					
					xy = xy.transform(this.map.proj_900913, this.map.proj_4326);
					html.push('<li><a href="javascript:void(0)"'
						+ ' onclick="AWP.searchByCircle(' + xy.lon + ', ' + xy.lat + ', \'proximity-placename\')"'
						+ ' onmouseover="AWP.Layer.overFeature(\'' + feature.fid + '\')"'
						+ ' onmouseout="AWP.Layer.outFeature(\'' + feature.fid + '\')"'
						+ '>' + place.name + '(' + place.gid + ')</a></li>');
				}
				placenameList.innerHTML = html.join('');
				
				var strong = document.getElementById('placename-title');
				strong.style.display = 'block';
				strong.style.fontWeight = 'bold';
				strong.style.marginTop = '5px';
				strong.innerHTML = 'Total ' + places.length + ' results found:';
				
				layer.displayFeatures(features);
			},
			failure: function() {alert('sorry')},
			scope: this
		});
	},
	zoomByCircle: function(xy, r, area) {
		var bounds = new OpenLayers.Bounds(xy.lon - r, xy.lat - r, xy.lon + r, xy.lat + r);
		var zoomLevel = this.map.getZoomForExtent(bounds);
		this.map.setCenter(xy, zoomLevel);
		
		this.drawAddressMarker(xy);
		this.drawProximityCircle(xy, r);
		
		var layer = this.findLayer();
		if (layer) layer.findByProximity(xy, r, area);
	},
	drawAddressMarker: function(xy) {
		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(xy, icon);
		this.layerAddressMarker.addMarker(marker);
		this.layerAddressMarker.setOpacity(0.5);
	},
	proximity: function(selectId) {
		var selectId = selectId || "proximity";
		var proximity = document.getElementById(selectId).value;
		proximity = [10000, 20000, 50000, 100000][proximity] || 10000;
		
		return proximity;
	},
	areaLimit: function(selectId) {
		var area = document.getElementById(selectId).value;
		return ([100000, 10000, 1000, 100][area] || 100000) * 1000 * 1000;
	},
	drawProximityCircle: function(xy, r) {
		if (!this.layerProximityMarker) {
			this.layerProximityMarker = new OpenLayers.Layer.Vector("Proximity marker", {
				style: {
					fillColor: '#ffffff',
					strokeColor: '#00ff00',
					fillOpacity: 0,
					strokeWidth: 1
				}
			});
			this.map.addLayers([this.layerProximityMarker]);
		}
		
		if (this.vectorProximity) {
			this.layerProximityMarker.removeFeatures([this.vectorProximity]);
		}
		
		var pointList = [];
		for (var i = 0; i < 61; i++) {
			var a = i * (2 * Math.PI) / 60;
			var newPoint = new OpenLayers.Geometry.Point(
				xy.lon + (r * Math.cos(a)),
				xy.lat + (r * Math.sin(a))
			);
			pointList.push(newPoint);
		}
		
		var linearRing = new OpenLayers.Geometry.LinearRing(pointList);
		this.vectorProximity = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([linearRing]));
		this.layerProximityMarker.addFeatures([this.vectorProximity]);
	},
    CLASS_NAME: "AWP.Control.Search"
});
