   
var map;
var geocoder;
//var mgr;
var mileMarkers = [];
var icons = {};
var allmarkers = [];
var allpolylines = [];
var totalDistance = 0.0;
var clickListener;
var reversegeocoder;

var MileOrKM = 'mile';

var cityName = "";
var stateName = "";
var CountryName = "";
var ZipCodeName = "";
var StreetName = "";



// === Some cookie parameters ===
var cookiename = "mapinfo";  // name for this cookie
var expiredays = 365;          // number of days before cookie expiry



    
	

// Create our lettered marker icons 
var icons = new Array();
icons[""] = new GIcon(); 
icons[""].image = "http://www.google.com/mapfiles/marker.png"; 
icons[""].shadow="http://www.google.com/mapfiles/shadow50.png"; 
icons[""].iconSize=new GSize(18, 24); 
icons[""].shadowSize=new GSize(37, 34); 
icons[""].iconAnchor=new GPoint(9,24); //positioning of icon
icons[""].infoWindowAnchor=new GPoint(9,2); 
icons[""].infoShadowAnchor=new GPoint(18,25); 
icons[""].printImage="http://www.google.com/mapfiles/markerie.gif"; 
icons[""].mozPrintImage="http://www.google.com/mapfiles/markerff.gif"; 
icons[""].printShadow="http://www.google.com/mapfiles/dithshadow.gif"; 
icons[""].transparent="http://www.google.com/mapfiles/markerTransparent.png";
icons[""].imageMap=[9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0]; 


    //var locations = [];

    function createMap()
	{



      map = new GMap2(document.getElementById("map_canvas"));


      // === Default values to use if there is no cookie ===
      var lat = 39.4419;
      var lng = -102.1419;
      var zoom = 4;
      var maptype = 0;


 

     map.setCenter(new GLatLng(lat,lng),zoom);


      // === Look for the cookie ===
      if (document.cookie.length>0) {

        cookieStart = document.cookie.indexOf(cookiename + "=");
        if (cookieStart!=-1) {
          cookieStart += cookiename.length+1; 
          cookieEnd=document.cookie.indexOf(";",cookieStart);
          if (cookieEnd==-1) {
            cookieEnd=document.cookie.length;
          }
          cookietext = document.cookie.substring(cookieStart,cookieEnd);
          // == split the cookie text and create the variables ==
          bits = cookietext.split("|");
          lat = parseFloat(bits[0]);
          lng = parseFloat(bits[1]);
          zoom = parseInt(bits[2]);
          maptype = parseInt(bits[3]);
        } 
      }

	//keep the map for messing up
	if(!(lat == 0 || lng == 0 || isNaN(lng) || isNaN(lat)))
	{
	     map.setCenter(new GLatLng(lat,lng),zoom);
		
	} 


      //map.panTo(new GLatLng(lat,lng));


      changeMapType(maptype);

      map.disableDoubleClickZoom();
      map.addControl(new GLargeMapControl());


	}

    function MyApplication() {
	counter = 0;
	createMap();
	recalculateDistance();
	geocoder = new GClientGeocoder();
	startMapping();
    }

    function changeMapType(MapType)
    {

	//Change the mapType and also change the selected option in the dropdown menu
	
	if('hybrid' == MapType || 3 == MapType)
	{
		map.setMapType(G_HYBRID_MAP);
		document.getElementById("mapType").options[3].selected = true;
	}else if('satellite' == MapType || 2 == MapType)
	{
		map.setMapType(G_SATELLITE_MAP);
		document.getElementById("mapType").options[2].selected = true;
	}
	else if('physical' == MapType || 1 == MapType)
	{
		map.setMapType(G_PHYSICAL_MAP);
		document.getElementById("mapType").options[1].selected = true;
	}
	else
	{
		map.setMapType(G_NORMAL_MAP);
		document.getElementById("mapType").options[0].selected = true;
	}

	
    }

	function removeLastMarker()
	{
		if(!(0 == counter))
		{
			if(counter > 0)
			{ 
			counter--;
			}
			if(counter > 0)
			{ 
			map.removeOverlay(allpolylines[counter - 1]);
			allpolylines.pop();
			}

			//mgr.removeMarker(allmarkers[counter]);
			map.removeOverlay(allmarkers[counter]);
			allmarkers.pop();
			allmarkers[counter - 1].show();
			//mgr.refresh();
			recalculateDistance();
		}
	}

    function clearMarkers() {

	map.clearOverlays();
	allmarkers = [];
	allGLatLngs = [];
	allpolylines = [];
	recalculateDistance();
	counter = 0;
	cityName = "";
	stateName = "";
	CountryName = "";
	ZipCodeName = "";
	StreetName = "";
    }

    function recalculateDistance()
    {
	
	var numberOfMarkers = allmarkers.length;
	var distance = 0.00;
	var mileCounter = 0;
	var kmCounter = 0;

	for(var i = 0; i < mileMarkers.length; ++i)
	{
		//mgr.removeMarker(mileMarkers[i]);
		map.removeOverlay(mileMarkers[i]);
	}
	mileMarkers = [];


	for(var i = 1;i < numberOfMarkers; ++i)
	{
		if(i > 1 && i < numberOfMarkers)
		{
			allmarkers[i - 1].iconSize=new GSize(0, 0);; // hide all but first and last.
			allmarkers[i - 1].hide(); // hide all but first and last.
		}else if(i == numberOfMarkers)
		{
			allmarkers[i - 1].iconSize=new GSize(18, 24);
			allmarkers[i - 1].show();
		}


		prevDistance = distance==0?0.0001:distance;
		distance += allmarkers[i - 1].getLatLng().distanceFrom(allmarkers[i].getLatLng());



		if(Math.floor(distanceConversionFromMeters(distance,MileOrKM)) > Math.floor(distanceConversionFromMeters(prevDistance,MileOrKM)))
		{
			numberOfMiles = Math.floor(distanceConversionFromMeters(distance,MileOrKM)) - Math.floor(distanceConversionFromMeters(prevDistance,MileOrKM));


			if(MileOrKM == "mile")
			{
			nextMileMarkerDistance = meterConversionFromMiles(Math.ceil(distanceConversionFromMeters(prevDistance,MileOrKM)) 
				- distanceConversionFromMeters(prevDistance,MileOrKM));
			}
			else
			{
			nextMileMarkerDistance = meterConversionFromKilometers(Math.ceil(distanceConversionFromMeters(prevDistance,MileOrKM)) 
				- distanceConversionFromMeters(prevDistance,MileOrKM));
			}

			for(var counter = 0; counter < numberOfMiles; counter++)
			{
			
			mileCounter++;

			var fakePolyline = new GPolyline([
	  		    allmarkers[i - 1].getLatLng(),
	  		    allmarkers[i].getLatLng()
			    ], "#ff0000", 1);


			var point = fakePolyline.GetPointAtDistance(nextMileMarkerDistance );
			
			fakePolyline = null;

			var mileIcon = new GIcon(icons[""]);
			mileIcon.image = "http://www.joggermaps.com/create_image.php?numberMarker="+mileCounter;
			mileIcon.iconSize = new GSize(20, 20); 
			mileIcon.iconAnchor=new GPoint(9,10);
			mileIcon.shadow = "";
			
			var mileMarker = new GMarker(point,mileIcon);
			map.addOverlay(mileMarker);

			mileMarkers.push(mileMarker);




			if(MileOrKM == "mile")
			{
				nextMileMarkerDistance = nextMileMarkerDistance + meterConversionFromMiles(1);
			}else //KM
			{
				nextMileMarkerDistance = nextMileMarkerDistance + meterConversionFromKilometers(1);
			}


			}
		}
	}
	
	//mgr.refresh();

	totalDistance = distance;
	
	document.getElementById('mile_box').innerHTML = Math.round((mileConversion(totalDistance))*100)/100 + " Miles";
	document.getElementById('km_box').innerHTML = Math.round((kilometerConversion(totalDistance))*100)/100 + " KM";
    }

    function mileConversion(distance)
    {
	return distance * 0.000621371192; // meters * 0.000621371192
    }
    function kilometerConversion(distance)
    {
	return distance * 0.001; // meters * 0.001
    }
    function meterConversionFromMiles(distance)
    {
	return distance * 1609.334; // meters / 1609.34
    }
    function meterConversionFromKilometers(distance)
    {
	return distance * 1000; // meters / 1000.00
    }
    function distanceConversionFromMeters(meters,typeOfMeasure)
    {
	if(typeOfMeasure == "mile")
	{
		return mileConversion(meters);
	}
	else if(typeOfMeasure == "km")
	{
		return kilometerConversion(meters);
	}
	return null;
    }

    // showLocation() is called when you click on the Search button
    // in the form.  It geocodes the address entered into the form
    // and adds a marker to the map at that location.
    function showLocation() {
      var address = document.forms[0].q.value;
      geocoder.getLocations(address, addAddressToMap);
    }

    // addAddressToMap() is called when the geocoder returns an
    // answer.  It adds a marker to the map with an open info window
    // showing the nicely formatted version of the address and the country code.
    function addAddressToMap(response) {
      map.clearOverlays();
      if (!response || response.Status.code != 200) {
        alert("Sorry, we were unable to geocode that address");
      } else {
        place = response.Placemark[0];
        point = new GLatLng(place.Point.coordinates[1],
                            place.Point.coordinates[0]);
	map.setCenter(point, 13);
        //marker = new GMarker(point);
        //map.addOverlay(marker);
        //marker.openInfoWindowHtml(place.address + '<br>' +
        //  '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
      }
    }




function startMapping()
{

clickListener = GEvent.bind(map, "click", this, function(marker,latlng) {
	
          if (latlng) {
	     addPoint(latlng,true);
		if(1 == counter || (2 == counter && null == cityName) || (3 == counter && null == cityName))
		{
			//alert('searching');
			GetLocationInformation();
		}
           } else {
             this.removeOverlay(marker);
           }

      }); 
}

function stopMapping()
{
	GEvent.removeListener(clickListener);
}





    function initialize() {
        var application = new MyApplication();
	resizeMap();
	$('.ui-tabs-nav').bind('tabsshow', function(event, ui) {
	    ui.options // options used to intialize this widget
	    ui.tab // anchor element of the selected (clicked) tab
	    ui.panel // element, that contains the contents of the selected (clicked) tab
	    ui.index // zero-based index of the selected (clicked) tab
	    resizeMap();
	});
    }



function printMap()
{
	//hideSidebar();
	//self.resizeTo(800,screen.height);
	window.print();  
	//showSidebar();
}


function hideSidebar()
{
	document.getElementById('sidepanel').style.width = 0;
	document.getElementById('sidepanel').style.display = 'none';
	document.getElementById('searchBox').style.display = 'none';
	document.getElementById('showSidepanel').style.display = 'inline';
	document.getElementById('map_canvas').style.width = '600px';
}
function showSidebar()
{
	document.getElementById('showSidepanel').style.display = 'none';
	document.getElementById('sidepanel').style.width = 100;
	document.getElementById('sidepanel').style.display = 'inline';
	document.getElementById('searchBox').style.display = 'inline';
	document.getElementById('map_canvas').style.width = '100%';
}

//resize the map
  function resizeMap()
  {

    $("body").css("visibility","visible");

    var heightOfTitle = document.getElementById("TitleRow").offsetHeight;

    //get reference to map div, the one that contains the map
    var map = document.getElementById('MapRow');

    
    var maxWidth  = getScreenWidth();
    var maxHeight = (getScreenHeight() - heightOfTitle - 80);

    map.style.width  = maxWidth  + 'px';
    map.style.height = maxHeight + 'px';

    
    document.getElementById('sidepanel').style.height = (maxHeight - 2) + 'px';
    document.getElementById('map_canvas').style.height = (maxHeight - 2) + 'px';
    document.getElementById('About').style.height = (maxHeight - 2) + 'px';


   
	//document.getElementById('Help').style.height = (maxHeight - 2) + 'px';
	//alert('HI');
  }
  
  //get the viewable height of browser
  function getScreenHeight()
  {
    
    var divHeight;

    //if Mozilla or some others
    if (window.innerHeight)
    {
      divHeight = window.innerHeight;
    }
    //if IE 6
    else if((document.documentElement) && (document.documentElement.clientHeight))
    {
      divHeight = document.documentElement.clientHeight;
    }
    //if IE 5 or less
    else if((document.body) && (document.body.clientHeight))
    {
      divHeight = document.body.clientHeight;
      
    }
    return divHeight;
  }

  //get the viewable width of browser
  function getScreenWidth()
  {
    
    var divWidth;

    //if Mozilla or some others
    if (window.innerWidth)
    {
      divWidth = window.innerWidth;
    }
    //if IE 6
    else if((document.documentElement) && (document.documentElement.clientWidth))
    {
      divWidth = document.documentElement.clientWidth;
    }
    //if IE 5 or less
    else if((document.body) && (document.body.clientWidth))
    {
      divWidth = document.body.clientWidth;
    }

    return divWidth;
  }

function addPoint(latlng,refreshBoolean)
{

		var newIcon = new GIcon(icons[""]);
		newIcon.image = "http://labs.google.com/ridefinder/images/mm_20_green.png";
	     var newMarker = new GMarker(latlng,newIcon);
             
	     
	     
	     
		//Print Lat and Long.
	    //alert(latlng);

		
		if(counter > 0)
		{ 
			/** **/
		  //NO ICON OR SHADOWS!!
		  newIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
		  newIcon.shadow="";
		
		  var polyline = new GPolyline([
  		    latlng,
  		    allmarkers[counter - 1].getLatLng()
		    ], "#ff0000", 5);

		  map.addOverlay(polyline);
		  allpolylines.push(polyline);

	
		}

		allmarkers.push(newMarker);
		//mgr.addMarker(newMarker,1);
		map.addOverlay(newMarker);

		counter++;

		if(counter > 1)
		{
			var distance = allmarkers[counter - 2].getLatLng().distanceFrom(allmarkers[counter - 1].getLatLng());
			if(distance > 20000)
			{
				alert('Sorry.. The furthest one point can be from the previous point is 20km.');
				removeLastMarker();
			
			}
		}
		

		if(refreshBoolean)
		{
			recalculateDistance(); // in meters
		}
	     //map.addOverlay(locations[this.counter]);



}

function changeDistanceUnits()
{
	$("#km_box,#mile_box,#marker_type").fadeOut("fast");

	if(MileOrKM == "mile")
	{
		MileOrKM = 'km';
		$("#km_box").css("font-weight","bold");
		$("#km_box").css("font-size","14px");
		$("#mile_box").css("font-weight","normal");
		$("#mile_box").css("font-size","12px");
		$("#km_box").after($("#mile_box"));

		$("#marker_type").text("Display: KM markers");


	}
	else if(MileOrKM == "km")
	{
		MileOrKM = 'mile';
		$("#mile_box").css("font-weight","bold");
		$("#mile_box").css("font-size","14px");
		$("#km_box").css("font-weight","normal");
		$("#km_box").css("font-size","12px");
		$("#mile_box").after($("#km_box"));

		$("#marker_type").text("Display: Mile markers");

	}
	else
	{
		MileOrKM = 'km';
	}

	$("#km_box,#mile_box,#marker_type").fadeIn("fast");

	recalculateDistance();


	
}

function GetLocationInformation()
{
	reversegeocoder = new GReverseGeocoder(map);

        GEvent.addListener(reversegeocoder, "load",
          function(placemark) {
            
		cityName = reversegeocoder.getPlacemarkProperty(placemark,"LocalityName");
		stateName = reversegeocoder.getPlacemarkProperty(placemark,"AdministrativeAreaName");
		CountryName = reversegeocoder.getPlacemarkProperty(placemark,"CountryNameCode");
		ZipCodeName = reversegeocoder.getPlacemarkProperty(placemark,"PostalCodeNumber");
		StreetName = reversegeocoder.getPlacemarkProperty(placemark,"ThoroughfareName");

		document.getElementById('city_box').innerHTML = cityName == null?"":cityName + ", ";
		document.getElementById('state_box').innerHTML = stateName  + ", ";
		document.getElementById('country_box').innerHTML = CountryName;

		//alert(cityName + " " + stateName + " " + CountryName + " " + ZipCodeName + " " + StreetName );
          }
        );

	reversegeocoder.reverseGeocode(allmarkers[0].getLatLng());
	
	






}
function SaveMap()
{

	if(allmarkers.length > 0)
	{


	var RouteString = "";
	
	for(var i = 0; i < allmarkers.length; ++i)
	{
		RouteString += ";" + allmarkers[i].getLatLng();
	}
	
	var zoomLevelString = "<" + map.getZoom() + ">;";
	var centerPointString = "{" + map.getCenter() + "};";
	var mapTypeString = "[" + map.getCurrentMapType().getName() + "],";
	var ExtraString = "< >";


	var RoutePointsString = zoomLevelString + centerPointString + mapTypeString + ExtraString + RouteString;


	var remainderOfUrl = "&city="+cityName+"&state="+stateName+"&country="+CountryName+"&zip="+ZipCodeName+"&street="+StreetName;

	//alert("RoutePoints="+RoutePointsString+"&action=saveRoute"+remainderOfUrl);


	var domain = '/';

	$.ajax({
	type: "POST",
	url: domain + "route_access.php", 
	data: "RoutePoints="+RoutePointsString+"&action=saveRoute"+remainderOfUrl,
	success: function showResponse(msg)
		{
			//alert(msg);
			document.getElementById('message').style.display = "inline";
			$("#message").html("<center>Here's the link to your saved route: <br /> <input type='textbox' size='50' value=' "+ msg + "' /></center> ");

			var nameTitle = "";

			var currentDate = new Date ();

			if(cityName && stateName)
			{
				nameTitle = cityName + ', ' + stateName;
			}else if(stateName)
			{
				nameTitle = stateName;
			}

	         	var title = "JoggerMaps - " +nameTitle + " Running Route: " + currentDate.toDateString() ; 
		 	var url = msg;



			$("#message").dialog({
				title:"Permalink Details",
				width:500,
				height:200,
				minWidth: 500,
				modal: true, 
	    			overlay: { 
					opacity: 0.5, 
					background: "black" 
	    			}, 
				buttons: { 

					"Share on Facebook": function() { 

						window.open("http://www.facebook.com/sharer.php?u=" + encodeURIComponent(url) + "&t=" + encodeURIComponent(title),'mywindow','width=650,height=300,toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,copyhistory=yes,resizable=yes');


       				 	},
       				 	"Bookmark": function() { 
						

						if (window.sidebar) 
						{ // Mozilla Firefox Bookmark
							window.sidebar.addPanel(title, url,"");
						} else if( window.external ) 
						{ // IE Favorite
							window.external.AddFavorite( url, title); 
						}
						else if(window.opera && window.print) 
						{ // Opera Hotlist
							return true; 
						}
       				 	},
					"Close": function() { 
        				    $(this).dialog("close");
       				 	}


    				} ,
				bgcolor: "red"
			});

		}
	});

	}

	else
	{
		document.getElementById('errorMessage').style.display = "inline";
		$("#errorMessage").html("<br /><center>Sorry... Please create a route before saving.</center>");
		$("#errorMessage").dialog({
				title:"Notification",
				width:500,
				height:160,
				minWidth: 500,
				modal: true, 
	    			overlay: { 
					opacity: 0.5, 
					background: "black" 
	    			}, 
				buttons: { 
       				 	
					"Close": function() { 
        				    $(this).dialog("close");
       				 	}

    				} ,
				bgcolor: "red"
		});



	}


}

function LoadMap(routeID)
{

	//var domain = 'http://dev.joggermaps.com/';
	var domain = '/';

	$.ajax({
	type: "POST",
	url: domain + "route_access.php", 
	data: "id="+routeID+"&action=getRoute",
	success: loadSavedMap
	});


}



function loadSavedMap(req)
{
	

	var tempTxt = req;
	
	var zoomLevelString = tempTxt.substring(1,tempTxt.indexOf(";") - 1);

	var txt = tempTxt.substring(tempTxt.indexOf(";") + 1);

	



	var startLat = txt.substring(txt.indexOf("(")+1,txt.indexOf(","));
	var startLng = txt.substring(txt.indexOf(" ")+1,txt.indexOf(")"));


	txt = txt.substring(txt.indexOf(";") + 1);

	var MapType = txt.substring(txt.indexOf("[")+1,txt.indexOf("]"));
	var MapTypeString = "";

	switch(MapType)
	{
		case "Map":
			MapTypeString = 'normal';
			break;
		case "Satellite":
			MapTypeString = 'satellite';
			break;	
		case "Hybrid":
			MapTypeString = 'hybrid';
			break;	
		case "physical":
			MapTypeString = 'physical';
			break;	
		default:
			MapTypeString = 'normal';	
	}
	
	changeMapType(MapTypeString);


	//txt = txt.substring(txt.indexOf(";") + 1); //Skip Extra String
	txt = txt.substring(txt.indexOf(";") + 1);

	pointArray = txt.split(";");

	//alert(pointArray[0].substring(pointArray[0].indexOf("(")+1,pointArray[0].indexOf(",")));
	//alert(pointArray[0].substring(pointArray[0].indexOf(" ")+1,pointArray[0].indexOf(")")));

	//alert(zoomLevelString);

	var zoomLevel = parseInt(zoomLevelString);


	clearMarkers();

		
	/** **/
	//keep the map for messing up
	//if(!(lat == 0 || lng == 0 || isNaN(lng) || isNaN(lat)))
	//{
	    map.setCenter(new GLatLng(startLat, startLng), zoomLevel);


		for(var i = 0; i < pointArray.length; i++)
		{
			var points = pointArray[i].split(",");

			var lat = parseFloat(points[0].substring(1));
			var lng = parseFloat(points[1].substring(0,points[1].length - 2));
			//alert(points[0].substring(1) + " / " + points[1].substring(0,points[1].length - 2) + " : " + new GLatLng(lat,lng));
			addPoint(new GLatLng(lat,lng),false);
		

		}

	//} 
	




	recalculateDistance();
	//setTimeout("recalculateDistance();",5250);
	//recalculateDistance();


}

// === A method which returns a GLatLng of a point a given distance along the path ===
// === Returns null if the path is shorter than the specified distance ===
GPolygon.prototype.GetPointAtDistance = function(metres) {
// some awkward special cases
if (metres == 0) return this.getVertex(0);
if (metres < 0) return null;
var dist=0;
var olddist=0;
for (var i=1; (i < this.getVertexCount() && dist < metres); i++) {
  olddist = dist;
  dist += this.getVertex(i).distanceFrom(this.getVertex(i-1));
}
if (dist < metres) {return null;}
var p1= this.getVertex(i-2);
var p2= this.getVertex(i-1);
var m = (metres-olddist)/(dist-olddist);
return new GLatLng( parseFloat(p1.lat()) + (parseFloat(p2.lat())-parseFloat(p1.lat()))*m, parseFloat(p1.lng()) + (parseFloat(p2.lng()) - parseFloat(p1.lng()))*m);
}


      // === Set the cookie before exiting ===
      function setCookie() {
        maptype = 0;
        for (var i=0;i<map.getMapTypes().length;i++) {
          if (map.getCurrentMapType() == map.getMapTypes()[i]) {
            maptype = i;
          }
        }
        var cookietext = cookiename+"="+map.getCenter().lat()+"|"+map.getCenter().lng()+"|"+map.getZoom()+"|"+maptype;
        if (expiredays) {
          var exdate=new Date();
          exdate.setDate(exdate.getDate()+expiredays);
          cookietext += ";expires="+exdate.toGMTString();
        }
        // == write the cookie ==
        document.cookie=cookietext;
        // == Call GUnload() on exit ==
        GUnload();
      }



GPolyline.prototype.GetPointAtDistance   = GPolygon.prototype.GetPointAtDistance;


  //when the window loads and resizes, then resize the Map
  window.onload   = resizeMap;
  window.onresize = resizeMap;
  window.onunload = setCookie;

/*** For Jquery Tabs ******/
  $(document).ready(function(){
    $("#example > ul").tabs();
  });






