﻿//Constants
var PopupPrefix = "POPUP";

//public varibles
var map = null;  
var pins = new Array();
var CurrentPopupID = 0;
var pinID = 0;
var zoomlevel = 0;
var layer = null;
var currentpin = null;
var currentindex = 0;   
var order = "";
var suborder = "";
var family = "";
var era = "";
var period = "";
var epoch = "";
var plot_bool = 0;

MapArgs = function(divID, center, zoomlevel, style, fixed, mode, scale) {
   /// <summary>
   ///   Virtual Earth Arguments
   /// </summary>
   /// <param name="divID">The ID of the div to create the map</param>
   /// <param name="center">The centre of the initial map view - type VELatLong</param>
   /// <param name="zoomlevel">The initial zoom level 1-19</param>
   /// <param name="style">The map style - type VEMapStyle</param>
   /// <param name="fixed">Is the map fixed = not interactive</param>
   /// <param name="mode">The map mode - type VEMapMode</param>
   /// <param name="scale">The map scale - type VEDistanceUnit </param>
   
    this.DivID = divID;
    this.Center = center;
    this.Zoomlevel = zoomlevel;
    this.Style = style;
    this.Fixed = fixed;
    this.Scale = scale;
}

var mapArgs = new MapArgs("myMap", new VELatLong(0 , 0), 2, VEMapStyle.Hybrid, false, VEMapMode.Mode3D, VEDistanceUnit.Kilometers);

//Map initialisation on page load.       
function GetMap() {        
    // Firefox support - see VE wiki.
    var ffv = 0;
    var ffn = "Firefox/"
    var ffp = navigator.userAgent.indexOf(ffn);
    if (ffp != -1) ffv = parseFloat(navigator.userAgent.substring(ffp + ffn.length));
    // If we're using Firefox 1.5 or above override the Virtual Earth drawing functions to use SVG
    if (ffv >= 1.5) {
      Msn.Drawing.Graphic.CreateGraphic = function(f,b) { return new Msn.Drawing.SVGGraphic(f,b) }
	}
    //Birdseye - fix due to not lat/long data available

    GetPinDataDelegate = null;
    PinHoverDelegate = null;
    //setup map
    map = new VEMap(mapArgs.DivID);
    map.latoffset = 0.005;
    map.lonoffset = 0.01;  
    map.MapBEyeCentre;   
    map.LoadMap(mapArgs.Center, mapArgs.Zoomlevel, mapArgs.Style, mapArgs.Fixed, VEMapMode.Mode2D); // last argument should be mapArgs.getMode but I don't have time to make that work at this moment..
    map.SetScaleBarDistanceUnit(mapArgs.Scale);
    layer = new VEShapeLayer();         
    map.AddShapeLayer(layer);    
        
    //setup the function to get new data whenever the map changes
    GetPinDataDelegate = Function.createDelegate(this, GetPinData);
    map.AttachEvent("onchangeview", GetPinDataDelegate);
        
    //turn off the standard popup and attach our custom handler
    PinHoverDelegate = Function.createDelegate(this, PinActivate);
    map.AttachEvent("onmouseover", PinHoverDelegate);
    map.AttachEvent("onclick", PinHoverDelegate);
              
    //Setup additional storage for shapes
    VEShape.prototype.Bounds = "";  
	VEShape.prototype.Drawn = false;    
	VEShape.prototype.Match = false;
	//GetPinData();    
}  

//Whenever the map view changes call the webservice for the latest data
function GetPinData() {
    if(plot_bool == 1) {
        /// <summary>
        ///   Get the latest map data from the webservice.
        /// </summary>
            
        //encode the current map bounds
        var points = new Array();
        var zoom;
        
        if (map.GetMapStyle() == VEMapStyle.Birdseye) {    
            //set zoomlevel      
            zoom = 19;
            points.push(new VELatLong(mapMapBEyeCentre.Latitude + map.latoffset, map.MapBEyeCentre.Longitude - map.lonoffset));
            points.push(new VELatLong(map.MapBEyeCentre.Latitude - map.latoffset, map.MapBEyeCentre.Longitude + map.lonoffset));
        } else {
            var view = map.GetMapView();
            points.push(view.TopLeftLatLong);
            points.push(view.BottomRightLatLong);
            
            //get zoomlevel
            zoom = map.GetZoomLevel();

            //to try to support Birsdeye we store the centre as currently there is no way to get the lat/long in birdseye :(
            map.MapBEyeCentre = map.GetCenter();

        }
        
        var bounds = Utility.createEncodings(points);
        if (map.zoomlevel != zoom) {
            //clear existing pins
            layer.DeleteAllShapes();
            map.zoomlevel = zoom;
        }
      
        //call webservice
       Paleo.MapService.GetClusteredMapData(bounds, zoom, order, suborder, family, era, period, epoch, Function.createDelegate(this, OnMapDataSucceeded), Utility.OnFailed);
    }
}

//callback when data returns from web service
function OnMapDataSucceeded(results) {             
        //decode pins
        var result = results.split(",")
        var locs = Utility.decodeLine(result[0]);
               
        //add new pins
        for(x = 0; x < locs.length; x++) {
            var loc = locs[x];
            var bounds = result[x+1];
            var drawn = false;
            
            //see if it is in the current drawn pins
            for(i = 0; i < totalpins; i++) {
               var currentshape = layer.GetShapeByIndex(i);
                if (currentshape.Bounds == bounds) {
                    drawn = true;
                    currentshape.Match = true;
                    break; //shortcut loop
                }
            }            
            
            if (!drawn) {
                var newShape = new VEShape(VEShapeType.Pushpin, loc); 
                newShape.Bounds = bounds;         
                newShape.Drawn = drawn;
                newShape.Match = true;
                newShape.SetCustomIcon("<img src='four.gif'/>");
               layer.AddShape(newShape);  
            }          
        }
        
        //remove all existing pins on matches from the screen
        var totalpins = layer.GetShapeCount();
        for(x = (totalpins-1); x >=0; x--) {
            var currentshape = layer.GetShapeByIndex(x);
            if (!currentshape.Match) {
                layer.DeleteShape(currentshape);
            }
            //set match back to false for next time we pan the map.
            currentshape.Match = false;
        }  
}

// on pin hover   
function PinActivate(e) {
  /// <summary>
	///   Receives any mouse of event from VE
	/// </summary>  
	/// <param name="e">The MapEvent object</param>         
	if (e.elementID) {
		var popupShape = map.GetShapeByID(e.elementID)
		if (popupShape) {
			//set current pin
			currentpin = popupShape;
			currentindex = 0;
			
			//get the content for the pin.
			getAJAXContent();
			currentpin.SetDescription("<div id='" + PopupPrefix + currentpin.GetID() + "' style=\"font-weight:bold;\">Loading...</div>");
			currentpin.SetTitle("");
		}
	}
}


function getAJAXContent(ID, bounds, startIndex) {  
    Paleo.MapService.GetPushPin(currentpin.Bounds, currentindex, order, suborder, family, era, period, epoch, Function.createDelegate(this, OnContentSucceeded), Utility.OnFailed, currentpin.GetID());
}


//Receive content for popup
function OnContentSucceeded(result, ID) { 
    /// <summary>
	///   Receive content for popup.
	/// </summary>  
	/// <param name="result">The webservice result object - JSON PinData</param>  
	/// <param name="ID">The popup ID associated with this call</param>  
		
	//verify this is the data for the current popup.
	// alert("contentsuceeded");
	if (ID == currentpin.GetID()) {
		if (map.GetMapMode() == VEMapMode.Mode3D) {
			//3D mode fails to be able to retrieve the div we placed earlier so resort to setting the title and description only
			currentpin.SetTitle(result.Title);
			currentpin.SetDescription(result.Details);
		} else {
			//create the content element
			var el = document.createElement("div");
			el.innerHTML = (currentindex + 1) + " of " + result.TotalRecords + " Records<br />" + "<br/>" + " Name = " + result.Details + ";";
			PrintRecords(result);
			//clear loading and attach the content
			$get(PopupPrefix + ID).innerHTML = "";
			$get(PopupPrefix + ID).appendChild(el);
			
			if (result.TotalRecords > 1) {
				//prev / next functionality
				var prevButton = document.createElement("div");
				prevButton.innerHTML = "Previous";
				el.appendChild(prevButton);
				Sys.UI.DomElement.addCssClass(prevButton, "ActionButton");
				if (currentindex > 0) {  
					$addHandler(prevButton,"click",Function.createDelegate(this, PreviousRecord));      
				}else {
					Sys.UI.DomElement.addCssClass(prevButton, "ButtonDisabled");
				}
				var nextButton = document.createElement("div");
				nextButton.innerHTML = "Next";
				el.appendChild(nextButton);  
				Sys.UI.DomElement.addCssClass(nextButton, "ActionButton");
				if (currentindex < (result.TotalRecords-1)) {  
					$addHandler(nextButton,"click",Function.createDelegate(this, NextRecord));                         
				}else {
					Sys.UI.DomElement.addCssClass(nextButton, "ButtonDisabled");
				}
			}              
		}
	}
}

function PrintRecords(result) {    
  var div = document.getElementById("output1");
  div.innerHTML = " <h2>Detailed Chiton Information</h2>";
  div.innerHTML += "ID = " + result.Title + "<br />";
  div.innerHTML += "Name = " + result.Details + "<br />";
  div.innerHTML += "Era = " + result.Era + "<br />";
  div.innerHTML += "Period = " + result.Period + "<br />";
  div.innerHTML += "Epoch = " + result.Epoch + "<br />";
  div.innerHTML += "Class = " + result.Class + "<br />";
  div.innerHTML += "Order = " + result.Order + "<br />";
  div.innerHTML += "Suborder = " + result.Suborder + "<br />";
  div.innerHTML += "Family = " + result.Family + "<br />";
  div.innerHTML += "Genus = " + result.Genus + "<br />";
  div.innerHTML += "Species = " + result.Species + "<br />";  
}

function PreviousRecord() {
	/// <summary>
	///   Request the previous record.
	/// </summary>  
	currentindex--;
	$get(PopupPrefix + currentpin.GetID()).innerHTML = "Loading...";
	getAJAXContent();
}

function NextRecord() {
	/// <summary>
	///   Request the next record.
	/// </summary>      
	currentindex++;
	$get(PopupPrefix + currentpin.GetID()).innerHTML = "Loading...";
	getAJAXContent();
}

// This is the failed callback function for all webservices.
function OnFailed(error) {
    var stackTrace = error.get_stackTrace();
    var message = error.get_message();
    var statusCode = error.get_statusCode();
    var exceptionType = error.get_exceptionType();
    var timedout = error.get_timedOut();
   
    // Display the error.    
    var RsltElem = 
        "Stack Trace: " +  stackTrace + "<br/>" +
        "Service Error: " + message + "<br/>" +
        "Status Code: " + statusCode + "<br/>" +
        "Exception Type: " + exceptionType + "<br/>" +
        "Timedout: " + timedout;
        
        alert(RsltElem);
}

//Clean up all objects
function Dispose() {
	/// <summary>
	///   cleans up all objects. Detaches all events.
	/// </summary>
	if (map != null) {
		map.DetachEvent("onchangeview",GetPinDataDelegate);
		map.DetachEvent("onmouseover", PinHoverDelegate);
		map.DetachEvent("onclick", PinHoverDelegate);	
	    map.GetPinDataDelegate = null;
	    map.PinHoverDelegate = null; 
	    	
	    //Birdseye
	    map.MapBEyeCentre = null;  
	    map.latoffset = null;
	    map.lonoffset = null;  
	    
		map.Dispose();
	}    
	service = null;
	mapArgs = null;
	
	map = null;
	pinID = null;
	zoomlevel = null;
	layer = null;
	
	//popup specific
	PopupPrefix = null;
	currentpin = null;
	currentindex = null;  
}

function plot() {
	plot_bool = 1;
	var select1 = document.getElementById("DropDownList1");
	order = select1.options[select1.selectedIndex].value;
	var select2 = document.getElementById("DropDownList2");
	suborder = select2.options[select2.selectedIndex].value;
	var select3 = document.getElementById("DropDownList3");
	family = select3.options[select3.selectedIndex].value;
	var select4 = document.getElementById("DropDownList4");
	era = select4.options[select4.selectedIndex].value;
	var select5 = document.getElementById("DropDownList5");
	period = select5.options[select5.selectedIndex].value;
	var select6 = document.getElementById("DropDownList6");
	epoch = select6.options[select6.selectedIndex].value;
	GetPinData();
}

function remove() {
	plot_bool = 0;
	layer.DeleteAllShapes();  
}   
    
//set map to run onload and dispose on exit
if (window.attachEvent) {
	window.attachEvent("onload", GetMap);
	window.attachEvent("onunload", Dispose);	
} else {
	window.addEventListener("load", GetMap, false);
	window.addEventListener("unload", Dispose, false);
}

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
