_mSvgEnabled = true ;
_mSvgForced  = true ;

var center ;
var circle ;
var radius ;
var marker = [] ;
var poly = [] ;
var line ;
var geocoder ;
var icon ;
var gicon ;
var map ;



function load()
{
 map = new GMap2(document.getElementById("map"));
 var start = new GLatLng(39.0904,-94.5837);
 map.setCenter(start, 9);

 map.addControl(new GLargeMapControl());
 map.addControl(new GMapTypeControl());
 map.addControl(new GScaleControl()) ;

 geocoder = new GClientGeocoder() ;
 icon = new GIcon();
 icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
 icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
 icon.iconSize = new GSize(12, 20);
 icon.shadowSize = new GSize(22, 20);
 icon.iconAnchor = new GPoint(6, 20);

 gicon = new GIcon(icon);
 gicon.image = "http://labs.google.com/ridefinder/images/mm_20_green.png";
 gicon.iconAnchor = new GPoint(-20, 20);
}

// Draw...
function draw()
{
 var bounds ;

 var html = '' ;
 poly = [] ;

 for(var i = 0 ; i < marker.length ;i++)
 {
  poly.push(marker[i].getPoint()) ;
  html += marker[i].getPoint().toUrlValue() + "<br>\n" ;
 }
 if(line)
 {
  map.removeOverlay(line) ;
 }

 poly.push(marker[0].getPoint()) ;

 html += marker[0].getPoint().toUrlValue() + "<br>\n" ;

 line = new GPolyline(poly,'#FF0000', 3, 1) ;
 map.addOverlay(line) ;

 return ( poly )
}

// Draw a circle...

function drawCircle( )
{
 for(var n = 0 ; n < marker.length ; n++)
 {
  map.removeOverlay( marker[n] ) ;
 }

 marker = [] ;
 var points = [] ;
 var point = center.getPoint() ;
 var lat = point.lat() ;
 var lng = point.lng() ;
 if ( center.oldpoint )                 // Move radius when center is moved
 {
  var p = radius.getPoint() ;
  var x = point.lat() - center.oldpoint.lat() ;
  var y = point.lng() - center.oldpoint.lng() ;
  radius.setPoint( new GLatLng( p.lat() + x, p.lng() + y) ) ;
 }
 center.oldpoint = point ;

 var Cradius = point.distanceFrom(radius.getPoint()) * 0.000621371192 ;
 var b = radius.getPoint() ;

 var meters = distance(point.lat(),point.lng(),b.lat(),b.lng()) ;

 var Ccolor = '#0000ff' ;               // color blue
 var Cwidth = 3 ;                       // width pixels
 var d2r = Math.PI/180 ;                // degrees to radians
 var r2d = 180/Math.PI ;                // radians to degrees
 var Clat = (Cradius/3963) * r2d ;      //  using 3963 as earth's radius

 var Clng = Clat/Math.cos(lat*d2r);
 var Cpoints = [] ;

 var list = '' ;
 for (var i = 0 ; i < 13 ; i++)
 {
  var theta = Math.PI * (i/6) ;
  Cx = lng + (Clng * Math.cos(theta)) ;
  Cy = lat + (Clat * Math.sin(theta)) ;
  Cpoints.push(new GLatLng(Cy,Cx)) ;

  points.push(new GLatLng(Cy,Cx)) ;
 }

 for(var n = 0 ; n < (points.length -1) ; n++)
 {
  marker[n] = new GMarker(points[n], {icon:icon, draggable: true, title: n});
  map.addOverlay(marker[n]);
  marker[n].enableDragging();
  GEvent.addListener(marker[n],'dragend',function() {draw(); PolySearch(draw()); });
 }

 var poly = draw() ;

 map.setCenter(center.getPoint(), map.getBoundsZoomLevel(getMBR( poly ))) ;


}

function collectPoints(markers){
	poly = [];

	for(var i = 0 ; i < marker.length ;i++){
		var point = marker[i].getPoint()
		poly.push([point.x, point.y]);
	}	
	return poly;
}


function drawPoints(points){
	map.clearOverlays();
	marker = [];
	var gPoints  = [];
	for(var idx in points){
		// console.debug(points[idx]);
		gPoints.push(new GLatLng(points[idx][0],points[idx][1]));
		marker.push(new GMarker(gPoints[idx], {icon:icon, draggable: true, title: idx}));

		map.addOverlay(marker[idx]);
		GEvent.addListener(marker[idx],'dragend',function() { 
			PolySearch(draw());
		});
	}
	line = new GPolyline(gPoints,'#FF0000', 3, 1) ;
	map.addOverlay(line) ;

	map.setCenter(new GLatLng(points[0][0],points[0][1]), 13);

}

function selectVariable(variables){
	for(var variable in variables){
		$("#variable_" + variables[variable]).click();
	}
}

// Find the address using the geocoder...
function reloadSearch(address, points, variables){
	// Uncheck all variables
	$("#tab_data").unCheckCheckboxes()

	// Select given variables
	selectVariable(variables);

	// Push address and radius to form
	$("#address").attr("value", address);
	$("#radius").attr("value", 0);

	drawPoints(points);

	// Load Data
	PolySearch(points);
}

function recallSearch(address, radius, variables){
	// Uncheck all variables
	$("#tab_data").unCheckCheckboxes()

	// Select given variables
	selectVariable(variables);

	// Push address and radius to form
	$("#address").attr("value", address);
	$("#radius").attr("value", radius)

  // Load Points and Data
  showAddress(address, radius);
}


function showAddress(address,miles)
{
 map.clearOverlays();
 geocoder.getLatLng( address, function(point)
 {
  if (!point)
  {
   alert(address + " not found")
  } else
  {
   if (center)
   {
    map.removeOverlay( center ) ;
    map.removeOverlay( radius ) ;
   }
   center = new GMarker(point, {icon:icon, draggable: true,  title: "Center"});
   center.enableDragging();
   map.addOverlay(center);
   GEvent.addListener(center,'dragend',function() { PolySearch(poly); drawCircle();});

   oldpoint = center.getPoint() ;

   radius = new GMarker(getRadius(miles,center), {icon:gicon, draggable: true,  title: "Radius"});
   map.addOverlay(radius);
   radius.enableDragging();
   GEvent.addListener(radius,'dragend',function() {PolySearch(poly); drawCircle(); });
   drawCircle();
   PolySearch(poly);

  }
 }) ;
}

// Calculate the distance...

function distance(lat1,lng1,lat2,lng2)
{
 var O = Math.PI/180 ;
 var b = lat1 * O ;
 var c = lat2 * O ;
 var d = b - c ;
 var e = (lng1 * O) - (lng2 * O) ;
 var f = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(d/2),2)+Math.cos(b)*Math.cos(c)*Math.pow(Math.sin(e/2),2)));
 return f*6378137
}

// Figure out the radial point...

function getRadius( miles, center )
{
 var point = center.getPoint() ;
 var lat = point.lat() ;
 var lng = point.lng() ;
 var d2r = Math.PI/180 ;                // degrees to radians
 var r2d = 180/Math.PI ;                // radians to degrees
 var Clat = (miles/3963) * r2d ;       //  using 3963 as earth's radius
 var Clng = Clat/Math.cos(lat*d2r);
 Clng = lng + (Clng * Math.cos(0)) ;
 Clat = lat + (Clat * Math.sin(0)) ;
 return(new GLatLng(Clat,Clng)) ;
}

// Minimum Bounding Rectangle...

function getMBR (points)
{
 var minx = 0;
 var miny = 0;
 var maxx = 0;
 var maxy = 0;

 if ( points.length < 4 )
 {
  return ( GLatLngBounds(new GLatlng(minx,miny), new GLatlng(maxx,maxy)) ) ;
 }

 minx = points[0].lat() ;
 miny = points[0].lng() ;
 maxx = points[0].lat() ;
 maxy = points[0].lng() ;

 for(var i = 1; i < points.length ; i++ )
 {
  if ( points[i].lat() > maxx )
  {
   maxx = points[i].lat() ;
  }
  if ( points[i].lat() < minx )
  {
   minx = points[i].lat() ;
  }
  if ( points[i].lng() > maxy )
  {
   maxy = points[i].lng() ;
  }
  if ( points[i].lng() < miny )
  {
   miny = points[i].lng() ;
  }
 }

 return ( new GLatLngBounds(new GLatLng(maxx,miny), new GLatLng(minx,maxy)) ) ;
}

// Search
function PolySearch(points){

  var varsource = new Array();
  var total = 0;
  var varparam = new Array();

	$("input[@name='variable']:checked").each(
		function(){
			varparam.push($(this).val());
		}
	);

  if(varparam.length > 0){
	  $("#dataresult").load("search/html/source/1001/searchtype/contains/spatialtype/1/",
	  {'point[]': points,
	  'variable[]': varparam},
	  setupResults);
	}

  return true;
}

function setupResults(){
  if($("#large").length > 0){
  	$("#large").tablesorter({widgets: ['zebra']});
		$("#content").tabs().tabs('select', 1);
		$(".tooltip").tooltip();
	}

	// Document Ready
	var address = $('#address_field'),
		allFields = $([]).add(name).add(description),
		description = $("#save_description"),
	  name = $("#save_name"),
		dialogTips = $("#validateTips_dialog"),
		public = $("#save_public");

	$(".ui-button").hover(
		function(){
			$(this).addClass("ui-state-hover");
		},
		function(){
			$(this).removeClass("ui-state-hover");
		}
	).mousedown(function(){
		$(this).addClass("ui-state-active");
	})
	.mouseup(function(){
			$(this).removeClass("ui-state-active");
	});

	function updateTips(t, tip_target) {
		tip_target.text(t).effect("highlight",{},1500);
	}

	function checkLength(o,n, tip) {
		if ( o.val().length <= 0) {
			o.addClass('ui-state-error');
			updateTips("Length of " + n + " can not be blank.", tip);
			return false;
		} else {
			return true;
		}
	}

  function saveSearchUrl(){
		var map_id = $('#search-map-id');

		var save_path = ["search", "save"];
		save_path.push("id", map_id.val());
		save_path.push("name", name.val());
		save_path.push("address", address.val());
		save_path.push("description", description.val());
		if(public.attr("checked")){
			save_path.push("public", 1);
		} else {
			save_path.push("public", 0);
		}
		save_path.push("center", map.getCenter().toUrlValue());
	  return save_path.join("/");
  }

	$('#save-search').click(function() {
		$('#save-search-dialog').dialog('open');
	})

  var saveSearch = function(){
		$.getJSON(saveSearchUrl(), function(data){
			var search_map = $("<div>").addClass("map").
					    append($("<a>").click(function(){
					      reloadSearch(data["address"], data["points"], data["variables"]);
					    }).
					      append($("<img src=\"" + data.imgpath + googleKey() +"\"/>")).
					      append($("<br/>")).
					      append($("<div>").addClass("enlarge_map_btn ui-corner-all").
					        append($("<span>").addClass("enlarge_map")).
					        append($("<a>").addClass("enlarge_map_text").text("Launch Map"))
					      )
					  );

		  var search_info = $("<dl>").
		    append($("<dt>Address:</dt>")).
		    append($("<dd>").text(data["address"])).
		    append($("<dt>Description:</dt>")).
		    append($("<dd></dd>").text(data["description"]));

		  var map_item = $("<li>").
				append(search_map).
				append(search_info);

			var target_list = "tabs_public_search";
			if(data.public == "0"){
				target_list = "tabs_my_search";
			}
			$("#" + target_list  + " ul.maps").prepend(map_item);			
		});
  }

	$("#save-search-dialog").dialog({
		bgiframe: true,
		autoOpen: false,
		width: 400,
		modal: true,
		dialogClass: "save-search-dialog",
		buttons: {
			'Save Search': function() {
				var bValid = true;
				allFields.removeClass('ui-state-error');

				bValid = bValid && checkLength(name,"name", dialogTips);
				bValid = bValid && checkLength(description,"description", dialogTips);

				if (bValid) {
					saveSearch();
					$(this).dialog('close');
				}
			},
			Cancel: function() {
				$(this).dialog('close');
			}
		},
		close: function() {
			allFields.val('').removeClass('ui-state-error');
		}
	});
  // End Document Ready
}