var BingMaps = Class.create(AjaxObject, {
  initialize: function(container, url, remove_all_events)
  {
    this.domContainer = $(container);
    this.url = url;
    this.originalCenter = false;
    this.remove_all_events = remove_all_events;
  },
  
  init: function()
  {
	  	this.map = new VEMap(this.domContainer.id);
	  	this.map.HideDashboard(); //hide default controls
	  	this.map.ShowMessageBox = false;
	  	this.map.LoadMap(new VELatLong(0,0), 2,'h' ,false);

	  	this.map.previousCenter = new Array();
	  	this.map.previousZoomLevel = new Array();
	  	
	  	if (!this.remove_all_events) { 
	  	this.map.AttachEvent("onclick",this.MouseHandler.bind(this));
	  	this.map.AttachEvent("onmousedown",this.drawHandlerStart.bind(this));
	  	this.map.AttachEvent("onmouseup",this.drawHandlerFinish.bind(this));
	  	this.map.AttachEvent("onchangeview", this.historyHandler.bind(this));
	  	this.map.AttachEvent("onmousemove", this.mouseMoveHandler.bind(this));
	  	}

	  	this.map.containerName = this.domContainer.id;
	  	this.map.originalCenter = this.map.GetCenter(); 
	  	this.map.originalZoomLevel = this.map.GetZoomLevel();
	   if (window.BingMapsSlider) BingMapsSlider.setValue(this.map.GetZoomLevel());
	   if (this.url) this.loadXML();
  },

  loadXML: function()
  {
	  this.map.Clear();
	  this.l = new VEShapeLayer();
	  var veLayerSpec = new VEShapeSourceSpecification(VEDataType.GeoRSS, this.url, this.l);
	  this.map.ImportShapeLayerData(veLayerSpec, this.onFeedLoad.bind(this));
  },

  onFeedLoad: function(feed)
  {
	  this.map.ClearInfoBoxStyles(); //otherwise we can't apply own custom styles

	  var numShapes = feed.GetShapeCount();
	  var shape;
	  
	   for(var i = 0; i < numShapes; ++i)
	   {
	      shape = feed.GetShapeByIndex(i);
	      shape.SetCustomIcon(shape.IconId);

			var reg = /type="([^"]*)/;
			var res = reg.exec(shape.IconId);
			var lineColor = false;
			if (res && res[1].length>0) {
				switch (res[1]) {
					case '1':
						var lineColor = new VEColor(255,252,225,1);
					break;
					case '2':
						var lineColor = new VEColor(254,250,207,1);
					break;
					case '3':
						var lineColor = new VEColor(255,221,32,1);
					break;
					case '4':
						var lineColor = new VEColor(255,192,0,1);
					break;
					case '5':
						var lineColor = new VEColor(255,144,12,1);
					break;
					case '6':
						var lineColor = new VEColor(255,102,0,1);
					break;
					case '7':
						var lineColor = new VEColor(255,54,0,1);
					break;
				}
			}
		/*
			#fffce1
			#fefacf
			#ffdd20
			#ffc000
			#ff900c
			#ff6600
			#ff3600
		*/

		  //Set the line color
	 	  if (lineColor) {
			  shape.SetLineColor(lineColor);
		  }

	      //Set the line width
	      //shape.SetLineWidth(5);
			
	   }

	   if (numShapes == 1) {
		//center and zoom map if we have 1 item
		this.map.previousCenter.pop(); 
		this.map.previousZoomLevel.pop(); 
		//shape = feed.GetShapeByIndex(0);
		this.map.SetZoomLevel(2);
	   }

	   this.map.originalCenter = this.map.GetCenter(); 
	   this.map.originalZoomLevel = this.map.GetZoomLevel(); 
	   	
	   
  },

  drawHandlerStart: function (e)
  {
	if (this.map.mode=='draw') {
		this.map.mode='drawing';
		this.map.drawStartX = e.mapX; 
		this.map.drawStartY = e.mapY; 
	}
  },
	
  drawHandlerFinish: function (e)
  {
	if (this.map.mode=='zoom') {
		this.map.mode ='';
		$('map_zoom').removeClassName('nb_zoom_active');
		document.getElementById(this.map.containerName).childNodes[0].style.cursor = 'auto';
	}
	if (this.map.mode=='drawing') {
    	 var distance = drawCircleHandler(e, this.map);
	     
    	 this.map.vemapcontrol.EnableGeoCommunity(false);
		 document.getElementById(this.map.containerName).style.cursor = '';
		 this.map.mode=false;

		 var drawStartPixel = new VEPixel(this.map.drawStartX, this.map.drawStartY);
		 var drawStartLL = this.map.PixelToLatLong(drawStartPixel);
		
		 if (($("alert_lat")) && $("alert_lon") && $("alert_radius")) {
			 $("alert_lat").value = drawStartLL.Latitude; 
			 $("alert_lon").value = drawStartLL.Longitude; 
			 $("alert_radius").value = distance; 
		 }

		 if (($("user_notification_radius")) && $("user_notification_lat_cr") && $("user_notification_lon_cr")) {
			 $("user_notification_lat_cr").value = drawStartLL.Latitude; 
			 $("user_notification_lon_cr").value = drawStartLL.Longitude; 
			 $("user_notification_radius").value = distance; 
		 }
	}
  },

  mouseMoveHandler: function (e){
	    if (this.map.mode=='drawing') {
	    	drawCircleHandler(e, this.map);
	    }
	},
  
	
  MouseHandler: function (e)
  {
	if ((e.eventName == "onclick") && (e.leftMouseButton))
     {
		var reg = /source_url="([^"]*)/;
		if (this.map.GetShapeByID(e.elementID)) {
			var res = reg.exec(this.map.GetShapeByID(e.elementID).IconId);
			if (res && res[1].length>0) {
				location.href = res[1];
			}
		}
     }

  },

  historyHandler: function (e)
  {
	  this.map.previousCenter.push(this.map.GetCenter()); 
	  this.map.previousZoomLevel.push(this.map.GetZoomLevel());
	  if (window.BingMapsSlider) {
		   if (BingMapsSlider.value != this.map.GetZoomLevel()) {
			   BingMapsSlider.setValue(this.map.GetZoomLevel());
		   }
	  }
  },

  findLocation: function()
  {
	  try {
		  this.map.Find(null, document.getElementById('map_search_where').value);
		  if ((window.AList) && (document.getElementById('mode_home'))) {
				AList.setParam('cc', document.getElementById('map_search_where').value);
				AList.resetPage();
				AList.reload();
		  }
	  }
	  catch(e) {
		  alert(e.message);
	  }
	  
  },

  resetFindLocation: function()
  {
	  if ((window.AList) && (document.getElementById('mode_home'))) {
		  	if (Prototype.Browser.IE) 
		  		$('map_search_where').value='                                   ';
		  	else 
		  		$('map_search_where').value='';
			AList.setParam('age', '1');
			AList.setParam('cc', '');
			AList.resetPage();
			AList.reload();
	  }
  },

  goFromForm: function()
  {
	 if ($("alert_lat") && $("alert_lon") && $("alert_radius") ) {
		 lat = $("alert_lat").value;
		 lon = $("alert_lon").value;
		 radius = $("alert_radius").value;
	 }

	 if ($("user_notification_lat_cr") && $("user_notification_lon_cr") && $("user_notification_radius")) {
		 lat = $("user_notification_lat_cr").value;
		 lon = $("user_notification_lon_cr").value;
		 radius = $("user_notification_radius").value;
	 }

	 if ((window.lat) && (window.lon)) {
		 if (!window.radius) {
			 //just center cart to provided lat/lon
			 BingMapsObj.map.SetCenterAndZoom(new VELatLong(lat, lon),7);
		 }
	 }
  },

  reDrawFromForm: function()
  {
	 this.goFromForm();
	 if (($("alert_lat")) && $("alert_lon") && $("alert_radius")) {
		 if (($("alert_lat").value) && ($("alert_lon").value) && ($("alert_radius").value)) {
			 radius = $("alert_radius").value;
			 if ($("alert_radius_type") && ($("alert_radius_type").value=='miles')) radius = radius*1.609344;  
			 drawCircle(new VELatLong($("alert_lat").value, $("alert_lon").value),radius, this.map);
		 }
	 }
	 if (($("user_notification_lat_cr")) && $("user_notification_lon_cr") && $("user_notification_radius")) {
		 if (($("user_notification_lat_cr").value) && ($("user_notification_lon_cr").value) && ($("user_notification_radius").value)) {
			 if ($('user_whole_world_0').checked) {
				 radius = $("user_notification_radius").value;
				 if ($("radius_type") && ($("radius_type").value=='miles')) radius = radius*1.609344;  
				 drawCircle(new VELatLong($("user_notification_lat_cr").value, $("user_notification_lon_cr").value),radius, this.map);
			 }  else {
				 this.map.DeleteAllShapes();
			 }
		 }
	 }
  }
  
});



/* ******************************************************** */
/* The code for the GeoCodeCalc class was copied from here: */
/* http://pietschsoft.com/Blog/Post.aspx?PostID=1452        */
/* ******************************************************** */
var GeoCodeCalc = {};
GeoCodeCalc.EarthRadiusInMiles = 3956.0;
GeoCodeCalc.EarthRadiusInKilometers = 6367.0;

GeoCodeCalc.ToRadian = function(v) {
    return v * (Math.PI / 180);
};

GeoCodeCalc.DiffRadian = function(v1, v2) {
    return GeoCodeCalc.ToRadian(v2) - GeoCodeCalc.ToRadian(v1);
};

GeoCodeCalc.CalcDistance = function(lat1, lng1, lat2, lng2, radius) {
    return radius * 2 * Math.asin(
            Math.min(1,
                Math.sqrt(
                    (
                        Math.pow(Math.sin((GeoCodeCalc.DiffRadian(lat1, lat2)) / 2.0), 2.0) +
                        Math.cos(GeoCodeCalc.ToRadian(lat1)) * Math.cos(GeoCodeCalc.ToRadian(lat2)) *
                        Math.pow(Math.sin((GeoCodeCalc.DiffRadian(lng1, lng2)) / 2.0), 2.0)
                    )
               )
           )
       );
};

if (GeoCodeCalc == undefined) var GeoCodeCalc = {}
GeoCodeCalc.ToDegrees = function(radians){
    return radians * 180 / Math.PI;
};

function CreateCircle(loc, radius, units)
{    
    var earthRadius = parseFloat(units);
    var lat = GeoCodeCalc.ToRadian(loc.Latitude); //radians
    var lon = GeoCodeCalc.ToRadian(loc.Longitude); //radians
    var d = parseFloat(radius) / earthRadius;  // d = angular distance covered on earth's surface
    var locs = new Array();
    for (x = 0; x <= 360; x++) 
    { 
        var p2 = new VELatLong(0,0)            
        brng = GeoCodeCalc.ToRadian(x); //radians
        
        var latRadians = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(brng));
        var lngRadians = lon + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(lat), Math.cos(d) - Math.sin(lat) * Math.sin(latRadians));
        
        locs.push(new VELatLong(GeoCodeCalc.ToDegrees(latRadians), GeoCodeCalc.ToDegrees(lngRadians)));
    }

   return new VEShape(VEShapeType.Polyline, locs); 
}

function drawCircleHandler(e, map)
{    
	var drawStartPixel = new VEPixel(map.drawStartX, map.drawStartY);
	var drawFinishPixel = new VEPixel(e.mapX, e.mapY);
	var drawStartLL = map.PixelToLatLong(drawStartPixel);
	var drawFinishLL = map.PixelToLatLong(drawFinishPixel);
	
	var distance = GeoCodeCalc.CalcDistance(drawStartLL.Latitude, drawStartLL.Longitude, drawFinishLL.Latitude, drawFinishLL.Longitude, GeoCodeCalc.EarthRadiusInKilometers)
	drawCircle(drawStartLL,distance, map);
	return distance;
}

function drawCircle(drawStartLL,distance, map, dont_zoom)
{    
	if (map.current_shape) {
		map.DeleteShape(map.current_shape);
	}
	
	for(var i=0;i<=0;++i){
		if (i>0) 
			radius = distance-(distance/(i*10))*9;
		else 
			radius = distance;
		var circle = CreateCircle(
				 	drawStartLL,
				 	radius,
				 	GeoCodeCalc.EarthRadiusInKilometers);
		circle.HideIcon();
		circle.SetLineColor(new VEColor(255,0,0,1));
		map.AddShape(circle);
		map.current_shape = circle; 
		//sets best view for array of points
		if (dont_zoom) {
		} else {
			window.setTimeout(function() { drawCircleZoom(map,circle); }, 1000);
		}
	}
}
function drawCircleZoom(map, circle)
{ 
	if (circle)
	{
		points = circle.GetPoints();
		if ((points instanceof Array) && (points.length != null)) {
		  try {
			//ie8 produce stupid error , but works well   
			window.onerror = handleError;  
			map.SetMapView(circle.GetPoints());
		  } 
		  catch (err) {
			  return false;
		  }
		}
	}
}

function handleError()
{
return true;
}

