 function trim(str)
{
   return str.replace(/^\s*|\s*$/g,"");
}

function GMapWFS(map, baseURL, typename, buffer, proxy){
	if(proxy == ""){
		this.useProxy = false;
	}else{
		this.useProxy = true;
	}
	this.localProxy = proxy?proxy:"wfs_proxy.php";
	this.map = map;
	this.baseURL = baseURL;
	this.typename = typename;
	this.buffer = buffer;
}

//In order to use a different proxy for WFS, you need to override this function to return the correct URL.
//In the new function you should probably use this.baseURL, this.typename, and the bounds.
GMapWFS.prototype.getWFSURL = function (bounds){
	var bbox = bounds.minX + "," + bounds.minY + ", " +bounds.maxX + "," +bounds.maxY;
	if(this.useProxy){	
		query = this.localProxy + '?';
		query = query + "baseURL=" + encodeURI(this.baseURL);
	}else{
		query = this.baseURL;
		query = query + "&version=1.0.0&request=GetFeature&service=WFS";
	}
	query = query + "&typename=" + encodeURI(this.typename);
	query = query + "&bbox=" + encodeURI(bbox);
	return query;
}

GMapWFS.prototype.setBaseURL = function (baseURL){
	this.baseURL = baseURL;
}

GMapWFS.prototype.setTypename = function (typename){
	this.typename = typename;
}

GMapWFS.prototype.addOverlay = function (a){
	this.map.addOverlay(a);
}

GMapWFS.prototype.clear = function (){
	this.map.clearOverlays();
}


GMapWFS.prototype.refreshInBounds = function (bounds){
	if(!bounds){
		bounds = this.map.getBoundsLatLng();
	}
	
	var url = this.getWFSURL(bounds);
	
	
	var request = GXmlHttp.create();
	request.open("GET", url, true);
	
	var wfs = this; //copies the reference because we can't use this to refer to this in the onreadystatechange function below
	request.onreadystatechange = function() {
	  if (request.readyState == 4) {
		var xmlDoc = GXml.parse(request.responseText);
		var pointsInChunk = 200;
		var points;
		var lines;
		var polygons;
		var pointStr;
		var marker;
		var latlng;
		var lon;
		var lat;
		var coords;
		var point;
		var array;
		var linePoints;
		
		//parse points
		points = xmlDoc.documentElement.getElementsByTagName("Point");
		if(points.length == 0){
			points = xmlDoc.documentElement.getElementsByTagName("gml:Point");
		}

		lines = xmlDoc.documentElement.getElementsByTagName("LineString");
		if(lines.length == 0){
			lines = xmlDoc.documentElement.getElementsByTagName("gml:LineString");
		}
		
		polygons = xmlDoc.documentElement.getElementsByTagName("LinearRing");
		if(polygons.length == 0){
			polygons = xmlDoc.documentElement.getElementsByTagName("gml:LinearRing");
		}
		
		wfs.clear();
		
		//points
		for(var i=0; i < points.length; i++){
			latlng = trim(GXml.value(points[i])).split(",");
			marker = new GMarker(new GPoint(parseFloat(latlng[0]), parseFloat(latlng[1])));
			marker.infoWindowHtml = trim(GXml.value(points[i].parentNode.parentNode)) //.getElementsByTagName("NAME")[0]));
			wfs.addOverlay(marker);
		}
		
		function drawLines(coords){
			coords = trim(coords);
			points = coords.split(" ");
			linePoints = [];
			for(var j=0; j < points.length; j++){
				latlng = points[j].split(",");
				point = new GPoint(parseFloat(latlng[0]), parseFloat(latlng[1]));
				linePoints.push(point);
			}
			
			for(var j=0; j< linePoints.length; j += pointsInChunk){
				wfs.addOverlay(new GPolyline(linePoints.slice(j, j+pointsInChunk+1)));
			}
		}

		for(var i=0; i < lines.length; i++){
			coords = GXml.value(lines[i]);
			drawLines(coords);
		}		
				
		for(var i=0; i < polygons.length; i++){
			coords = GXml.value(polygons[i]);
			drawLines(coords);
		}

		GEvent.addListener(map, "click", function(overlay, point){
			if(overlay) {
				map.openInfoWindowHtml(overlay.point, overlay.infoWindowHtml, new GSize(0, -35));
			}
		});
	  }
	}
	request.send(null);
}

GMapWFS.prototype.refreshInBoundsWithBuffer = function (buffer, bounds){
	this.refreshInBounds(this.bufferBounds(buffer, bounds));
}

GMapWFS.prototype.bufferBounds = function (buffer, bounds){
	if(!buffer){
		buffer = this.buffer;
	}
	if(!bounds){
		bounds = this.map.getBoundsLatLng();
	}
	var width = bounds.maxX - bounds.minX;
	var height = bounds.maxY - bounds.minY;
	bounds.minX -= width*buffer;
	bounds.maxX += width*buffer;
	bounds.minY -= height*buffer;
	bounds.maxY += height*buffer;
	return bounds;
}