var map, tiledMapServiceLayer, featureLayer;
var popupTemplate;
var currentYear = '11/12';

var gradeLinks = new Array();
gradeLinks['Very poor'] = 'http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx#v.poor';
gradeLinks['Poor'] = 'http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx#poor';
gradeLinks['Fair'] = 'http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx#fair';
gradeLinks['Good'] = 'http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx#v.good';
gradeLinks['Very good'] = 'http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx#good';
gradeLinks['Insufficient data'] = 'http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx';
gradeLinks['Not graded'] = 'http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx';
gradeLinks['Warning'] = 'http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx';

function init() {
    $("#siteGraph2").dialog({ autoOpen: false, closeOnEscape: true, width: 430, position: 'center', resizable: false });

    // Set Zoom Symbol
    var zoomSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([20, 156, 255]), 1), new dojo.Color([141, 185, 219, 0.3]));
    esriConfig.defaults.map.zoomSymbol = zoomSymbol.toJson();

    // Set initial extent
    var initialExtent = new esri.geometry.Extent({ "xmin": 18786242, "ymin": -5619497, "xmax": 19463168, "ymax": -5187657, "spatialReference": { "wkid": 102100} });

    // Define custom popup options 
    var popupOptions = {
        'markerSymbol': new esri.symbol.SimpleMarkerSymbol('circle', 32, null, new dojo.Color([0, 0, 0, 0.25])),
        'marginLeft': '20',
        'marginTop': '20'
    };
    //create a popup to replace the map's info window 
    var popup = new esri.dijit.Popup(popupOptions, dojo.create("div"));

    // Create the map
    map = new esri.Map("map", { extent: initialExtent, slider: true, logo: false, infoWindow: popup });

    // Add a resize event to the map
    dojo.connect(map, 'onLoad', function (map) {
        //resize the map when the browser resizes 
        dojo.connect(dijit.byId('map'), 'resize', map, map.resize);
    });

    dojo.connect(map, "onExtentChange", function (extent) {
        // Check and enable the labels layer visibility
        var mapLevel = map.getLevel();
        if (mapLevel < 12 && labelLayer.visible == true) {
            labelLayer.hide();
        }
        else if (mapLevel >= 12 && labelLayer.visible == false) {
            labelLayer.show();
        }
    });

    // Create the popup template object
    popupTemplate = new esri.InfoTemplate();

    // Add the base map
    //Creates the Virtual Earth layer to add to the map
    veTileLayer = new esri.virtualearth.VETiledLayer({
        bingMapsKey: 'As0fh04cRgwAgd2NcZhB7cR45JFXQDdDGt2gAXGzRmDWlzRnmQ_wbwVIenkxgI71',
        mapStyle: esri.virtualearth.VETiledLayer.MAP_STYLE_ROAD
    });
    map.addLayer(veTileLayer);
	
	// Add the water areas layer to the map
	//var imageParameters = new esri.layers.ImageParameters(); 
	//imageParameters.layerIds = [1]; 
	//imageParameters.layerOption = esri.layers.ImageParameters.LAYER_OPTION_SHOW; 
	//imageParameters.transparent = true; 
	 
	//var dynamicMapServiceLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://gis.ecan.govt.nz/ArcGIS/rest/services/Public/SwimmingWaterQuality/MapServer", {"imageParameters":imageParameters}); 
	//map.addLayer(dynamicMapServiceLayer);  

    // Add graphics layer for labels
    var labelLayer = new esri.layers.GraphicsLayer();
    map.addLayer(labelLayer);

    // Add the feature layer for the results
    featureLayer = new esri.layers.FeatureLayer("http://gis.ecan.govt.nz/ArcGIS/rest/services/Public/SwimmingWaterQuality/MapServer/0", {
        mode: esri.layers.FeatureLayer.MODE_SNAPSHOT,
        outFields: ["SITE_ID", "DISPLAY_NAME", "AREA_CODE", "SITE_TYPE", "SITE_GRADE", "RAIN_AFFECTED", "SITE_NOT_SAMPLED", "WARNING_TEXT", "NOTE_TEXT", "DISPLAY_AREA_NAME", "MODIFIEDDATE", "SITE_SAMPLE_TYPE", "NZTMX", "NZTMY", "DISPLAY_GRADE"]
    });

    dojo.connect(featureLayer, "onUpdateEnd", function (error) {
        // Get the regions list
        var regions = getRegionsList();
        $.each(regions, function (index, value) {
            $('#regionList').append(("<p><a style='padding:0px; background-color:#ffffff; color:#000; text-decoration:underline;' href='javascript:void(0);' id='region{areacode}' >{areaname}</a></p>")
                            .replace("{areacode}", value.code)
                            .replace("{areaname}", value.name));

            $('#region' + value.code).click(function () {
                showRegionSites(value.code);
            });
        });

        // Iterate through the features and get the warnings and add the label graphic
        var items = [];
        var font = new esri.symbol.Font("8pt", esri.symbol.Font.STYLE_NORMAL, esri.symbol.Font.VARIANT_NORMAL, esri.symbol.Font.WEIGHT_NORMAL, 'Serif');
        $.each(featureLayer.graphics, function (index, feature) {
            // Check for a 
            if (feature.attributes.WARNING_TEXT != '') {
                items.push(feature);
            }

            // Add the label - the label colour is controlled by the 'dojo.Color...' section
            var textSymbol = new esri.symbol.TextSymbol(formatLabel(feature.attributes.DISPLAY_NAME, 25),
                        font, new dojo.Color([150, 0, 0])); 
            textSymbol.setAlign(esri.symbol.TextSymbol.ALIGN_END);
            textSymbol.setOffset(-10, 2);
            var labelPointGraphic = new esri.Graphic(feature.geometry, textSymbol);
            labelLayer.add(labelPointGraphic);
        });

        // Populate the warnings list
        if (items.length > 0) {
            $.each(items, function (index, value) {
                // Get the date and apply timezone difference
                var d = new Date(value.attributes.MODIFIEDDATE);
                d.setMinutes(d.getMinutes() + d.getTimezoneOffset());

                $('#warningList').append(("<li><a href='javascript:void(0);' id='warn{site}' >{sitename}</a>: {warningtext}<br/> <span class='warnUpdate'>Last Updated: {modifieddate}</span></li>")
                            .replace("{site}", value.attributes.SITE_ID)
                            .replace("{sitename}", value.attributes.DISPLAY_NAME)
                            .replace("{warningtext}", value.attributes.WARNING_TEXT)
                            .replace("{modifieddate}", d.toLocaleString()));

                $('#warn' + value.attributes.SITE_ID).click(function () {
                    showSite(value.attributes.SITE_ID);
                });
            });

            // Show the warnings dialog
            $('#warnings').removeClass("hideMessage").addClass("warningMessageShown");
        }
        else {
            $('#warnings').empty();
        }
    });

    dojo.connect(featureLayer, "onClick", function (evt) {
        var site = getSiteByPoint(evt.mapPoint);

        if (site) {
            showSite(site.attributes.SITE_ID);
        }
    });

    // Add the sites layer to the map
    map.addLayer(featureLayer);
}

function showSite(site_id) {
    var site = getSite(site_id);
    if (site) {
        // Set the info window content
        map.infoWindow.setContent(getTextContent(site));

        // Show the info window
        map.infoWindow.show(site.geometry);

        // Zoom to this location
        map.centerAt(site.geometry);
    }
}

function getTextContent(graphic) {
    var content = "<div style='width: 100%; height: 100%;' id='pop'>";

    //content += "<div id='popclose'><a href='javascript:HideWin()'>x</a></div>";
    content += "<div id='popclose' style='float:right;'><a href='javascript:void(0)' onclick='map.infoWindow.hide();'>x</a></div>";
	
	// Check for warning content
    if (graphic.attributes.WARNING_TEXT != '') {
        content += "<div class='warningText'>" + graphic.attributes.WARNING_TEXT + "</div>"
    }

    // Set the display name content - Add the legend item and grade
    if (graphic.attributes.SITE_GRADE == 'Warning') {
        content += "<div class='popupDescription " +
                graphic.attributes.SITE_GRADE + "'><img alt='" + graphic.attributes.SITE_GRADE + "' src='" +
                getSiteLegendImage(graphic.attributes.SITE_ID) + "' style='float:left;' />" + graphic.attributes.DISPLAY_NAME + "  " +
                graphic.attributes.SITE_GRADE + "</span></a></div>";
    } else {
        content += "<div class='popupDescription " +
                graphic.attributes.SITE_GRADE + "'><img alt='" + graphic.attributes.SITE_GRADE + "' src='" +
                getSiteLegendImage(graphic.attributes.SITE_ID) + "' style='float:left;' />" + graphic.attributes.DISPLAY_NAME + " is  " +
                graphic.attributes.SITE_GRADE + "</span></a></div>";
    }

    //content += "<div class='popupDescription'><strong>" + graphic.attributes.DISPLAY_NAME + "</strong> swimming conditions, based on risk of faecal contamination and water testing for faecal indicator bacteria, are</div>";


    // Check for rain affected 
    if (graphic.attributes.RAIN_AFFECTED == 'Y') {
        content += "<p class='rainWarning'>May be unsuitable for swimming for up to 48 hours after rainfall.</p>"
    }

    // Check for site not sampled
    if (graphic.attributes.SITE_NOT_SAMPLED == 'Y') {
        content += "<p class='siteNotSampled'>This site is not being sampled during the " + currentYear + " season.</p>"
    }

    // Check for notes
    if (graphic.attributes.NOTE_TEXT != '' && graphic.attributes.NOTE_TEXT != null) {
        content += "<p class='popupNoteText'>" + graphic.attributes.NOTE_TEXT + "</p>"
    }

    // Add show samples graph button if Grade != 'Warning'
	if (graphic.attributes.SITE_GRADE != 'Warning')
	{
		content += "<div id='siteGraph' class='popupSection'><button id='showReadings' onclick='showGraph()'>Show Sampling History</button></div>";
		setGraph(currentYear, graphic.attributes.SITE_ID);
		content+="<div class='pintro'><strong>" + "This grade is based on risk of faecal contamination and water testing for faecal indicator bacteria.</div>"
		content += "<div class='pgrade'><a href='http://ecan.govt.nz/services/online-services/monitoring/swimming-water-quality/Pages/swimming-water-quality-grades.aspx#'" + gradeLinks[graphic.attributes.SITE_GRADE] + "' target='_blank' title='Click to view a description of this grade' ><span style='height: 100%; display:inline-block; vertical-align:middle'>Find out what this grade means.</a></div>"
	}

    return content + '</div>';
}

function formatLabel(value, maxLength) {
    var words = value.split(" ");
    var label = "";
    var lineLength = 0;
    $.each(words, function (index, word) {
        var wordLength = word.length;
        if (lineLength + wordLength < maxLength || lineLength == 0) {
            label += word + " ";
            lineLength += wordLength;
        } else {
            label += "\n" + word + " ";
            lineLength = wordLength;
        }
    });
    return label;
}

function getSiteLegendImage(site_id) {
    var legimg;
    
	if (site_id)
	{
		var site = getSite(site_id);
		if (site) {
			$.each(featureLayer.renderer.infos, function (index, info) {
				if (info.value == site.attributes.DISPLAY_GRADE) {
					console.log(info.value);
					legimg = info.symbol.url;
				}
			});
		}
	}
	else
	{
		// Assume a warning - get the warning icon
		$.each(featureLayer.renderer.infos, function (index, info) {
			if (info.value == "Warning") {
				console.log(info.value);
				legimg = info.symbol.url;
			}
		});		
	}
	return legimg;
}

function showRegionSites(areacode) {
    // Get the sites in this region
    var items = getSitesByRegion(areacode);

    // Sort by name
    items.sort(SortByDisplayName);

    $('#sitesMessage').html("Click on a site in this list or on the map to see its grade details :");

    // Clear the site list
    $('#sitesList').empty();

    if (items.length > 0) {
			$('#sites').css("height","400px");
			$('#sites').css("overflow","scroll");
        // Generate the sites list
        $.each(items, function (index, feature) {
            var siteitem = "<div class='siteItem'><a class='linkListGrade' href='{gradedesclink}' target='_blank'><img src='{legendimage}' alt='{sitegrade}' /></a><a href='javascript:void(0);' id='site{site}' title='Click to view site details' >{sitename}</a></div>"
            $('#sitesList').append((siteitem)
                .replace("{site}", feature.attributes.SITE_ID)
                .replace("{sitename}", feature.attributes.DISPLAY_NAME)
                .replace("{sitegrade}", feature.attributes.SITE_GRADE)
                .replace("{legendimage}", getSiteLegendImage(feature.attributes.SITE_ID))
                .replace("{gradedesclink}", gradeLinks[feature.attributes.SITE_GRADE]));

            $('#site' + feature.attributes.SITE_ID).click(function () {
                showSite(feature.attributes.SITE_ID);
            });
        });

        // Set the map extent
        var ext = getPointCollectionExtent(items).expand(1.25)
        map.setExtent(ext);
        /*
        if (map.extent.contains(ext) == false) {
           map.setLevel(map.getLevel() - 1);
        }
        */
    } else {
        $('#sites').html('<p>No site details avilable for this region.<p>');
    }
}

function getSitesByRegion(areacode) {
    var items = [];
    $.each(featureLayer.graphics, function (index, feature) {
        if (feature.attributes.AREA_CODE == areacode) {
            items.push(feature);
        }
    });
    return items;
}

function getSite(site_id) {
    var site;
    $.each(featureLayer.graphics, function (index, feature) {
        if (feature.attributes.SITE_ID == site_id) {
            site = feature;
        }
    });
    return site;
}

function getSiteByPoint(mapPoint) {
    var site;
    if (mapPoint) {
        // Generate an extent
        var ext = pointToExtent(map, mapPoint, 10);

        // Iterate though and get the first intersecting graphic
        $.each(featureLayer.graphics, function (index, feature) {
            if (ext.contains(feature.geometry) && site == undefined) {
                site = feature;
            }
        });
    }
    return site;
}

function getRegionsList() {
    var items = [];
    // Get the unique list of regions
    $.each(featureLayer.graphics, function (index, feature) {
        var area = { code: feature.attributes.AREA_CODE, name: feature.attributes.DISPLAY_AREA_NAME, sortcode: feature.attributes.NZTMY };
        if (regionlistContains(area, items) != true) {
            items.push(area);
        }
    });

    // Sort the list
    items.sort(SortBySortCode);

    return items;
}

function setGraph(gyear, site_id) {
    // Update the dialog title
    $("#siteGraph2").dialog("option", "title", 'Sample history for site ' + site_id + ' (' + gyear + ')');

    // Apply the 
    var contentGraphTop = "<p class='graphtext'>Please use the grade rather than this graph to find out whether a swimming site is suitable for swimming. Please note the numbers on the vertical or y axis are logarithmic which means concentrations increase ten fold for each horizontal line.</p>"
    var contentGraphBelow = "<p class='graphtext'>Green vertical bars in the graphs show the concentration of indicator bacteria measured in the water on particular days. The actual value is shown above the bar. The red line is the action level, above which the water is not suitable for swimming. " +
    "When concentrations are above the red line specific actions are undertaken by the organisations involved in swimming water quality monitoring.</p>";

    $('#siteGraph2').load("/WaterQuality/WaterQualityGraph.aspx?site_id=" + site_id + "&year=" + gyear, function () {
        $("#siteGraph2").prepend(contentGraphTop).append(contentGraphBelow);
    });
}

function changegraph(gyear, siteid) {
    setGraph(gyear.value, siteid);
}

function showGraph() {
    $("#siteGraph2").dialog('open');
}

/* ----------------------------------------
Sort functions 
---------------------------------------- */

function SortBySortCode(a, b) {
    var aName = a.sortcode;
    var bName = b.sortcode;
    return ((aName > bName) ? -1 : ((aName < bName) ? 1 : 0));
}

function SortByDisplayName(a, b) {
    var aName = a.attributes.DISPLAY_NAME.toLowerCase();
    var bName = a.attributes.DISPLAY_NAME.toLowerCase();
    return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
}


function regionlistContains(region, array) {
    var found = false;
    $.each(array, function (index, value) {
        if (value.code == region.code && value.name == region.name) {
            found = true;

            // Check if sort order value is higher than the current value
            if (value.sortcode < region.sortcode) {
                value.sortcode = region.sortcode;
            }
        }
    });
    return found;
}

function getPointCollectionExtent(items) {
    var xmin, xmax, ymin, ymax;

    // Iterate through each graphic
    $.each(items, function (index, feature) {
        if (index == 0) {
            xmin = feature.geometry.x;
            xmax = feature.geometry.x;
            ymin = feature.geometry.y;
            ymax = feature.geometry.y;
        } else {
            if (feature.geometry.x < xmin) {
                xmin = feature.geometry.x;
            }

            if (feature.geometry.x > xmax) {
                xmax = feature.geometry.x;
            }

            if (feature.geometry.y < ymin) {
                ymin = feature.geometry.y;
            }

            if (feature.geometry.y > ymax) {
                ymax = feature.geometry.y;
            }
        }
    });

    if (xmin == xmax) {
        xmin -= 10000;
        xmax += 10000;
    }

    if (ymin == ymax) {
        ymin -= 10000;
        ymax += 10000;
    }

    return new esri.geometry.Extent(xmin, ymin, xmax, ymax, map.spatialReference);
}

function pointToExtent(map, point, toleranceInPixel) {
    var pixelWidth = map.extent.getWidth() / map.width;
    var toleraceInMapCoords = toleranceInPixel * pixelWidth;
    return new esri.geometry.Extent(point.x - toleraceInMapCoords,
                    point.y - toleraceInMapCoords,
                    point.x + toleraceInMapCoords,
                    point.y + toleraceInMapCoords,
                    map.spatialReference);
}

function hideWarnings() {
    if ($('#warnings').hasClass("warningMessageShown")) {
        $('#warnings').removeClass("warningMessageShown").addClass("warningMessageHidden");
		$(btn).html('&rsaquo;&rsaquo;');
    }
    else {
        $('#warnings').removeClass("warningMessageHidden").addClass("warningMessageShown");
		$(btn).html('&lsaquo;&lsaquo;');
    }
}
//jquery accordian menu Copyright 2007-2010 by Marco van Hylckama Vlieg  
jQuery.fn.initMenu = function() {  
    return this.each(function(){
        var theMenu = $(this).get(0);
        $('.acitem', this).hide();
        $('li.expand > .acitem', this).show();
        $('li.expand > .acitem', this).prev().addClass('active');
        $('li a', this).click(
            function(e) {
                e.stopImmediatePropagation();
                var theElement = $(this).next();
                var parent = this.parentNode.parentNode;
                if($(parent).hasClass('noaccordion')) {
                    if(theElement[0] === undefined) {
                        window.location.href = this.href;
                    }
                    $(theElement).slideToggle('normal', function() {
                        if ($(this).is(':visible')) {
                            $(this).prev().addClass('active');
                        }
                        else {
                            $(this).prev().removeClass('active');
                        }    
                    });
                    return false;
                }
                else {
                    if(theElement.hasClass('acitem') && theElement.is(':visible')) {
                        if($(parent).hasClass('collapsible')) {
                            $('.acitem:visible', parent).first().slideUp('normal', 
                            function() {
                                $(this).prev().removeClass('active');
                            }
                        );
                        return false;  
                    }
                    return false;
                }
                if(theElement.hasClass('acitem') && !theElement.is(':visible')) {         
                    $('.acitem:visible', parent).first().slideUp('normal', function() {
                        $(this).prev().removeClass('active');
                    });
                    theElement.slideDown('normal', function() {
                        $(this).prev().addClass('active');
                    });
                    return false;
                }
            }
        }
    );
});
};

$(document).ready(function() {$('.menu').initMenu();});


