/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("Cted");

Cted.MapBehavior = function(element) {
    Cted.MapBehavior.initializeBase(this, [element]);
    this._Map = null;
    this._InitialLatitude = 0.0;
    this._InitialLongitude = 0.0;
    this._MapZoom = 1;
    this.shapeLayerArray = null;
    this.shapeLayerPointsArray = null;
    this._BUSINESS = 3; //Corresponds to LocationType.cs enumuration value for buisness listing
}
Cted.MapBehavior.prototype = {
	initialize: function() {
		Cted.MapBehavior.callBaseMethod(this, "initialize");
		document.getElementById("myMap").style.display = "block";
		if (!this._Map) {
			this._Map = new VEMap('myMap'); //this map id is declared in Map.cs
		}
		this._Map.SetDashboardSize(VEDashboardSize.Tiny);



		//VEMap.LoadMap parameters: VELatLong, zoom, style, fixed, mode, showSwitch, tileBuffer
		this._Map.LoadMap(
            new VELatLong(this.get_InitialLatitude(), this.get_InitialLongitude())
            , this.get_Zoom()
            , VEMapStyle.Road
            , 0
            , VEMapMode.Mode2D
            , 0
            , 0);

		if (this.get_Byway()) {
			if (this.get_Byway().WaypointList.length != 0) {
				this.AddBywayRoute();
			}
		}

		if (this.get_MapPinList()) {
			this.AddMapPinsToMap();

		}
		this._addMapLayerEventHandlers();

		//add zoom buttons
		//        this._Map.HideDashboard();
		//        this._zoomInButton = document.createElement('input');
		//        this._zoomInButton.setAttribute('id', 'mapzoominbutton');
		//        this._zoomInButton.setAttribute('type', 'button');
		//        this._zoomInButton.setAttribute('class', 'mapzoominbutton');

		//        var zoomInEventDelegate = Function.createDelegate(this, this.ZoomInMap);
		//        this._zoomInButton.attachEvent("onclick", zoomInEventDelegate);
		//        this._Map.AddControl(this._zoomInButton);

		//        //This must be called after loaded in map control or
		//        //virtual easrth will over write this information
		//        this._zoomInButton.style.position = 'absolute';
		//        this._addShim(this._zoomInButton, 1);

		//        this._zoomOutButton = document.createElement('input');
		//        this._zoomOutButton.setAttribute('id', 'mapzoomoutbutton');
		//        this._zoomOutButton.setAttribute('type', 'button');
		//        this._zoomOutButton.setAttribute('class', 'mapzoomoutbutton');

		//        var zoomOutEventDelegate = Function.createDelegate(this, this.ZoomOutMap);
		//        this._zoomOutButton.attachEvent("onclick", zoomOutEventDelegate);
		//        this._Map.AddControl(this._zoomOutButton);

		//        //This must be called after loaded in map control or
		//        //virtual easrth will over write this information
		//        this._zoomOutButton.style.position = 'absolute';
		//        this._addShim(this._zoomInButton, 2);
	},


	_addShim: function(customMapControl, id) {	//taken from VE documentation: http://msdn.microsoft.com/en-us/library/bb412435.aspx used for custom map zoom buttons
		var shim = document.createElement("iframe");
		shim.id = "myShim" + id;
		shim.frameBorder = "0";
		shim.style.position = "absolute";
		shim.style.zIndex = "1";
		shim.style.top = customMapControl.offsetTop;
		shim.style.left = customMapControl.offsetLeft;
		shim.width = customMapControl.offsetWidth;
		shim.height = customMapControl.offsetHeight;
		customMapControl.shimElement = shim;
		customMapControl.parentNode.insertBefore(shim, customMapControl);
	},

	dispose: function() {
		this._removeMapLayerEventHandlers();
		Cted.MapBehavior.callBaseMethod(this, "dispose");
	},
	_addMapLayerEventHandlers: function() {
		if (this.get_MapLayerEvents()) {
			if (this._MapLayerEventsDelegates == null)
				this._MapLayerEventsDelegates = [];

			for (var i = 0; i < this.get_MapLayerEvents().length; i++) {
				var event = (this.get_MapLayerEvents()[i].Event == Cted.MapLayerEvents.Click) ? 'click' : '';

				this._MapLayerEventsDelegates[i] = Function.createDelegate(this, Function.createCallback(this.ShowLayer, { layer: this.get_MapLayerEvents()[i].Layer }));

				if ($get(this.get_MapLayerEvents()[i].ControlID) != null) {
					$addHandler($get(this.get_MapLayerEvents()[i].ControlID), event, this._MapLayerEventsDelegates[i]);
				}
			}
		}
	},
	_removeMapLayerEventHandlers: function() {
		if (this.get_MapLayerEvents() && this._MapLayerEventsDelegates != null) {
			for (var i = 0; i < this.get_MapLayerEvents().length; i++) {
				var event = (this.get_MapLayerEvents()[i].Event == Cted.MapLayerEvents.Click) ? 'click' : '';

				if ($get(this.get_MapLayerEvents()[i].ControlID) != null) {
					$removeHandler($get(this.get_MapLayerEvents()[i].ControlID), event, this._MapLayerEventsDelegates[i]);
				}
			}
		}
	},
	ZoomInMap: function() {
		this._Map.ZoomIn();
	},
	ZoomOutMap: function() {
		this._Map.ZoomOut();
	},
	AddBywayRoute: function() {
		var waypointList = this.get_Byway().WaypointList;
		var waypointArray = new Array();
		for (var i = 0; i < waypointList.length; i++) {
			var latitude = waypointList[i].Latitude;
			var longitude = waypointList[i].Longitude;
			waypointArray[i] = new VELatLong(latitude, longitude);
		}

		var options = new VERouteOptions;
		options.ShowDisambiguation = false;
		options.RouteColor = new VEColor(153, 51, 0, 0.9);
		options.RouteWeight = 3;

		var thisMapControl = this;
		options.RouteCallback = function(route) {
			thisMapControl.OnRouteCallback(route);
		}

		this._Map.GetDirections(waypointArray, options);
	},
	OnRouteCallback: function(route) {
		//This algorithm removes all the pins on the route:
		var legs = route.RouteLegs;
		var leg = null;
		var shape = null;

		for (var i = 0; i < legs.length; i++) {
			leg = legs[i];
			for (var j = 0; j < leg.Itinerary.Items.length; j++) {
				this._Map.DeleteShape(leg.Itinerary.Items[j].Shape);
			}
		}
	},
	AddMapPinsToMap: function() {
		this.shapeLayerArray = [];

		for (i = this.get_MapPinList().length - 1; i > -1; i--) {
			var layer = this.get_MapPinList()[i].Layer;

			if (this.shapeLayerArray[layer] == null) {
				this.shapeLayerArray[layer] = new VEShapeLayer();
			}

			var shape = new VEShape
                (
                    VEShapeType.Pushpin
                    , new VELatLong
                        (
                            this.get_MapPinList()[i].Latitude
                            , this.get_MapPinList()[i].Longitude
                        )
                );

			var mapPinNumber = this.get_MapPinList()[i].Number;
			var mapPinCssClass = "mappin";

			if (this.get_MapPinList()[i].IsActiveLocation) {
				mapPinNumber = "";
				mapPinCssClass = "featuredlocationpin";
			}
			shape.SetCustomIcon("<div class='" + mapPinCssClass + "'><div class='text'></div><span><em>" + mapPinNumber + "</em></span></div>");

			shape.SetDescription(this.GenerateDescriptionHtml(this.get_MapPinList()[i]));
			this.shapeLayerArray[layer].AddShape(shape);
		}

		for (var i = 0; i < this.shapeLayerArray.length; i++) {
			// initially show the first layer
			if (i != 0)
				this.shapeLayerArray[i].Hide();

			if (this.shapeLayerArray[i] != null) {
				this._Map.AddShapeLayer(this.shapeLayerArray[i]);
			}
		}
		if (this.get_MapLayerToBeShown() >= 0 && this.get_MapLayerToBeShown() < this.shapeLayerArray.length) {
			this.shapeLayerArray[0].Hide();
			this.shapeLayerArray[this.get_MapLayerToBeShown()].Show();
			this.CalculateZoomAspectRatio(this.get_MapLayerToBeShown());
		}
		else {
			this.CalculateZoomAspectRatio(0);
		}
	},
	GenerateDescriptionHtml: function(mapPin) {
		var descriptionMarkup = '';

		if (mapPin.PhotoUrl != null) {
			descriptionMarkup += '<div class="mappopupaddresswithphoto">';

			if (mapPin.MoreInformationUrl != null) {

				descriptionMarkup += '<a class="mappopupphotoanchor" href="' + mapPin.MoreInformationUrl + '"><image class="mappopupphoto" src="' + mapPin.PhotoUrl + '"/></a>';
			}

			else {
				descriptionMarkup += '<image class="mappopupphoto" src="' + mapPin.PhotoUrl + '"/>';
			}

		}
		else {
			descriptionMarkup += '<div class="mappopupaddresswithoutphoto">';
		}
		if (mapPin.Title != null) {

			if (mapPin.MoreInformationUrl != null) {


				descriptionMarkup += '<a class="mappopuptitleanchor" href="' + mapPin.MoreInformationUrl + '"><h3 class="mappopuptitle">' + mapPin.Title + '</h3></a>';
			}
			else {
				descriptionMarkup += '<h3 class="mappopuptitle">' + mapPin.Title + '</h3>';
			}


		}

		if (mapPin.StreetAddress1 != null && mapPin.StreetAddress1 != "") {
			descriptionMarkup += mapPin.StreetAddress1 + '<br />';
		}
		if (mapPin.StreetAddress2 != null && mapPin.StreetAddress2 != "") {
			descriptionMarkup += +mapPin.StreetAddress2 + '<br />';
		}
		if (mapPin.CityName != null && mapPin.State != null && mapPin.PostalCode != null) {
			descriptionMarkup += mapPin.CityName + ', ' + mapPin.State + ' ' + mapPin.PostalCode + '<br />';
		}
		if (mapPin.PhoneNumber != null && mapPin.PhoneNumber != "") {
			descriptionMarkup += 'Phone: ' + mapPin.PhoneNumber + '<br />';
		}
		if (mapPin.TollFreePhoneNumber != null && mapPin.TollFreePhoneNumber != "") {
			descriptionMarkup += 'Toll-Free: ' + mapPin.TollFreePhoneNumber + '<br />';
		}
		descriptionMarkup += '<br />' + '</div>';
		descriptionMarkup += '<div class="mappopupdescription"';
		if (mapPin.Description != null) {
			descriptionMarkup += '<p>' + mapPin.Description + '</p>';
		}
		descriptionMarkup += '</div>';


		//Generate the More Information | Email | Website panel:
		var needSpacer = false;


		descriptionMarkup += '<div class="mappopupaddresswithoutphoto">';
		descriptionMarkup += '<span>';
		if (mapPin.MoreInformationUrl != null && mapPin.MoreInformationUrl != "") {
			descriptionMarkup += '<a href="' + mapPin.MoreInformationUrl + '" >More Information</a>';
			needSpacer = true;
		}
		//Nasty if bellow is used to enforce business rule
		if (
            (mapPin.EntityType == this._BUSINESS)
                &&
            (mapPin.PhotoUrl != null && mapPin.PhotoUrl != "")
                &&
            (mapPin.WebsiteUrl != null && mapPin.WebsiteUrl != "")
            ) {
			if (mapPin.Email != null && mapPin.Email != "") {
				if (needSpacer == true) {
					descriptionMarkup += ' | ';

				}
				descriptionMarkup += '<a href="mailto:' + mapPin.Email + '" >Email</a>';
			}

			if (needSpacer) {
				descriptionMarkup += ' | ';
			}
			var httpFromUrl = mapPin.WebsiteUrl.substring(0, 4);
			if (httpFromUrl != 'http') {
				descriptionMarkup += '<a href="http://' + mapPin.WebsiteUrl + '" >Website</a>';
			}
			else {
				descriptionMarkup += '<a href="' + mapPin.WebsiteUrl + '" >Website</a>';
			}
		}
		descriptionMarkup += '</span>';
		descriptionMarkup += '</div>';

		return descriptionMarkup;
	},
	CalculateZoomAspectRatio: function(layer) {
		if (this.shapeLayerPointsArray == null)
			this.shapeLayerPointsArray = [];

		if (this.shapeLayerArray.length != 0) {
			if (this.shapeLayerPointsArray[layer] == null) {
				var lowLat, highLat, lowLong, highLong;

				for (var i = 0; i < this.shapeLayerArray[layer].GetShapeCount(); i++) {
					if (i == 0) {
						lowLat = this.shapeLayerArray[layer].GetShapeByIndex(0).GetPoints()[0].Latitude;
						highLat = this.shapeLayerArray[layer].GetShapeByIndex(0).GetPoints()[0].Latitude;
						lowLong = this.shapeLayerArray[layer].GetShapeByIndex(0).GetPoints()[0].Longitude;
						highLong = this.shapeLayerArray[layer].GetShapeByIndex(0).GetPoints()[0].Longitude;
					}
					else {
						lowLat = (this.shapeLayerArray[layer].GetShapeByIndex(i).GetPoints()[0].Latitude < lowLat) ? this.shapeLayerArray[layer].GetShapeByIndex(i).GetPoints()[0].Latitude : lowLat;
						highLat = (this.shapeLayerArray[layer].GetShapeByIndex(i).GetPoints()[0].Latitude > highLat) ? this.shapeLayerArray[layer].GetShapeByIndex(i).GetPoints()[0].Latitude : highLat;
						lowLong = (this.shapeLayerArray[layer].GetShapeByIndex(i).GetPoints()[0].Longitude < lowLong) ? this.shapeLayerArray[layer].GetShapeByIndex(i).GetPoints()[0].Longitude : lowLong;
						highLong = (this.shapeLayerArray[layer].GetShapeByIndex(i).GetPoints()[0].Longitude > highLong) ? this.shapeLayerArray[layer].GetShapeByIndex(i).GetPoints()[0].Longitude : highLong;
					}
				}

				this.shapeLayerPointsArray[layer] = [
				    new VELatLong(lowLat - 0.002, lowLong + 0.002),
				    new VELatLong(lowLat - 0.002, highLong - 0.002),
				    new VELatLong(highLat + 0.002, lowLong + 0.002),
				    new VELatLong(highLat + 0.002, highLong - 0.002)
			    ];
			}

			this._Map.SetMapView(this.shapeLayerPointsArray[layer]);
			if (this.shapeLayerArray.length < 2 && this._Map.GetZoomLevel() > 14) {
				this._Map.SetZoomLevel(14);
			}
		}
	},
	ShowLayer: function(e, context) {
		for (var i = 0; i < this.shapeLayerArray.length; i++) {
			// initially show the first layer
			if (i != context.layer)
				this.shapeLayerArray[i].Hide();
			else
				this.shapeLayerArray[i].Show();
		}

		this.CalculateZoomAspectRatio(context.layer);
	},

	//Properties:
	get_Byway: function() {
		return this._Byway;
	},
	set_Byway: function(value) {
		if (this._Byway != value) {
			this._Byway = value;
			this.raisePropertyChanged("Byway");
		}
	},

	get_InitialLatitude: function() {
		return this._InitialLatitude;
	},
	set_InitialLatitude: function(value) {
		this._InitialLatitude = value;
	},

	get_InitialLongitude: function() {
		return this._InitialLongitude;
	},
	set_InitialLongitude: function(value) {
		this._InitialLongitude = value;
	},

	get_Zoom: function() {
		return this._MapZoom;
	},
	set_Zoom: function(value) {
		this._MapZoom = value;
	},

	get_MapPinList: function() {
		return this._mapPinList;
	},
	set_MapPinList: function(value) {
		if (this._mapPinList != value) {
			this._mapPinList = value;
			this.raisePropertyChanged("MapPinList");
		}
	},

	get_MapLayerEvents: function() {
		return this._mapLayerEvents;
	},
	set_MapLayerEvents: function(value) {
		if (this._mapLayerEvents != value) {
			this._mapLayerEvents = value;
			this.raisePropertyChanged("MapLayerEvents");
		}
	},
	get_AddNumbersToCityPins: function() {
		return this._addNumbersToCityPins;
	},
	set_AddNumbersToCityPins: function(value) {
		if (this._addNumbersToCityPins != value) {
			this._addNumbersToCityPins = value;
			this.raisePropertyChanged("AddNumbersToCityPins");
		}
	},
	get_MapLayerToBeShown: function() {
		return this._mapLayerToBeShown;
	},
	set_MapLayerToBeShown: function(value) {
		if (this._mapLayerToBeShown != value) {
			this._mapLayerToBeShown = value;
			this.raisePropertyChanged("MapLayerToBeShown");
		}
	}
}

Cted.MapBehavior.registerClass("Cted.MapBehavior", Sys.UI.Control);

Cted.MapLayerEvents = function() { };

Cted.MapLayerEvents.prototype =
{
	Click: 0
}

Cted.MapLayerEvents.registerEnum("Cted.MapLayerEvents");

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();