var aerialLayer;
var Utils = {
    /* function to display an error message in an alert */
    "errMsg" : function (sField){
	alert("Please enter your " + sField + " in the " + sField + " box.");
	return false;
    }, 
    /* show the privacy policy */
    "openPolicy" : function() {
	var strFeatures = "scrollbars=1, resizable=1, width=400, height=300, left=50, top=50";
	var winPolicy = window.open("#self#?fuseaction=warden.policy", "winPolicy", strFeatures);
    },

    /* display a warning when naturewardens overwrite an existing record*/	
    "overwriteWarning" : function() {
	var str = 'CAUTION\n\nThis record already exists in the citywildlife database.\n';
	str += 'Saving your record at this time will overwrite the previous record,\n';
	str += 'requiring any photos to be verified by an administrator again.\n\n';
	str += 'Click OK to save the record or Cancel to abandon changes';
	if (confirm(str)) {
	    bCanLeave = true;
	    return true;
	} else {
	    location.href = 'fbx_index.cfm?fuseaction=species.special';
	    return false;
	}
    }, 

    /* look up a map service in the 2D Config array */

    "findService" : function(services, key, value) {
	var s;
	for (var i=0; i < services.length; i++) {
	    s = services[i];
	    if (s[key] == value) { 
		return s;
	    }
	}
    },

    /* look up a key value in the url querystring */
    "queryString" : function(k) {
	var qs = window.location.search.substring(1);
	var kvs = qs.split("&");
	for (var i=0; i < kvs.length; i++) {
	    var kv = kvs[i].split("=");
	    if (kv[0].toLowerCase() === k.toLowerCase()) {
		return kv[1];
	    }
	}
	return null;
    },

    /* handle a map error */ 
    "serviceError" : function(err) {
	console.log("Map service error. " + err.code + ", " + err.details);
    },

    /* Common code for initialising a map and adding the base layer */

    "mapAndBaseLayer" : function(initialExtent) {
	try {
	    dojo.style(dojo.byId("map"), {
		width: dojo.contentBox("map").w + "px",
		height: (dojo.contentBox("map").w * 0.7) + "px"
		//height: dojo.contentBox("map").h + "px"
            });
        
            var startExtent;
	    if (initialExtent) {
		startExtent = new esri.geometry.Extent(initialExtent.xmin, 
						       initialExtent.ymin, 
						       initialExtent.xmax, 
						       initialExtent.ymax,
						       new esri.SpatialReference({ wkid: initialExtent.spid }));
	    } else {
		startExtent = new esri.geometry.Extent(appSettings.DefaultExtent.xmin, 
						       appSettings.DefaultExtent.ymin, 
						       appSettings.DefaultExtent.xmax, 
						       appSettings.DefaultExtent.ymax,
						       new esri.SpatialReference({ wkid: appSettings.DefaultExtent.spid }));
	    }
	    esriConfig.defaults.map.sliderLabel = null;
	    //esriConfig.defaults.map.slider.height = "0px";
	    //esriConfig.defaults.map.slider = null;
            map = new esri.Map("map", { extent: startExtent });

	    var imageParameters = new esri.layers.ImageParameters();
            imageParameters.layerOption = esri.layers.ImageParameters.LAYER_OPTION_SHOW;
	    imageParameters.layerIds = [1];

	    var baseLayer = new esri.layers.ArcGISTiledMapServiceLayer(appSettings.BaseMapUrl, {"imageParameters":imageParameters, "opacity": 0.9});
	    aerialLayer = new esri.layers.ArcGISDynamicMapServiceLayer(CWLSettings.aerialURL);

            Utils.addLayer(baseLayer, 1);

	    dojo.connect(map, "onLoad", Utils.showLoading);
	    function incAndShowLoading () {
		Utils.numLayersToLoad = map.layerIds.length;
		Utils.showLoading();
	    }

	    function addAerialLayerInner() {
		if (map.getLevel() > 8 && !CWLSettings.hasAerialLayer){
		    //Utils.addAerialLayer();
		    Utils.writeContentAndNudgeMap($('#baseLayerSwitcheroo'), Utils.switcherooForm());
		} else if (map.getLevel() < 9){
		    if (CWLSettings.hasAerialLayer) Utils.removeAerialLayer();
		    Utils.writeContentAndNudgeMap($('#baseLayerSwitcheroo'), '');
		}
	    }
	
            dojo.connect(map, "onZoomStart", incAndShowLoading);
	    dojo.connect(map, "onZoomEnd", addAerialLayerInner);
            dojo.connect(map, "onPanStart", incAndShowLoading);
	} catch (e) {
	    console.log('Utils.mapAndBaseLayer error:',e);
	}
    },

    "addAerialLayer": function() {
	Utils.addLayer(aerialLayer, 1);
	CWLSettings.hasAerialLayer = true;
	CWLSettings.baseLayerIsAerial = true;
    } ,

    "removeAerialLayer": function() {
	map.removeLayer(aerialLayer);
	CWLSettings.hasAerialLayer = false;
	CWLSettings.baseLayerIsAerial = false;
    } ,

    /* the form for switching base layers */
    "switcherooForm" : function() {
	var str = '<form><strong>Base layer: </strong><input type="radio" name="baseLayer" value="sview" onClick="return Utils.switchBaseLayer(\'sview\');"';
	if (!CWLSettings.baseLayerIsAerial) str += ' checked ';
	str += '/>street map &nbsp; <input type="radio" name="baseLayer" value="aerial" onClick="return Utils.switchBaseLayer(\'aerial\');"';
	if (CWLSettings.baseLayerIsAerial) str += ' checked ';
	str += ' /> aerial</form>';
	return str;
    },

    /* switch base layers on and off */
    "switchBaseLayer": function (layer) {
	if (layer === 'sview' && CWLSettings.baseLayerIsAerial) {
	    Utils.removeAerialLayer();
	    CWLSettings.hasAerialLayer = false;
	} else if (layer === 'aerial' && !CWLSettings.baseLayerIsAerial) {
	    Utils.addAerialLayer();
	    CWLSettings.hasAerialLayer = true;
	}
    },

    "addLayer" : function(layer, index) {
	dojo.connect(layer, "onError", null, Utils.serviceError);
	dojo.connect(layer, "onUpdate", Utils.hideLoading);
	if (index) {
	    map.addLayer(layer, index);
	} else {
	    map.addLayer(layer);
	}
    },

    "numLayersLoaded" : 0 ,
    
    "showLoading": function() {
	var loading = dojo.byId("loadingImg");  
	esri.show(loading);
	//map.disableMapNavigation();
	//map.hideZoomSlider();
    }, 

    "hideLoadingSimple": function() {
	var loading = dojo.byId("loadingImg");  
	esri.hide(loading);
        map.enableMapNavigation();
        map.showZoomSlider();
    },

    "hideLoading": function() {
	Utils.numLayersLoaded++;
	if (Utils.numLayersLoaded === map.layerIds.length) {
	    Utils.hideLoadingSimple();
            Utils.numLayersLoaded = 0;
	}
    },

    /* returns true if we're using the streetview layer as the base layer of the map */

    "isSView" : function () {
	Utils.getBaseLayer() == 'sview';
    },

    /* returns true if we're using the aerial layer as the base layer of the map */

    "isSView" : function () {
	Utils.getBaseLayer() == 'aerial';
    },

    /* returns the name of the layer being used as the base layer of the map */

    "getBaseLayer" : function () {
	var base = Utils.queryString('baseLayer');
	if (base && base.length > 0) {
	    return base;
	} else {
	    return CWLSettings.defaultBaseLayer;
	}
    }, 

    /* draw a point at map ref east/north using symbol */
    "drawAtPoint" : function(east, north, symbol, clear, attr) {
	if(clear == null) {
	    clear = true;
	} 
	attr = attr || {};
	//draw the point
	if(!symbol) {
	    symbol = new esri.symbol.SimpleMarkerSymbol().setColor(
		new dojo.Color([0, 255, 0]));
	}
	if (clear) map.graphics.clear();
	var point = new esri.geometry.Point(east, north, map.spatialReference);
	graphic = new esri.Graphic(point, symbol, attr);
	map.graphics.add(graphic);        
    },

    /* zoom to a point on the map, given an offset in SCREEN values */
    "zoomToPoint": function (mapX, mapY, screenOffset) {
	var spid = new esri.SpatialReference({ wkid: appSettings.DefaultExtent.spid });
	var screenPoint = map.toScreen(new esri.geometry.Point(mapX, mapY, spid));
	var lowerLeft = map.toMap(screenPoint.update(screenPoint.x - screenOffset, screenPoint.y +  screenOffset));
	var upperRight = map.toMap(screenPoint.update(screenPoint.x + 2*screenOffset, screenPoint.y -  2*screenOffset));
	var extent = new esri.geometry.Extent(lowerLeft.x, lowerLeft.y, upperRight.x, upperRight.y, spid);
	map.setExtent(extent);
    },

    /* draw a set of sightings */
    "drawSightings" : function(data) {
	var green = new esri.symbol.SimpleMarkerSymbol().setColor(
		new dojo.Color([0, 255, 0]));
	var red = new esri.symbol.SimpleMarkerSymbol().setColor(
		new dojo.Color([255, 0, 0]));
	
	map.graphics.clear();
	var point, colour, sighting;
	//draw the points
	for (var i=0; i < data.length; i++) {
	    sighting = data[i];
	    var images = "";
	    var approved = true;
	    if(sighting.lscape_photos.length > 0) {
		var photo;
		for (var j=0; j < sighting.lscape_photos.length; j++) {
		    photo = sighting.lscape_photos[j];
		    images = images + "<img src='photos/landscape/t_"+photo.filename+"' />&nbsp;";
		    if (photo.verified_status === 'N') approved = false;
		}
	    } 
	    colour = (approved ? [0, 255, 0, 128] : [255, 0, 0, 128]);
	    if (images !== '') images = "<br />" + images + "<p></p>";
	    point = {"geometry":{"x": sighting.x,
				 "y": sighting.y,
				 "spatialReference": map.spatialReference},
		     "attributes":{
			 "pending_status": sighting.pending_status,
			 "scientific_name": sighting.scientific_name,
			 "common_name": sighting.common_name,
			 "number_observed": sighting.number_observed,
			 "observation_date": sighting.observation_date,
			 "date_of_entry": sighting.date_of_entry
		     },
		     "symbol":{
			 "color": colour,
			 "size":12,
			 "angle":0,
			 "xoffset":0,
			 "yoffset":0,
			 "type":"esriSMS",
			 "style":"esriSMSCircle",
			 "outline":{
			     "color":[0,0,0,255],
			     "width":1,
			     "type":"esriSLS",
			     "style":"esriSLSSolid"
			 }
		     },
		     "infoTemplate":{
			 "title": " ${common_name} [${scientific_name}]",
			 "content": "Number seen: ${number_observed} <br/> Date observed: ${observation_date} <br/> Date recorded: ${date_of_entry} <br/>" + images
		     }
		    };
	    graphic = new esri.Graphic(point);
	    map.graphics.add(graphic);        
	}
	//set map extent to city
	map.setExtent(new esri.geometry.Extent(CWLSettings.cityExtent));
    },

    /* form a date string */
    "formatDate" : function(str) {
	var strDate = str.substring(0,10);
	var bits = strDate.split("-");
	return bits[2] + "/" + bits[1] + "/" + bits[0];
    },

    /* draw a set of points at map ref east/north using symbol */
    "drawAtPoints" : function(ps, symbol) {
	//draw the point
	if(!symbol) {
	    symbol = new esri.symbol.SimpleMarkerSymbol().setColor(
		new dojo.Color([0, 255, 0]));
	}
	map.graphics.clear();
	var point;
	for(var i=0; i < ps.length; i++) {
	    point = new esri.geometry.Point(ps[i][0], ps[i][1], map.spatialReference);
	    graphic = new esri.Graphic(point, symbol);
	    map.graphics.add(graphic);        
	}
    },
    /* return true if the attributes of two sightings, represented by graphics objects, are equal */
    "sightingsEqual" : function(g1, g2) {
	return (g1.scientific_name === g2.scientific_name) 
	    && (g1.observation_date === g2.observation_date) 
	    && (g1.number_observed === g2.number_observed)
	    && (g1.x === g2.x)
	    && (g1.y === g2.y);
    } ,
    
    "colours" : {
	"green"  : [0,   255, 0,   128],
	"red"    : [255, 0,   0,   128],
	"yellow" : [255, 255, 0,   128],
	"brown"  : [188, 143, 143, 128]
    }, 
    /* a simple marker symbol for maps */
    "smsJSON" : function (colour, size){
	size = size || 12;
	return {
	    "color": colour,
	    "size": size,
	    "angle":0,
	    "xoffset":0,
	    "yoffset":0,
	    "type":"esriSMS",
	    "style":"esriSMSCircle",
	    "outline":{
		"color":[0,0,0,255],
		"width":1,
		"type":"esriSLS",
		"style":"esriSLSSolid"
	    }
	}
    },
    /* Convert a pair of X,Y coordinates (supplied as strings) to National Grid Reference */

    "xyToNGR": function(x, y) {
	//MT changed his mind about the grid ref format, leave this in unless he changes it again
	/*if (x.length === 6 && y.length === 6) {
	    return "TQ" + x.substring(1,4)+y.substring(1,4);
	}*/
	return "TQ"+x+","+y;
    },
    /* Write a message in the div if a deprecated browser is being used */
    "deprecationTest": function(div, version) {
	if($.browser.msie && parseInt($.browser.version) < version) {
	    // IE 7 is supported but not optimal, IE<7 is not supported
	    var message = (version === 7) ? CWLSettings.props.deprecation : CWLSettings.props.deprecationGentle;
	    Utils.writeContentAndNudgeMap(div, message); 
	}
    },
    /* Write some ajaxy content to a page with a map in it, needed a reposition for the map*/
    "writeContentAndNudgeMap": function(jqElement, content) {
	jqElement.html(content);
	map.resize();
	map.reposition();
    },
    /* show a photo in a popup window */
    "photoPopup" : function (path,title) {
	var id = new Date().getTime();
	window.open('fbx_index.cfm?fuseaction=plain.viewPhoto&path='+path+'&title='+title, 
		    'page' + id, 
		    'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=500,height=450,left = 440,top = 362');
    },
    /* get the year from a date string */
    "getYear" : function(str) {
	return str.split('/')[2];
    },
    /* returns true if two extents are equal*/
    "equalExtents" : function(e1, e2) {
	return (e1 != null && e2 != null && e1.xmin == e2.xmin 
		&& e1.xmax == e2.xmax && e1.ymin == e2.ymin && e1.ymax == e2.ymax);
    }
}

