// index.js
/*
Copyright 2008 Google Inc.

Modified by GMaps Gaier for the Gaiagi Driver (c) 2008 - 2011
   
Copyright 2008-2011 GMaps Gaier

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * @fileoverview This is the main JavaScript file for the Driving Simulator
 * @author Roman Nurik
 * @supported Tested in IE6+ and FF2+
 *
 * Modified by GMaps Gaier for the Gaiagi Driver 
 *
 *   http://www.gaiagi.com/driving-simulator/
 *
 */

/**
 * The global Directions object for the currently loaded directions
 * @type {google.maps.Directions}
 */
var DS_directions = null;

/**
 * The list of driving steps loaded from google.maps.Directions
 * @type {Array.<Object>}
 */
var DS_steps = [];

/**
 * The list of path vertices and their metadata for the driving directions
 * @type {Array.<Object>}
 */
var DS_path = []; // entire driving path

/**
 * The global simulator instance that conducts the driving simulation
 * @type {DDSimulator}
 */
var DS_simulator; // instance of the DDSimulator class

/**
 * The car marker that appears on the reference map to the right of the main
 * simulation screen
 * @type {google.maps.Marker}
 */
var DS_mapMarker = null; // car marker on the Map
var DS_mapMarker_icon = null; // car marker icon on the Map

/**
 * Instead of using the plugin's built-in ID system, which doesn't like when
 * IDs are reused, we will use a separate dictionary mapping ID to placemark
 * object
 * @type {Object}
 */
var DS_placemarks = {};

/**
 * The callback for when the 'Go!' button is pressed. This uses the Maps API's
 * Directions class to get the route and pull out the individual route steps
 * into a path, which is rendered as a polyline.
 */
function DS_goDirections() {
  $('#route-details').empty();
  show_route_details();
  $('#route-details').html(
      '<span class="loading">Loading directions...</span>');

  DS_directions = new google.maps.Directions(DS_map, null);
  
  google.maps.Event.addListener(DS_directions, 'load', DS_directionsLoaded);
  
  google.maps.Event.addListener(DS_directions, 'error', function() {
    $('#route-details').empty();
    show_route_details();
    if (DS_directions.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
	$('#route-details').html('<span class="error">No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.</span>');
    else if (DS_directions.getStatus().code == G_GEO_SERVER_ERROR)
	$('#route-details').html('<span class="error">A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.</span>');
    else 
	$('#route-details').html(
             '<span class="error">No directions found.</span>');
  });
  
  opts = {getSteps: true, getPolyline: true};
  if (g_canPlayAudioMP3) {
      div = document.getElementById("speaker_div");
      div.style.display = 'inline';
  }
  if (g_wantsPlayAudioMP3) {
      opts = {getSteps: true, getPolyline: true, locale: "en_US"};
  }
  DS_directions.load('from: ' + $('#from').val() + ' to: ' + $('#to').val(),
		     opts );

  var t = new Date(); t.setDate(t.getDate() + (2 * 360));
  setCookie("store", "" + $('#from').val() + "|" + $('#to').val(), t);

  // show driver interface
  show_hide_drive_ctrl();

  pageTracker._trackEvent('Driver', 'Directions',$('#from').val() + ' -- ' + $('#to').val());	
}

var DS_polyline = null, DS_polyline_drag = null, DS_directions_drag = null;
var DS_marker = [], DS_marker_drag = [];
var geocoderService = null;

/**
 * Initialization after directions are loaded
 */
function DS_directionsLoaded() {
  // Directions data has loaded
  $('#route-details').empty();
  show_route_details();
  var route = DS_directions.getRoute(0);
  if (DS_polyline) {
      // remove old polyline
      DS_map.removeOverlay(DS_polyline);
      DS_map.removeOverlay(DS_marker[0]);
      DS_map.removeOverlay(DS_marker[1]);
  }
  var start = route.getStartGeocode();
  var end = route.getEndGeocode();
  
  // build the path and step arrays from the google.maps.Directions route
  DS_buildPathStepArrays();
  
  DS_geHelpers.clearFeatures();
  if (g_webcamLink && g_conf_arr['ge_webcams']) {
      DS_ge.getFeatures().appendChild(g_webcamLink);
      // DS_ge.getFeatures().appendChild(g_weatherLink);
  }
  if (centerOverlay && g_conf_arr['show_center']) {
      DS_ge.getFeatures().appendChild(centerOverlay);
  }

  DS_placemarks = {};
  
  // create the starting point placemark
  DS_placemarks['start'] = DS_geHelpers.createPointPlacemark(
      new google.maps.LatLng(start.Point.coordinates[1],
                             start.Point.coordinates[0]),
      {description: start.address, standardIcon: 'grn-diamond'});
  
  // create the point placemarks for each step in the driving directions
  for (var i = 0; i < DS_steps.length; i++) {
    var step = DS_steps[i];
    
    var placemark = DS_geHelpers.createPointPlacemark(
        step.loc, {description: step.desc, standardIcon: 'red-circle'});
    
    DS_placemarks['step-' + i] = placemark; 
    
    google.earth.addEventListener(placemark, 'click', function() {
      // match up the placemark to its id in the dictionary to find out
      // which step number it is
      var id = '';
      for (k in DS_placemarks)
        if (DS_placemarks[k] == this)
          id = k;
      
      var stepNum = parseInt(id.match(/step-(\d+)/)[1]);
      
      DS_flyToStep(stepNum);
    });
  }
  
  // create the ending point placemark
  DS_placemarks['end'] = DS_geHelpers.createPointPlacemark(
      new google.maps.LatLng(end.Point.coordinates[1],
                             end.Point.coordinates[0]),
      {description: end.address, standardIcon: 'grn-diamond'});
  
  // build the route LineString; instead of creating a LineString using
  // pushLatLngAlt, which has some performance issues, we will construct a
  // KML blob and use parseKml() 
  var lineStringKml = '<LineString><coordinates>\n';
  
  for (var i = 0; i < DS_path.length; i++)
    lineStringKml +=
        DS_path[i].loc.lng().toString() + ',' +
        DS_path[i].loc.lat().toString() +
        ',10\n';
  
  lineStringKml += '</coordinates></LineString>';
  
  // create the route placemark from the LineString KML blob
  var routeLineString = DS_ge.parseKml(lineStringKml);
  routeLineString.setTessellate(true);
  
  var routePlacemark = DS_ge.createPlacemark('');
  routePlacemark.setGeometry(routeLineString);
  DS_placemarks['route'] = routePlacemark;
  
  routePlacemark.setStyleSelector(
      DS_geHelpers.createLineStyle({width: 10, color: '88ff0000'}));
  
  DS_ge.getFeatures().appendChild(routePlacemark);

  // build the left directions list
  DS_buildDirectionsList();
  
  // fly to the start of the route
  DS_flyToLatLng(new google.maps.LatLng(
                 start.Point.coordinates[1], start.Point.coordinates[0]));
  
  // enable the simulator controls
  $('#simulator-form input').removeAttr('disabled');
  $('#driver_fieldset').fadeIn('1500');
  // $('#butt_start').css("background-color", "gold");
  
  // destroy the simulator if exists
  if (DS_simulator) {
    DS_simulator.destroy();
    DS_simulator = null;
  }
  $('#butt_start').val("Start");

  // more housekeeping and enabling dragging start and end
  DS_polyline = DS_directions.getPolyline();

  var baseIcon = new GIcon(G_DEFAULT_ICON);
  baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
  baseIcon.iconSize = new GSize(20, 34);
  baseIcon.shadowSize = new GSize(37, 34);
  baseIcon.iconAnchor = new GPoint(9, 34);
  baseIcon.infoWindowAnchor = new GPoint(9, 2);

  DS_marker[2] = DS_directions.getMarker(0);
  latlng = DS_marker[2].getLatLng();
  // alert(DS_marker[0] + " " + latlng);
  window.setTimeout('DS_map.removeOverlay(DS_marker[2])', 1500);
  // DS_map.removeOverlay(DS_marker[0]);

  // start marker
  var letteredIcon = new GIcon(baseIcon);
  index=0;
  var letter = String.fromCharCode("A".charCodeAt(0) + index);
  letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
  var marker = new GMarker(latlng, {draggable: true, icon: letteredIcon});
  GEvent.addListener(marker, "dragend", function(e) {
      // marker.openInfoWindowHtml("Just bouncing along...");

      if (DS_polyline_drag) {
 	  // remove old polyline
 	  DS_map.removeOverlay(DS_polyline_drag);
	  window.setTimeout('DS_map.removeOverlay(DS_marker_drag[0]);', 1000);
	  window.setTimeout('DS_map.removeOverlay(DS_marker_drag[1]);', 1000);
	  DS_polyline_drag = null;
      }

      // DS_map.removeOverlay(DS_marker[0]);
      var address = e;
      if (!geocoderService) {
	  geocoderService = new GClientGeocoder();
      }
      geocoderService.getLocations(e, function(addresses) {
	  if(addresses.Status.code != 200) {
	      // alert("reverse geocoder failed to find an address for " + latlng.toUrlValue());
	      // no data
	  } else { 
	      var result = addresses.Placemark[0];
	      // alert ("we got " + e + " " + result.address);
	      $('#from').attr("value",result.address);
	      DS_goDirections();
	  }
      });

  });

  // show route during dragging
  GEvent.addListener(marker, "drag", function(e) {
      if (DS_polyline_drag) {
	  // remove old polyline
	  DS_map.removeOverlay(DS_polyline_drag);
	  DS_map.removeOverlay(DS_marker_drag[0]);
	  DS_map.removeOverlay(DS_marker_drag[1]);
       	  DS_polyline_drag = null;
      }
      // return;

      // debug ("dragging ...");
      if (!DS_directions_drag) {
 	  DS_directions_drag = new google.maps.Directions(DS_map, null);
      }
      // var opts = {getPolyline: true};
      var opts = {preserveViewport: true};
      DS_directions_drag.load('from: ' + e + ' to: ' + $('#to').val(),
			      opts );
      DS_polyline_drag = DS_directions_drag.getPolyline();
      // alert(DS_polyline_drag);
      DS_marker_drag[0] = DS_directions_drag.getMarker(0);
      DS_marker_drag[1] = DS_directions_drag.getMarker(1);

  });


  DS_marker[0] = marker;
  DS_map.addOverlay(marker);


  // end marker
  DS_marker[3] = DS_directions.getMarker(1);
  latlng = DS_marker[3].getLatLng();
  // DS_map.removeOverlay(DS_marker[3]);
  window.setTimeout('DS_map.removeOverlay(DS_marker[3])', 2500);
  
  var letteredIcon = new GIcon(baseIcon);
  index=1;
  var letter = String.fromCharCode("A".charCodeAt(0) + index);
  letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
  var marker = new GMarker(latlng, {draggable: true, icon: letteredIcon});
  GEvent.addListener(marker, "dragend", function(e) {
      // marker.openInfoWindowHtml("END -- Just bouncing along..." + e.lat());
      // route with new end

      if (DS_polyline_drag) {
 	  // remove old polyline
 	  DS_map.removeOverlay(DS_polyline_drag);
	  window.setTimeout('DS_map.removeOverlay(DS_marker_drag[0]);', 1000);
	  window.setTimeout('DS_map.removeOverlay(DS_marker_drag[1]);', 1000);
	  DS_polyline_drag = null;
      }

      var address = e;
      if (!geocoderService) {
	  geocoderService = new GClientGeocoder();
      }
      geocoderService.getLocations(e, function(addresses) {
	  if(addresses.Status.code != 200) {
	      // alert("reverse geocoder failed to find an address for " + latlng.toUrlValue());
	      // no data
	  } else { 
	      var result = addresses.Placemark[0];
	      // alert ("we got " + e + " " + result.address);
	      $('#to').attr("value",result.address);
	      DS_goDirections();
	  }
      });
// V3
//       geocoderService.geocode({ 'address': address }, function(results, status) {
// 	  if (status == google.maps.GeocoderStatus.OK) {
// 	      var latlng = results[0].geometry.location;
// 	      alert(latlng + " " + results[0]);
// 	  } else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
// 	      alert("Address not found");
// 	  } else {
// 	      alert("Address lookup failed");
// 	  }
//       });


  });

  DS_marker[1] = marker;
  DS_map.addOverlay(marker);

  // show route during dragging
  GEvent.addListener(marker, "drag", function(e) {
      if (DS_polyline_drag) {
	  // remove old polyline
	  DS_map.removeOverlay(DS_polyline_drag);
	  DS_map.removeOverlay(DS_marker_drag[0]);
	  DS_map.removeOverlay(DS_marker_drag[1]);
	  DS_polyline_drag = null;
      }
      // return;

      // debug ("dragging ...");
      if (!DS_directions_drag) {
 	  DS_directions_drag = new google.maps.Directions(DS_map, null);
      }
      // var opts = {getPolyline: true};
      var opts = {preserveViewport: true};
      DS_directions_drag.load('from: ' + $('#from').val() + ' to: ' + e,
			      opts );
      DS_polyline_drag = DS_directions_drag.getPolyline();
      // alert(DS_polyline_drag);
      DS_marker_drag[0] = DS_directions_drag.getMarker(0);
      DS_marker_drag[1] = DS_directions_drag.getMarker(1);

  });

  if (g_conf_arr['show_pic1'] == 1) {
      // show_picture();
      clearTimeout(g_show_pic_to);
      g_show_pic_to = setTimeout("show_picture()", 1000);
  }
}

/**
 * Generates the DS_path and DS_step arrays from the global DS_directions
 * instance
 * 
 * NOTE: only the first route is used
 */
function DS_buildPathStepArrays() {
  // begin processing the directions' steps and path
  DS_steps = [];
  DS_path = [];
  
  var polyline = DS_directions.getPolyline();
  var route = DS_directions.getRoute(0);
  var numPolylineVertices = polyline.getVertexCount();
  var numSteps = route.getNumSteps();
  
  for (var i = 0; i < numSteps; i++) {
    var step = route.getStep(i);
    
    var firstPolylineIndex = step.getPolylineIndex();
    
    var lastPolylineIndex = -1;
    if (i == numSteps - 1)
      lastPolylineIndex = numPolylineVertices - 1;
    else {
      // subtract 2 because the last vertex of a step is duplicated
      // as the first vertex of the next step in google.maps.Directions results
      lastPolylineIndex = route.getStep(i + 1).getPolylineIndex() - 2;
    }
    
    DS_steps.push({
      loc: step.getLatLng(),
      desc: step.getDescriptionHtml(),
      distanceHtml: step.getDistance().html,
      pathIndex: DS_path.length
    });
    
    var stepDistance = step.getDistance().meters;
    for (var j = firstPolylineIndex; j <= lastPolylineIndex; j++) {
      var loc = polyline.getVertex(j);
      var distance = (j == numPolylineVertices - 1) ?
                     0 : DS_geHelpers.distance(loc, polyline.getVertex(j + 1));
      
      DS_path.push({
        loc: loc,
        step: i,
        distance: distance,
        
        // this segment's time duration is proportional to its length in
        // relation to the length of the step
        duration: step.getDuration().seconds * distance / stepDistance
      });
    }
  }
}

/**
 * Generates the HTML elements for the left directions list
 * 
 * NOTE: only the first route is used
 */
function DS_buildDirectionsList() {
  var start = DS_directions.getRoute(0).getStartGeocode();
  var end = DS_directions.getRoute(0).getEndGeocode();
  
  $('#route-details').append($(
      '<div id="dir-start">' + start.address + '</div>'));
  
  $('#route-details').append('<ol>');
  for (var i = 0; i < DS_steps.length; i++) {
    $('#route-details ol').append($(
        '<li class="dir-step" id="dir-step-' + i + '">' +
        DS_steps[i].desc +
        '<div class="note">' + DS_steps[i].distanceHtml + '</div>' + 
        '</li>'));
  }
  
  $('#route-details').append($(
      '<div id="dir-end">' + end.address + '</div>'));
  
  // handle events on the directions list
  $('#dir-start').click(function() {
    DS_flyToLatLng(new google.maps.LatLng(
                   start.Point.coordinates[1], start.Point.coordinates[0]));
  });
  
  $('#dir-end').click(function() {
    DS_flyToLatLng(new google.maps.LatLng(
                   end.Point.coordinates[1], end.Point.coordinates[0]));
  });
  
  $('#route-details li').click(function() {
    var id = $(this).attr('id');
    if (id == 'dir-start' || id == 'dir-end')
      return;
    
    var stepNum = parseInt(id.match(/dir-step-(\d+)/)[1]);
    DS_flyToStep(stepNum);
  });
}

/**
 * Fly the camera to the given step index in the route, and highlight it in
 * the directions list
 * @param {number} stepNum The 0-based step index to fly to
 */
function DS_flyToStep(stepNum) {
  var step = DS_steps[stepNum];
  
  var la = DS_ge.createLookAt('');
  la.set(step.loc.lat(), step.loc.lng(),
      0, // altitude
      DS_ge.ALTITUDE_RELATIVE_TO_GROUND,
      DS_geHelpers.getHeading(step.loc, DS_path[step.pathIndex + 1].loc),
      60, // tilt
      50 // range (inverse of zoom)
      );
  DS_ge.getView().setAbstractView(la);
  
  DS_highlightStep(stepNum);

  // $("div.demo").scrollTop(300);
  // p.offset();

  DS_map.panTo(step.loc);
  SyncViews_gloc(step.loc);

}

/**
 * Highlights the given step in the left directions list
 * @param {number} stepNum The 0-based step index to highlight in the
 *     directions list
 */
function DS_highlightStep(stepNum) {
  $('#route-details li').removeClass('sel');
  $('#route-details #dir-step-' + stepNum).addClass('sel');

  str = $('#route-details #dir-step-' + stepNum).html();
  p = str.search("<div");
  str = str.substr(0, p);
  str = str.replace(/<[^>]*>/g, "");
  str = str.substr(0, 99);   // limit for tts
  // alert(str);
  PlayAudio(str);
}

/**
 * Move the camera to the given location, staring straight down, and unhighlight
 * all items in the left directions list
 * @param {google.maps.LatLng} loc The location to fly the camera to
 */
function DS_flyToLatLng(loc) {
    if (DS_ge) {
	var la = DS_ge.createLookAt('');
	la.set(loc.lat(), loc.lng(),
	       10, // altitude
	       DS_ge.ALTITUDE_RELATIVE_TO_GROUND,
	       90, // heading
	       0, // tilt
	       200 // range (inverse of zoom)
	       );
	DS_ge.getView().setAbstractView(la);
    }
    
    $('#route-details li').removeClass('sel');
    
    SyncViews_gloc(loc);

}

/**
 * Formats a time given in seconds to a human readable format
 * @param {number} s Time in seconds
 * @return {string} A string formatted in hh:mm form representing the given
 *     number of seconds
 */
function DS_formatTime(s) {
  var m = Math.floor(s / 60);
  s %= 60;
  var h = Math.floor(m / 60);
  m %= 60;
  s = Math.round(s);
  return ((h < 10) ? ('0' + h) : h) + ':' + ((m < 10) ? ('0' + m) : m);
}

/**
 * Simulator controls
 * @param {string} command The control command to run
 * @param {Function?} opt_cb Optional callback to run when the command
 *     completes its task
 */
function DS_controlSimulator(command, opt_cb) {
  switch (command) {
    case 'reset':
      if (DS_simulator)
        DS_simulator.destroy();
      
      // create a DDSimulator object for the current DS_path array
      // on the DS_ge Earth instance
      DS_simulator = new DDSimulator(DS_ge, DS_path, {
        // as the simulator runs, reposition the map on the right and the
        // car marker on the map, and update the status box on the bottom
        on_tick: function() {
          DS_map.panTo(DS_simulator.currentLoc);
          DS_mapMarker.setLatLng(DS_simulator.currentLoc);
          
          if (DS_simulator) {
            $('#status').html(
                '<strong>Time:</strong> ' +
                  DS_formatTime(DS_simulator.totalTime) + '<br/>' +
                '<strong>Distance:</strong> ' +
                  (Math.round(
                      DS_simulator.totalDistance / 1609.344 * 10) / 10) +
                  ' mi' + '<br/>' +
                '<strong>Current Speed:</strong> ' +
                  Math.round(DS_simulator.currentSpeed / 0.44704) + 'mph') +
                  '<br/>';
          }
        },
        
        // when the simulator moves to a new step (specified as an integer
        // index in DS_path items), highlight that step in the directions
        // list
        on_changeStep: function(stepNum) {
          DS_highlightStep(stepNum);
        }
      });
      
      if (!DS_mapMarker) {
        // create vehicle location indicator on map
        var icon = new google.maps.Icon();
        icon.iconSize = new google.maps.Size(42, 42);
        icon.iconAnchor = new google.maps.Point(21, 21);
	if (g_maps_icon_url && g_maps_icon_url != "") {
	    icon.image = g_maps_icon_url;
	} else {
	    icon.image = 'smart_marker.png';
	}
	DS_mapMarker_icon = icon;
        DS_mapMarker = new google.maps.Marker(
                       DS_simulator.currentLoc, {icon: icon});
        DS_map.addOverlay(DS_mapMarker);
      }
      
      DS_map.setZoom(13);
      DS_mapMarker.setLatLng(DS_simulator.currentLoc);
      
      DS_updateSpeedIndicator();
      DS_simulator.initUI(opt_cb);

      // reset birds view
      // bmap.SetMapMode(VEMapMode.Mode2D);
      // g_simulator_add_heading = 0;
      $('#butt_start').val("Start");

      break;
    
    case 'start':
      // $('#butt_start').css("background-color", "");
      // show_hide_drive_ctrl("close");
      if (!DS_simulator)
        DS_controlSimulator('reset', function() {
          DS_simulator.start();
          if (opt_cb) opt_cb();
        });
      else {
        DS_simulator.start();
        if (opt_cb) opt_cb();
      }
      break;
    
    case 'pause':
      if (DS_simulator)
        DS_simulator.stop();

      $('#butt_start').val("Resume");
      
      if (opt_cb) opt_cb();
      break;
    
    case 'resume':
      if (DS_simulator)
        DS_simulator.start();
      
      if (opt_cb) opt_cb();
      break;
    
    case 'slower':
      if (DS_simulator && DS_simulator.options.speed > 0.125) {
        DS_simulator.options.speed /= 2.0;
	g_getcar_speed = DS_simulator.options.speed;
        DS_updateSpeedIndicator();
      }
      break;
    
    case 'faster':
      if (DS_simulator && DS_simulator.options.speed < 32.0) {
        DS_simulator.options.speed *= 2.0;
	g_getcar_speed = DS_simulator.options.speed;
	// alert("speed " + DS_simulator.options.speed);
        DS_updateSpeedIndicator();
      }
      break;
  }
}

/**
 * Update the speed indicator in the simulation controls box to reflect
 * the current simulation speed multiplier
 */
function DS_updateSpeedIndicator() {
  if (DS_simulator.options.speed < 1)
    $('#speed-indicator').text('1/' +
        Math.floor(1 / DS_simulator.options.speed) + 'x');
  else
    $('#speed-indicator').text(Math.floor(DS_simulator.options.speed) + 'x');
}

g_last_menuitem="";
function _doFold(id, delay) {
    if (!g_loaded) return;

    // $("#placeholder").toggle();
    // alert(" fold ");
    // $("#"+id).toggle("fold", {size: 15 }, 800); 
    if (!delay) {
	delay = 800;
    }
    // $("#"+id).toggle("blind", {direction: "vertical" }, 800); 
    // $("#"+id).slideToggle("fast");
    if (g_last_menuitem != "") {
	if (g_last_menuitem != id) {
	    $("#"+g_last_menuitem).slideToggle();
	    $("#"+id).slideToggle();
	    g_last_menuitem=id;
	} else {
	    $('#iframe_shim').toggle();
	    $("#"+id).slideToggle();
	    g_last_menuitem="";
	}
    } else {
	$('#iframe_shim').toggle();
	$("#"+id).slideToggle();
	g_last_menuitem=id;
    }

    if (id == "config") {
	// config tabs
	$( "#conftabs" ).tabs();
    }


    // hide_birds();
}

function _undoFold(id) {
    // $("#"+id).toggle("fold", {size: 15 }, 800); 
    $('#iframe_shim').toggle();

    $("#"+id).toggle("blind", {direction: "vertical" }, 800); 
    g_last_menuitem="";

    // $("#placeholder").hide();
}


var g_hide_birds_save_top = 0;

// parseFloat(top.replace("px", "")) < clientHeight) {

function hide_birds(yes) {

    return;

    try {
	// top=$('#birdv1').css("top");
	top = document.getElementById("birdv1").style.top;
    } catch (err) {}

    var clientHeight = document.documentElement.clientHeight;

    // alert (clientHeight + " " + top );

    // var top=$('#birdv1').position().top;
    if (g_hide_birds_save_top == 0 || yes) {
	n_top = clientHeight + "px";
	// alert ("top = 0 " + clientHeight + " top:" + top + " XX " + n_top);
	// $('#birdv1').css("top", n_top);
	if (navigator.userAgent.match("MSIE")) {
	    try {
		// document.getElementById("birdv1").style.top = n_top;
		setTimeout('document.getElementById("birdv1").style.top = "'+n_top+'"', 300);  
	    } catch (err) {}
	} else {
	    $('#birdv1').css("top", n_top);
	}
	if (g_hide_birds_save_top == 0) {
	    if (top > 0) {
		g_hide_birds_save_top=top;
	    } else {
		lowerh = Math.round(clientHeight * 0.42);
		g_hide_birds_save_top = (clientHeight - (lowerh + 26)).toString() + 'px' ;      
	    }
	    // alert("new g_hide_birds_save_top " + g_hide_birds_save_top);
	}
	$('#speaker_div').hide();
    } else {
	n_top = g_hide_birds_save_top ;
	// alert ("back " + clientHeight + " X1 " + top + " X2 " + String(n_top));
	// $('#birdv1').css("top", n_top);
	try {
	    document.getElementById("birdv1").style.top = n_top;
	} catch (err) {}
	g_hide_birds_save_top = 0;
	//if (navigator.userAgent.match("Chrome")) {
	    // alert("after resize");
	    // onresize();
	//}

	if (g_canPlayAudioMP3) {
	    $('#speaker_div').show();
	}
    }
}

    

// Used with mouse move and lookat
function SyncViews(kmlEventorLookAt) {

    lat = 0;
    try {
	head = kmlEventorLookAt.getHeading();
	la = kmlEventorLookAt;
	// alert ("1 " + la);
    } catch (Error) {
    	la = DS_ge.getView().copyAsLookAt(DS_ge.ALTITUDE_RELATIVE_TO_GROUND);
	// alert ("2 " + la);
    };
    
    lat = la.getLatitude();
    lng = la.getLongitude();
    curHeading = la.getHeading();
    
    // pos GMap
    Gp = new GLatLng(lat, lng);
    
    // this.currentLoc = Gp;
    
    // alert(Gp);
    DS_map.panTo(Gp);
    // DS_map.setCenter(Gp, 17);
    
    //
    // alert(myPano);
    if (!myPano) {
	createPano();
    }
    
    // alert(Gp);
    myPOV = {yaw:curHeading,pitch:0};
    // myPano.setLocationAndPOV(Gp, myPOV);
    myPano.setLocationAndPOV(Gp, myPOV);
    myPano.panTo(myPOV);
    // alert(res);

    // pos BirdV
    // p = new VELatLong(kmlEvent.getLatitude(), kmlEvent.getLongitude());
    p = new VELatLong(lat, lng);
    
    // bmap.PanToLatLong(p);
    // bmap.SetBirdseyeScene(p);
    
    if (curHeading >= 315 || curHeading < 45) {
	// bmap.SetBirdseyeOrientation(VEOrientation.North);
	bmap.SetBirdseyeScene(p,VEOrientation.North)
	    dir = "north";
    }
    if (curHeading < 135 && curHeading >= 45) {
	// bmap.SetBirdseyeOrientation(VEOrientation.East);
	bmap.SetBirdseyeScene(p,VEOrientation.East)
	    dir = "east";
    }
    if (curHeading < 225 && curHeading >= 135) {
	// bmap.SetBirdseyeOrientation(VEOrientation.South);
	bmap.SetBirdseyeScene(p,VEOrientation.South)
	    dir = "south";
    }
    if (curHeading < 315 && curHeading >= 225) {
	// bmap.SetBirdseyeOrientation(VEOrientation.West);
	bmap.SetBirdseyeScene(p,VEOrientation.West)
	    dir = "west";
    }
    
    // alert("curHeading " + curHeading + " " + dir);
    
    // set link
    set_linkto();


    // show center marker and time out
    DS_ge.getFeatures().appendChild(centerOverlay);
    // g_conf_arr[command] = 1;

    // show location 
    show_location(Gp);
}

var svClient = null;
function createPano() {
    // svClient = new GStreetviewClient();
    myPano = new GStreetviewPanorama(document.getElementById("strv1"));
    GEvent.addListener(myPano, "initialized", function(loc) {
	// debug("streetv init..ed");
	return;
    });
    GEvent.addListener(myPano, "error", function(errorCode) {
	// alert ("The requested panorama could not be displayed");
	// alert (errorCode);
	if (errorCode == 603) {
	    // alert("Error: Flash doesn't appear to be supported by your browser");
	    return;
	}
	if (errorCode == 600) {
	    // alert("no pano here");
	    // $('#str_info').fadeIn();
	    myPano.hide();
	    return;
	}
	
    });
}

// used by init of driving
function SyncViews_gloc(loc, ctrl_earth) {

    // pos GMap
    Gp = loc;
    
    // this.currentLoc = Gp;
    
    // DS_map.panTo(Gp);
    // DS_map.setCenter(Gp, 17);
    
    //
    if (!myPano) {
	createPano();
    }
    
    if (DS_ge) {
	la = DS_ge.getView().copyAsLookAt(DS_ge.ALTITUDE_RELATIVE_TO_GROUND);
	var curHeading = la.getHeading();

	if (ctrl_earth) {
	    la.setLatitude(loc.lat());
	    la.setLongitude(loc.lng());
	    DS_ge.getView().setAbstractView(la);
	}

    }
    
    // alert("heading "  + curHeading);
    if (!curHeading) {
	curHeading = 90;
    }
    
    myPOV = {yaw:curHeading,pitch:0};
    myPano.setLocationAndPOV(Gp, myPOV);
    
    // pos BirdV
    vep = new VELatLong(loc.lat(), loc.lng());
    p=vep;
    
    if (curHeading >= 315 || curHeading < 45) {
	// bmap.SetBirdseyeOrientation(VEOrientation.North);
	bmap.SetBirdseyeScene(p,VEOrientation.North)
	    dir = "north";
    }
    if (curHeading < 135 && curHeading >= 45) {
	// bmap.SetBirdseyeOrientation(VEOrientation.East);
	bmap.SetBirdseyeScene(p,VEOrientation.East)
	    dir = "east";
    }
    if (curHeading < 225 && curHeading >= 135) {
	// bmap.SetBirdseyeOrientation(VEOrientation.South);
	bmap.SetBirdseyeScene(p,VEOrientation.South)
	    dir = "south";
    }
    if (curHeading < 315 && curHeading >= 225) {
	// bmap.SetBirdseyeOrientation(VEOrientation.West);
	bmap.SetBirdseyeScene(p,VEOrientation.West)
	    dir = "west";
    }
    
    // alert("pan to " + vep);
    // bmap.PanToLatLong(vep);
    // bmap.SetCenterAndZoom(vep, 13);
    // bmap.SetBirdseyeScene(vep);

    g_currentLoc = loc;

}

var g_result_address, g_showlocation = null ;

function show_location (loc) {

    if (! g_showlocation) {
	g_showlocation = new GClientGeocoder();
	g_showlocation.setBaseCountryCode("US");
	// alert (g_showlocation.getBaseCountryCode());
    }

    // get address information
    g_showlocation.getLocations(loc, function(addresses) {
	if(addresses.Status.code != 200) {
	    // alert("reverse geocoder failed to find an address for " + latlng.toUrlValue());
	    // no data
	} else { 
	    var result = addresses.Placemark[0];
	    str = '<fieldset style="font-size: 85%; color: #fbfbfb; background: #5f5f5f url(\'graphs/bg.png\') repeat-x scroll;">';
    	    str += '<legend><b>Location Information</b></legend>';
	    // str += '<ul style="margin-left: -2em;" ><li>' + result.address ;
	    str += '<li style="margin-left: 12px;">' + result.address ;
	    g_result_address = result.address;
	    // alert(g_result_address);
	    // str += '<li style="margin-left: 12px;"> <a href="#" style="display: inline;" onclick="show_loc_info(\'tweets\');" id="show_tweets">Show local Twitter Tweets</a><img height="12" id="tweet_wait" style="background-color: white; display: none; margin-left: 3px; " src="wait-rot.gif" /> </li>';

	    ///str += '<li> <input style="display: inline;" type="submit" onclick="show_zestimate();" id="show_zestimate" value="Show ZEstimate House Value"/></li>';
	    //if (navigator.userAgent) {
	    //	var s = navigator.userAgent;
	    //	if (s.match("gmapsg")) {
		    // get_zestimate(result);
		    // var t = str.match("gmapsg");
		    // alert(t);
	    str += '<li style="margin-left: 12px;"> <a href="#" style="display: inline;" onclick="show_loc_info(\'zestimate\');" id="show_zestimate">Zillows Zestimate<sup>&copy;</sup> Home Value</a><img height="12" id="zest_wait" style="background-color: white; display: none; margin-left: 3px;" src="wait-rot.gif" /> </li>';
	    //}
	    //}

	    // <br/> <br/>
	    str += '</li><li style="margin-left: 12px;">(Lat, Long): <br/>' + loc  ;
	    str += '</li><li style="margin-left: 12px;">Copy this location to directions: <a href="javascript: set_dir(\'from\',\''+loc+'\')">From</a>, <a href="javascript: set_dir(\'to\',\''+loc+'\')">To</a></li>';
	    str += ' <input style="display: block; margin-top: 9px;" type="submit" onclick="show_route_details();" id="showlocclose" value="Close Location Information"/>';
            str += "    </fieldset>";

	    str += '<fieldset style="font-size: 85%; color: #fbfbfb; background: #5f5f5f url(\'graphs/bg.png\') repeat-x scroll;">';
    	    str += '<legend><b>Incident Information</b></legend>';
	    str += ' <input style="display: block; margin-top: 3px;" type="submit" onclick="get_incidents();" id="showincid" value="Show Incidents on Google Map"/>';
            str += '<div id="incid_div"></div><div id="incid_div2"></div>    </fieldset>';
	    
	    // alert (str);
	    $('#location-details').html(str);
	    $('#location-details').css("display", "block");
	    // $('#location-details').slideToggle();
	    $('#route-details').css("display", "none");
	    $('#speaker_div').hide();
	    
	    var groundAltitude = DS_ge.getGlobe().getGroundAltitude(loc.lat(), loc.lng());
	    console.log("height is " + groundAltitude +"m");
	    // alert(groundAltitude);

	}
    });
}

function set_dir(which,loc) {
    loc=String(loc);
    loc=loc.substr(1, loc.length-2);
    $('#'+which).val(loc);
}

function show_route_details() {
    $('#route-details').css("display", "block");
    $('#location-details').css("display", "none");
    if (g_canPlayAudioMP3) {
	$('#speaker_div').show();
    }
    g_result_address = null;
    if (!g_conf_arr['show_center']) {
	DS_ge.getFeatures().removeChild(centerOverlay);
    }
}

function get_location(nofold) {

    if (!DS_ge) {
	setTimeout("get_location("+nofold+")", 500);
	return;
    }

    //if (!window.geocodeLocation) {
    // window.geocodeLocation = 'City name, country, latitude and longitude, etc';
    //}
    // window.geocodeLocation = prompt('Enter a location', window.geocodeLocation);

    // reset clear func
    $('#get_location').attr("onFocus", "");

    str = $('#get_location').val();
    if (str.match("lookat")) {
	arr = str.split(":");
	var lookAt = DS_ge.createLookAt('');
	// alert(arr + " " + arr[1]);
	lookAt.set(Number(arr[1]), Number(arr[2]), Number(arr[6]), 
		   DS_ge.ALTITUDE_RELATIVE_TO_GROUND, 
		   Number(arr[5]), Number(arr[4]), Number(arr[3]));
	// lookAt.set(Number(arr[1]), Number(arr[2]), 10, 		   DS_ge.ALTITUDE_RELATIVE_TO_GROUND, 		   0, 0, 1500);
	
	DS_ge.getView().setAbstractView(lookAt);
	SyncViews(lookAt);
	set_linkto(lookAt);
    } else {
	var geocoder = new google.maps.ClientGeocoder();
	// alert(str);
	// http://www.seeing-stars.com/Live/StarsAddresses_P.shtml
	geocoder.getLatLng(str, function(point) {
	    if (point) {
		if (DS_ge) {
		    var lookAt = DS_ge.createLookAt('');
		    lookAt.set(point.y, point.x, 10, 
			       DS_ge.ALTITUDE_RELATIVE_TO_GROUND, 
			       0, 0, 1500);
		    DS_ge.getView().setAbstractView(lookAt);
		}
		DS_map.panTo(point);
		SyncViews_gloc(point);
		// set link
		set_linkto(lookAt);
		$('#route-details').empty();
		$('#simulator-form input').attr('disabled', 'disabled');
		// $('#goto_status').html("");
		// $('#goto_status').css("background-color", "");
		// $('#menu_goto').css("background-color", "");
	    } else {
		// $('#goto_status').show();
		// $('#goto_status').html("Could not resolve the address ...");
		// $('#goto_status').css("background-color", "#928728");
		// _undoFold("goto"); 
		// hide_birds();
		// $('#menu_goto').css("background-color", "#922828");
	    }
	});
    }

    if (!nofold) {
	// _undoFold("goto");
	_doFold("goto");
    }
}

///////////////////////////////////////////////////////////////
// init
// 
var g_model_url = "";
var g_driver_mode = "";
var g_man_speed_ctrl = 0;

function init_conf() {
    // init street overlay
    g_conf_arr['streetv_overlay'] = 0;
    g_conf_arr['show_hide_drive_ctrl'] = 1;
    g_cam_follows_car = getCookie("cam_follows_car");
    if (g_cam_follows_car && g_cam_follows_car == 0) {
	// alert(g_cam_follows_car);
	g_conf_arr['cam_follows_car'] = 0;
	g_cam_follows_car = 0;
	document.getElementById("toggle_cam_follows_car").checked=false;
    } else {
	g_conf_arr['cam_follows_car'] = 1;
	g_cam_follows_car = 1;
    }

    // init radio
    // also relevant for setting checkboxes
    // no radio right now g_conf_arr['radio'] = 0;  

    // alert(g_conf_arr + " YX " + g_conf_arr['traffic'] );

    // $("#streetv_refresh_rate").val("1.0");
    // $("#streetv_refresh_rate").val("0.5");
    // alert ("init_conf");
    g_streetv_refresh_rate = getCookie("streetv_refresh_rate");
    if (g_streetv_refresh_rate) {
	$("#streetv_refresh_rate").val(g_streetv_refresh_rate);
    } else {
	$("#streetv_refresh_rate").val("0.42");
	g_streetv_refresh_rate = 0.42;
    }
    // check for maps_icon_url
    g_maps_icon_url = getCookie("maps_icon_url");
    if (g_maps_icon_url && g_maps_icon_url != "") {
	$('#maps_icon_url').val(g_maps_icon_url);
    }
    gtilt = 80;
    $("#ge_tilt").val(gtilt);
    grange = 10;
    $("#ge_range").val(grange);

    // document.getElementById("tr_smart").checked=true;
    document.getElementById("tr_q7").checked=true;
    
    if (navigator.userAgent) {
	var str = navigator.userAgent;
	if (str.match("gmapsg")) {
	    // setTimeout("get_tweets()", 5000);
	}
    }

    // show picture instead of birds view
    g_pic1_refresh_rate = getCookie("pic1_refresh_rate");
    if (!g_pic1_refresh_rate) {
	g_pic1_refresh_rate = 15000;
    }
    g_show_pic1 = getCookie("show_pic1");
    if (g_show_pic1 && g_show_pic1 == 1) {
	g_conf_arr['show_pic1'] = 1;
	// show_picture();
	g_show_pic_to = setTimeout("show_picture()", 7000);
	$('#toggle_birdv_pic1_a').html("Birds View");
    } else {
	// default is to show birds view
	g_conf_arr['show_pic1'] = 0;
    }
    $('#div_toggle_birdv_pic1').fadeTo('fast', 0.8);

    // update checkboxes
    for (conf in g_conf_arr) {
	t_conf="toggle_" + conf;
	// console.log(conf + " " + t_conf + " ");
	if (document.getElementById(t_conf)) {
	    if (g_conf_arr[conf]) {
		document.getElementById(t_conf).checked=true;
	    } else {
		document.getElementById(t_conf).checked=false;
	    }
	}
    }

    // done here as jquery+ui is loaded via google loader
//     $.getScript("ui.slider.js", function(){
// 	// $('#car_size_slider').slider({ min: 1 });
// 	$('#car_size_slider').slider({max: 10});
// 	$('#car_size_slider').slider('option', 'step', 0.1);
// 	// $('#car_size_slider').slider('option', 'min', 1.0);

// 	// $('#car_size_slider').bind('slidechange', function(ev, ui) {


//     });

    $( "#car_size_slider" ).slider();
    $('#car_size_slider').bind('slide', function(ev, ui) {
	val = $("#car_size_slider").slider('value');
	
	sc = model_car.getScale();
	sc.set(val,val,val);
	model_car.setScale(sc);
	
	$("#car_size_str").html('Car size factor is ' + val + '.');
    });

    $('#menu_tweet_id').draggable();
    // $('#config').draggable();
    // $('#about').draggable();
    // $('#goto').draggable();
    // $('#tour').draggable();
    
    $('#location_details_wrapper').draggable();

    // save config et al.
    time = (new Date).getTime();
    // alert (time);
    time_saved = getCookie("saved_time");
    if (time_saved) {
	sec_diff = (time - time_saved)/1000;
	m = Math.round(sec_diff/60)%60;
	h = Math.round(sec_diff/3600)%24;
	d = Math.round(sec_diff/3600/24);
	// last = "d: " + d + " h: " + h + " m: " + m;
	last = "D:H:M: " + d + ":" + h + ":" + m;
	// alert ("m: " + m + " h: " + h + " " + sec_diff/60);
	// alert (last);
	g_own_tour_arr_str= getCookie("own_tour_arr");
	if (g_own_tour_arr_str) {
	    // alert(g_own_tour_arr_str);
	    g_own_tour_arr=g_own_tour_arr_str.split("~");
	    show_own_tours();
	}
	store_str = getCookie("store");
	// alert(g_urlsettings);
	if (store_str && !g_urlsettings) {
	    store_arr = store_str.split("|");
	    if (store_arr.length > 0) {
		// alert(store_arr + " XX " + store_arr[0]);
		$('#from').attr("value",store_arr[0]);
		$('#to').attr("value",store_arr[1]);
		// gtilt = Number(v);
		// $("#ge_tilt").val(v);
		// grange = Number(v);
		// $("#ge_range").val(v);
		
		// and start
		DS_goDirections();
	    }
	}
	if (Math.round(sec_diff/60) > 10 ) { 
	    if (!getCookie("gaiagi_feedback")) {
		// show_welcome(last);
	    }
	    pageTracker._trackEvent('Driver', 'Last_Visit',last);	
	}
    }
    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
    setCookie("saved_time", time, t);

    // UI Settings
    // uncomment the next line to make drive ctrl resizable
    // $("#drive_ctrl_div").resizable();
    $("#drive_ctrl_div").bind("resize", function(event, ui) {
	// console.log("resize: " + $("#drive_ctrl_div").innerWidth());
	$("#iframe_shim_drive_ctrl").css({width: (21 + $("#drive_ctrl_div").innerWidth()) + 'px'});
	});
    // $("#iframe_shim_drive_ctrl").resizable();
    // $("#drive_ctrl_div").draggable();
    // $("#iframe_shim_drive_ctrl").draggable();

    // $("#earth").resizable();
    // $("#map-container").resizable();
    // $("#strv1").resizable();

    // config tabs
    $("#conftabs").tabs();

    // tour tabs
    $( "#tourtabs" ).tabs();

    // speed slider
    $( "#car_speed_slider" ).slider({ min: 5, max: 101 });
    $('#car_speed_slider').bind('slide', function(ev, ui) {
	var val;
	val = $("#car_speed_slider").slider('value');

	g_man_speed_ctrl = 1;

	// display speed
	// console.log("speed .." + val);
	$('#speed_display_ctrl').html(val + "mph");

	// set speed
	g_driver_calc_speed_save = val * 1.609344; // in kmh

    });


    // init car settings
    gmapsg = gup("gmapsg");
    // console.log("gmapsg = " + gmapsg + " " + window.location.href);
    if (gmapsg != "") {
	// console.log("setting spinning bike ...");
	g_driver_mode = "spinning_bike";
	g_model_url = 'http://www.gaiagi.com/driving-simulator/kml/bike_woman.kmz';
	g_simulator_add_heading = 180;
	g_car_scale = 2.4;
	g_maps_icon_url = 'graphs/Bicycle-Green-2-icon.png';
	$('#maps_icon_url').val(g_maps_icon_url);
	if (DS_mapMarker_icon) {
	    set_maps_icon();
	    // DS_mapMarker_icon.image=g_maps_icon_url;
	    console.log("setimg", g_maps_icon_url);
	    DS_mapMarker.setImage(g_maps_icon_url);
	}
    } else {
	g_driver_mode = "car";
	g_model_url = 'http://www.gaiagi.com/driving-simulator/kml/audiq7.kmz';
	g_simulator_add_heading = 180;
	g_car_scale = 1.9;
	g_maps_icon_url = 'graphs/ferrari-icon.png';
	$('#maps_icon_url').val(g_maps_icon_url);
	g_driver_calc_speed_init = 0;
    }

}

var g_own_tour_arr = [];
function store_own_tour() {
    // store the tour from the present from and to values
    from = $('#from').val();
    to = $('#to').val();
    // text = "my tour";
    text = prompt("Please give your tour a name:", "");
    if (text) {
	g_own_tour_arr.push(from+"|"+to+"|"+text);
	var t = new Date(); t.setDate(t.getDate() + (2 * 360));
	setCookie("own_tour_arr", g_own_tour_arr.join("~"), t);
	// $.cookie("own_tour_arr", g_own_tour_arr.join("~"), {expires: 365});
	// alert(g_own_tour_arr);
	show_own_tours();
	pageTracker._trackEvent('Driver', 'Tour_Store', g_own_tour_arr.length + ":"+text+"|"+from+"|"+to);	
    }
}

function show_own_tours() {
    var html = "<ul>";
    len = g_own_tour_arr.length;
    // alert(g_own_tour_arr.length);
    for (i=0; i<len; i++) {
	// alert(g_own_tour_arr[i]);
	str_arr = g_own_tour_arr[i].split("|");
	html+='<li><a title="Click on the link to load this tour" style="color: #222; font-size: 21px;" href="javascript: set_tour(\''+str_arr[0]+'\',\''+str_arr[1]+'\')">'+str_arr[2]+'</a> <span style="font-size: 80%; color: #222;">(<b>From</b> '+str_arr[0]+' <b>To</b> '+str_arr[1]+')</span>&nbsp;&nbsp;&nbsp; <a title="Remove this tour from your own tour list" href="javascript: remove_own_tour('+i+');">Remove</a><br/>';
	// alert(html);
    }
    $('#own_routes_content').html(html+"</ul>");
    $('#own_routes').fadeIn();
}

function remove_own_tour(item) {
    g_own_tour_arr.splice(item, 1);
    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
    setCookie("own_tour_arr", g_own_tour_arr.join("~"), t);
    show_own_tours();
}

function show_welcome() {
    // alert ("Welcome after " + last);
    // wmode="opaque"  <param NAME="wmode" VALUE="transparent">
    // <param name="wmode" value="opaque" />
    $('#gaiagi_welcome').draggable();
    $('#gaiagi_welcome').fadeIn();
    $('#settings_done').fadeIn('9000');
}

function close_welcome() {
    $('#gaiagi_welcome').fadeOut();
    // get answer
    response = document.getElementById('feedback').value;
    if (response != "") {
	// alert (response);
	setCookie("gaiagi_feedback", response, t);
	pageTracker._trackEvent('Driver', 'Feedback',response);	
    }
}

g_openclose_config = 0; // close
g_save_radio_top = 0;

function openclose_config(open) {
    // open = 1  : open

    if (open == 1 || g_openclose_config == 1) {
	// move radio away
	g_save_radio_top = $("#conf_radio").css("top");
	$("#conf_radio").css("top", "-300px");
	g_openclose_config = 0; // now closed
    } else {
	if (g_save_radio_top) {
	    $("#conf_radio").css("top", g_save_radio_top);
	}
	g_openclose_config = 1; // now open
    }
}

var g_cam_follows_car=1;
var g_show_hide_drive_ctrl_enabled=1;

function conf_handler(command, opt_cb) {
    switch (command) {
    case 'ge_roads':
	if (g_conf_arr[command]) {
	    DS_ge.getLayerRoot().enableLayerById(DS_ge.LAYER_ROADS, false);
	    g_conf_arr[command] = 0;
	} else {
	    DS_ge.getLayerRoot().enableLayerById(DS_ge.LAYER_ROADS, true);
	    g_conf_arr[command] = 1;
	}
	break;
	
    case 'ge_buildings':
	if (g_conf_arr[command]) {
	    DS_ge.getLayerRoot().enableLayerById(DS_ge.LAYER_BUILDINGS, false);
	    g_conf_arr[command] = 0;
	} else {
	    DS_ge.getLayerRoot().enableLayerById(DS_ge.LAYER_BUILDINGS, true);
	    g_conf_arr[command] = 1;
	}
	break;
	
    case 'ge_webcams':
	if (g_conf_arr[command]) {
	    DS_ge.getFeatures().removeChild(g_webcamLink);
	    g_conf_arr[command] = 0;
	} else {
	    DS_ge.getFeatures().appendChild(g_webcamLink);
	    g_conf_arr[command] = 1;
	}
	break;
	
    case 'show_center':
	if (g_conf_arr[command]) {
	    DS_ge.getFeatures().removeChild(centerOverlay);
	    g_conf_arr[command] = 0;
	} else {
	    DS_ge.getFeatures().appendChild(centerOverlay);
	    g_conf_arr[command] = 1;
	}
	break;

    case 'show_pic1':
	if (g_conf_arr[command]) {
	    show_birdsv();
	    g_conf_arr[command] = 0;
	    document.getElementById("toggle_show_pic1").checked=false;
	    $('#toggle_birdv_pic1_a').html("Show Pictures");
	    pageTracker._trackEvent('Picture', 'BirdsV_Picture', 'BirdsV');
	} else {
	    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
	    setCookie("show_pic1", 1, t);
	    document.getElementById("toggle_show_pic1").checked=true;
	    $('#toggle_birdv_pic1_a').html("Birds View");
	    show_picture();
	    g_conf_arr[command] = 1;
	    pageTracker._trackEvent('Picture', 'BirdsV_Picture', 'Picture');
	}
	break;

    case 'cam_follows_car':
	if (g_conf_arr[command]) {
	    g_conf_arr[command] = 0;
	    document.getElementById("toggle_cam_follows_car").checked=false;
	    g_cam_follows_car=0;
	    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
	    setCookie("cam_follows_car", 0, t);
	    // pageTracker._trackEvent('Picture', 'BirdsV_Picture', 'BirdsV');
	} else {
	    document.getElementById("toggle_cam_follows_car").checked=true;
	    g_cam_follows_car=1;
	    g_conf_arr[command] = 1;
	    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
	    setCookie("cam_follows_car", 1, t);
	    // pageTracker._trackEvent('Picture', 'BirdsV_Picture', 'Picture');
	}
	break;

    case 'show_hide_drive_ctrl':
	if (g_conf_arr[command]) {
	    g_conf_arr[command] = 0;
	    document.getElementById("toggle_show_hide_drive_ctrl").checked=false;
	    g_show_hide_drive_ctrl_enabled=0;
	    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
	    setCookie("show_hide_drive_ctrl_enabled", 0, t);
	} else {
	    document.getElementById("toggle_show_hide_drive_ctrl").checked=true;
	    g_show_hide_drive_ctrl_enabled=1;
	    g_conf_arr[command] = 1;
	    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
	    setCookie("show_hide_drive_ctrl_enabled", 1, t);
	    // pageTracker._trackEvent('Picture', 'BirdsV_Picture', 'Picture');
	}
	break;

    case 'show_sunplusatmo':
	if (g_conf_arr[command]) {
	    DS_ge.getSun().setVisibility(false);
	    DS_ge.getOptions().setAtmosphereVisibility(false);
	    DS_ge.getOptions().setScaleLegendVisibility(false);
	    g_conf_arr[command] = 0;
	} else {
	    DS_ge.getSun().setVisibility(true);
	    DS_ge.getOptions().setAtmosphereVisibility(true);
	    DS_ge.getOptions().setScaleLegendVisibility(true);
	    g_conf_arr[command] = 1;
	}
	break;

    case 'show_historical_satimg':
	if (g_conf_arr[command]) {
	    DS_ge.getTime().setHistoricalImageryEnabled(false);
	    g_conf_arr[command] = 0;
	} else {
	    // show historical sats
	    DS_ge.getTime().setHistoricalImageryEnabled(true);
	    g_conf_arr[command] = 1;
	}
	break;




    case 'traffic':
	traff_overl = g_store_arr['traffic'];
	if (g_conf_arr[command]) {
	    traff_overl.hide();
	    g_conf_arr[command] = 0;
	} else {
	    traff_overl.show();
	    g_conf_arr[command] = 1;
	}
	break;
    case 'streetv_overlay':
	streetv_overlay = g_store_arr['streetv_overlay'];
	if (!streetv_overlay ) {
	    streetv_overlay = new GStreetviewOverlay();
	    g_store_arr['streetv_overlay'] = streetv_overlay;
	    g_conf_arr[command] = 0;
	}
	if (g_conf_arr[command]) {
	    DS_map.removeOverlay(streetv_overlay);
	    g_conf_arr[command] = 0;
	} else {
	    DS_map.addOverlay(streetv_overlay);
	    g_conf_arr[command] = 1;
	}
	break;

    case 'pan_layer':
	layer = g_store_arr[command];
	if (!layer) {
	    layer = new GLayer("com.panoramio.all");
	    // pan_layer.hide();
	    DS_map.addOverlay(layer);
	    g_store_arr[command] = layer;
	    g_conf_arr[command] = 0;
	}
	if (g_conf_arr[command]) {
	    layer.hide();
	    g_conf_arr[command] = 0;
	} else {
	    layer.show();
	    g_conf_arr[command] = 1;
	}
	break;

	
    case 'wikipedia_en_layer':
	layer = g_store_arr[command];
	if (!layer) {
	    layer = new GLayer("org.wikipedia.en");
	    // pan_layer.hide();
	    DS_map.addOverlay(layer);
	    g_store_arr[command] = layer;
	    g_conf_arr[command] = 0;
	}
	if (g_conf_arr[command]) {
	    layer.hide();
	    g_conf_arr[command] = 0;
	} else {
	    layer.show();
	    g_conf_arr[command] = 1;
	}
	break;


    case 'resize':
	// $('#route-details, #earth-container, #map-container').each(function() {
	$('#route-details, #map-container').each(function() {
	    $(this).resizable();
	});
	break;

  }
}

function gup( name )
{
    name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
    var regexS = "[\\?&]"+name+"=([^&#]*)";
    var regex = new RegExp( regexS );
    var results = regex.exec( window.location.href );
    if( results == null )
	return "";
    else
	return results[1];
}

var g_streetv_refresh_rate = 1.0;

function set_streetv_refresh_rate()
{
    g_streetv_refresh_rate = $('#streetv_refresh_rate').val();
    // alert(g_streetv_refresh_rate);
    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
    setCookie("streetv_refresh_rate", g_streetv_refresh_rate, t);
}

function set_ge_tilt()
{
    gtilt = Number($('#ge_tilt').val());
    // alert(gtilt);
}
function set_ge_range()
{
    grange = Number($('#ge_range').val());
    // alert(gtilt);
}

var g_maps_icon_url = null;
function set_maps_icon()
{
    var str = $('#maps_icon_url').val();
    // alert(str);
    DS_mapMarker.setImage(str);
    g_maps_icon_url = str;
    setCookie("maps_icon_url", str);
}

function set_linkto(lookAt)
{
    // alert(DS_ge);
    if (!lookAt) {
        lookAt = DS_ge.getView().copyAsLookAt(DS_ge.ALTITUDE_RELATIVE_TO_GROUND);
    }
    // alert(lookAt);
    str = "lookat:" + lookAt.getLatitude() + ":" +	lookAt.getLongitude() + ":" +	lookAt.getRange()+ ":" + lookAt.getTilt()+ ":" + lookAt.getHeading() + ":" +lookAt.getAltitude();
    u_str=encodeURI(str);
    url = window.location.href;
    p = url.indexOf("?");
    if (p >= 0) {
	url=url.substr(0, p);
    }
    link = url + "?goto=" + u_str;
    // alert(str + " XX " + u_str + " XX "  + link);
    // alert(link);
    document.getElementById('linkto').innerHTML=link;
    $("#menu_linkto").attr("href",link);
    
    // window.clipboardData.setData('Text',x);
}

var tours = new Array();

// tours['Rome'] = ["Piazza di San Giovanni in Laterano, 00184 Rome, Italy", 	 "Piazza Pio XII, 00193 Rome, Italy"];
// tours['Rome_Coll'] = ["Via Labicana, 123, 00184 Rome, Italy", 
// 		      "Via del Corso, 00186 Rome, Italy"];
// tours['Rome_Coll'] = ["Via Celio Vibenna, 00184 Rome, Italy", 
// 		      "Via del Corso, 00186 Rome, Italy"];

tours['TourDeFrance'] = ["42.99740133590968, -0.2858615330276171",
		     "42.90819020334117, 0.14506920610118046", 70, 5, "get_car(\'bike_woman.kmz\', 180, 1, 2.9);", "tr_bike_woman", 0.25 ];

tours['LasVegas_Strip'] = ["36.08103202245626, -115.17254496724203",
		     "36.12132085326543, -115.17184944672648", 80, 20];

tours['Rio'] = ["-22.987749151831704, -43.19483902497324",
		     "-22.992144253885726, -43.2336750611268", 80, 20];

tours['SanFran_GoldenG'] = ["37.78425111432667, -122.40776932205307",
		     "37.83242334026777, -122.4800308708255"];

tours['NYC_BroadWash'] = ["40.70347421279834, -74.01444254055448",
		     "40.730818118937634, -73.9976581845339", 75, 5];
tours['NYC_Manhattan'] = ["40.77258822545935, -73.97850212220527",
			  "40.75113049229677, -73.98761615305295", 80, 8];

tours['Yellowst_OldFaith'] = ["44.45756592215072, -110.82702215965769",
			  "43.47956103373383, -110.76220466809372", 80,25];

tours['Yosemite'] = ["33416-33546 State Highway 41, Coarsegold, CA 93614, USA",
			  "Southside Dr, Yosemite National Park, CA 95389, USA", 75,18];

tours['Sydney_RBG'] = ["-33.87665862130953, 151.20950383961033",
		       "-33.86039100436096, 151.21500544067766", 70,20];

tours['Rome_Coll'] = ["41.888399025348896, 12.490293105904655", 
		      "41.895873323812076, 12.482210224906497", 70,20];
tours['Rome_StPeter'] = ["41.89618239143567, 12.481984000037428", 
		      "41.90224770909521, 12.458481867951548", 70,20];

tours['London_Buck'] = ["51.50607656568169, -0.11780726566800583", 
		      "51.4998710776753, -0.14186677843090933", 75, 25];

tours['Paris_NotreD'] = ["48.85674233830997, 2.2901677652449024", 
		      "48.853750528660875, 2.3483101466450336", 75, 25];
tours['Paris_LaDef'] = ["48.87217801053316, 2.300045254870909", 
		     "48.89144651247034, 2.2406073846286603", 75, 25];

// VIEWS TOURS

tours['Big_Island'] = ["19.06622162227011, -155.61023332828387", 
		     "19.453105844538264, -155.18118899274373", 75, 25];

tours['Maui'] = ["20.625372807874168, -156.39079207222483", 
		     "20.622269456160222, -156.2191940260013", 75, 25];

tours['Maui_Haleakala'] = ["20.76894213449881, -156.3056148996895", 
		     "20.707567222549567, -156.25589617599618", 75, 25];

tours['D64France'] = ["44.33243459919532, 6.852875316877945", 
		     "44.31919370962187, 6.7962498239702285", 60, 20];

tours['Sunroadmontana'] = ["48.71714686702088, -113.77660175743998", 
		     "48.74281521596991, -113.4292573386165", 70, 20];

tours['alaskadalton'] = ["70.19886418249439, -148.4086904349003", 
		     "67.409205477048, -150.10850929048556", 80, 20];

tours['MtHakusan'] = ["36.25807616756249, 136.89160320243707", 
		     "36.260168090552924, 136.7510839619771", 65, 25];

tours['MtCook'] = ["-43.80163776514062, 170.11375611947517", 
		     "-43.73245667291097, 170.09290092686572", 65, 25];

tours['Transfagarasan'] = ["45.55119989226132, 24.59968525653304", 
		     "45.59476320480428, 24.619174525027383", 65, 30];


 

var g_getcar_func = null;
var g_getcar_speed = null;

function set_tour(tour, par2)
{
    // alert(tour + " " + par2);
    if (par2) {
	start = tour;
	end = par2; 
    } else {
	start = tours[tour][0];
	end = tours[tour][1];
	var v = tours[tour][2];
	// alert("X"+v+"x");
	if (v) {
	    gtilt = Number(v);
	    $("#ge_tilt").val(v);
	}
	v = tours[tour][3];
	if (v) {
	    grange = Number(v);
	    $("#ge_range").val(v);
	}
	var f = tours[tour][4];
	if (f) {
	    //  setTimeout(f, 3500);
	    // alert(f);
	    g_getcar_func = f;
	    document.getElementById(tours[tour][5]).checked=true;
	}
	var s = tours[tour][6];
	if (s) {
	    g_getcar_speed = s;
	}
    }
    // alert (start  + " XX " + end + " XX " + tours[tour]);
    $('#from').attr("value",start);
    $('#to').attr("value",end);

    // prepare the tour link
    set_tour_url();

    _doFold("tour");
    // hide_birds();
    DS_goDirections();
    // $.get("info.txt?t="+tour);
    pageTracker._trackEvent('Tour', tour);
}

function set_tour_url()
{
    str="?from=" + $('#from').val() + "&to=" + $('#to').val() + "&gtilt=" + gtilt + "&grange=" + grange;
    u_str=encodeURI(str);
    url = window.location.href;
    p = url.indexOf("?");
    if (p >= 0) {
	url=url.substr(0, p);
    }
    link = url + u_str;
    // alert(str + " XX " + u_str + " XX "  + link);
    // alert(link);
    $('#tour_link').html('<a style=" color: #222;" href="'+link+'">Link</a> to share the present tour:<br/>' + link);
    $('#tour_link').show();

    // window.clipboardData.setData('Text',x);
}

function submit_tour_recomm()
{
    str="?from=" + $('#from').val() + "&to=" + $('#to').val() + "&gtilt=" + gtilt + "&grange=" + grange + "&recomm=" + $('#tour_recomm_text').val();
    $.get("info.txt"+encodeURI(str));

    pageTracker._trackEvent('Tour', 'RECOMMEND', str);

    $('#tour_recommend').toggle('blind', {direction: 'vertical' }, 333);
}

var g_celebs;

function open_holly()
{
    if (!g_celebs) {
	$.get("celeb.txt", function(data){

	    g_celebs = data.split("\n");

	    // alert("Data Loaded:\n " + data);
	    // alert("Data Loaded:\n " + res[0] + " XX " + res[1]);

	    f = Math.round(Math.random() * g_celebs.length);
	    t = Math.round(Math.random() * g_celebs.length);

	    // alert (f + " x " + t + " X " + g_celebs[f]);

	    $('#holly_text_f').html(g_celebs[f]);
	    $('#holly_text_t').html(g_celebs[t]);
	    $('#holly_details').show();
	    $('#t_set_holly').show();
	    $('#holly_wrap').css("border", "1px solid #eee");

	    $('#t_holly').attr("value", "Hollywood Celebrities (click again for new tour)");
	});
    } else {

	f = Math.round(Math.random() * g_celebs.length);
	t = Math.round(Math.random() * g_celebs.length);
	
	// alert (f + " x " + t + " X " + g_celebs[f]);
	
	$('#holly_text_f').html(g_celebs[f]);
	$('#holly_text_t').html(g_celebs[t]);
	$('#holly_details').show();
    }

    $('#celeb_info').hide();
}

function set_holly()
{
    f = $('#holly_text_f').html().split(",");
    // alert(f[1] + " x " +f[2]);
    t = $('#holly_text_t').html().split(",");

    $('#from').attr("value",f[1]+","+f[2]);
    $('#to').attr("value",t[1]+","+t[2]);

    // prepare the tour link
    set_tour_url();

    _doFold("tour");
    // hide_birds();
    DS_goDirections();
    str="?f=" + f +"&t=" + t;
    // $.get("info.txt"+encodeURI(str));
    pageTracker._trackEvent('Tour', 'Celebs', str);

}
//
// car changer
//
var g_car_kmz_item = 0;
var g_car_scale = 1.3;
var g_old_car_heading ;
var g_car_type;
var g_model;
var g_modelplacemark;

function get_car(type, ah, car_kmz_item, car_scale, p_driver_mode) {
    if (!DS_ge) {
	console.log("no DS_ge");
	return;
    }
    var MODEL_URL = 'http://www.gaiagi.com/driving-simulator/kml/' + type;
    g_model_url = MODEL_URL;
    g_car_type = type;
    g_old_car_heading = g_simulator_add_heading;
    g_simulator_add_heading = ah;
    g_car_scale = car_scale;
    g_car_kmz_item = car_kmz_item;
    window.google.earth.fetchKml(
      DS_ge,
      MODEL_URL,
      function(obj) {
        get_car_cb(obj);
      });
    if (!p_driver_mode || p_driver_mode == "car") {
	g_driver_mode = "car";
	g_maps_icon_url = 'graphs/ferrari-icon.png';
	$('#maps_icon_url').val(g_maps_icon_url);
	$('#div_toggle_birdv_pic1').fadeTo('fast', 0.8);
	show_birdsv();
	$('#toggle_birdv_pic1_a').html("Show Pictures");
	if (g_driver_calc_speed_init) {
	    g_driver_calc_speed_init = 0;
	    spin_bike_reset();
	}
        pageTracker._trackEvent('Driver', 'Car', type);
    } else {
	g_driver_mode = "spinning_bike";
	g_maps_icon_url = 'graphs/Bicycle-Green-2-icon.png';
	$('#maps_icon_url').val(g_maps_icon_url);
	f_driver_calc_speed_init();
	$('#div_toggle_birdv_pic1').fadeTo('fast', 0.);
        pageTracker._trackEvent('Driver', 'Spin_Bike', type);
    }
    if (DS_mapMarker_icon) {
	set_maps_icon();
	// DS_mapMarker_icon.image=g_maps_icon_url;
	// DS_mapMarker.setImage(g_maps_icon_url);
    }
    _doFold('config'); openclose_config();
}
function get_car_cb(obj) {
    if (DS_simulator && DS_simulator.model) {
	model = DS_simulator.model;
	lat = model.getLocation().getLatitude();
	lng = model.getLocation().getLongitude();
	alt = model.getLocation().getAltitude();
	head = model.getOrientation().getHeading();
	modelPlacemark = DS_simulator.modelPlacemark;
	DS_ge.getFeatures().removeChild(modelPlacemark);    
    } else {
	console.log("model not yet loaded");
    }

    kml = obj.getFeatures().getChildNodes().item(g_car_kmz_item);
    modelPlacemark_car = kml;
    model_car = modelPlacemark_car.getGeometry();
    model_car.setAltitudeMode(DS_ge.ALTITUDE_RELATIVE_TO_GROUND);
    // model_car.setAltitudeMode(DS_ge.ALTITUDE_ABSOLUTE);
    DS_ge.getFeatures().appendChild(modelPlacemark_car);
    sc = model_car.getScale();
    s = g_car_scale;
    sc.set(s,s,s);
    model_car.setScale(sc);
    if (lat) {
	model_car.getLocation().setLatLngAlt(lat, lng, alt);
	model_car.getOrientation().setHeading(head + g_simulator_add_heading + g_old_car_heading);
	// model_car.getOrientation().setHeading(head);
    }
    if (DS_simulator) {
	// alert(model_car);
	DS_simulator.model =  model_car;
	DS_simulator.modelPlacemark = modelPlacemark_car;
    }
    g_model = model_car;
    g_modelplacemark = modelPlacemark_car;
}


///////////////////////////////////////////////////////////////
// ZEstimates
// 

/*
 * Zillow estimate for location
 *
 */
// http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=X1-ZWz1c9k97844qz_43hp8&address=1022+Palisades+Beach+Rd&citystatezip=Santa%20Monica,%20CA

function get_zestimate(res_addr) {
    // adminarea = res.AddressDetails.Country.AdministrativeArea;
    // if (adminarea.SubAdministrativeArea) {
    //subadminarea = adminarea.SubAdministrativeArea;
    //	sub_areaname= subadminarea.SubAdministrativeAreaName;
    //} else {
    //	sub_areaname = "";
    //}

    $('#zest_wait').show();

    addr_arr = res_addr.split(",");
    par = "address=" + encodeURIComponent(addr_arr[0].replace(/-[0-9]+/, "")) + "&citystatezip=" + encodeURIComponent(addr_arr[1])  +",%20"+ encodeURIComponent(addr_arr[2]);
    // str = "http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=X1-ZWz1c9k97844qz_43hp8&" + par + '&output=json&callback=?';
    // str = "http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=X1-ZWz1c9k97844qz_43hp8&" + par + '&output=json';
    par = encodeURIComponent(par);
    str = 'generic-proxy.php?url='+encodeURIComponent("http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=X1-ZWz1c9k97844qz_43hp8&" + par);
    // alert(str);
    $.get(str, function(xml, textstatus){
     	// alert(textstatus + " " + xml);
	code = $(xml).find('code').text();
	inf_str = '<div style="margin-top: 1px; margin-left: 1px; font-size: 90%;"><a href="http://www.zillow.com" target="_blank"><img height="42" border="0" style=" margin-left: 0px; background-color: white;" src="http://www.zillow.com/static/images/ZillowLogoLarge.gif" /></a><br/>Zillows Zestimate<sup>&copy;</sup> for home <u>near</u> <br/>"' + res_addr + '"</div><hr/>';
	if (code == 0) {
	    $(xml).find('result').each(function(){
		res = $(this);
		street = $(res).find('street').text();
		zipcode = $(res).find('zipcode').text();
		lat = $(res).find('latitude').text();
		lng = $(res).find('longitude').text();
		zestimate = $(res).find('amount').text();
		valch = $(res).find('valueChange').text();
		last_upd = $(res).find('last-updated').text();
		// alert(lat + " " + lng + " " + zestimate + " " + xml);
		// inf_str += lat + " " + lng + " " + zestimate;

		inf_str += '<div style="margin-left: 1px; margin-top: 1px; font-size: 80%;">Zestimate<sup>&copy;</sup>: &nbsp;&nbsp;&nbsp;<b>$' + $(res).find('amount').text() + '</b>&nbsp;&nbsp;&nbsp; (last update: '+last_upd+')<p/>';
		inf_str += 'Value change of $' + $(res).find('valueChange').text() + ' over the last 30 days ('+ Math.round(valch/zestimate*100) +'%) <p/>';
		inf_str += 'Address of home zestimated<sup>&copy;</sup>: ' + $(res).find('street').text() + ', ' + $(res).find('city').text() + ', ' + $(res).find('state').text() + ', ' + $(res).find('zipcode').text() + '<p/>';
		inf_str += 'More details: <a target="_blank" href="' + $(res).find('homedetails').text() + '">Home Details</a>';
		inf_str += ', <a target="_blank" href="' + $(res).find('graphsanddata').text() + '">Home Value Chart</a><p/>';
		inf_str += 'Data provided by <a target="_blank" href="http://www.zillow.com">zillow.com</a></div><p/><hr/>';

	    });

	    $("#location_details").html(inf_str);

	    show_loc_info_fin();

	    pageTracker._trackEvent('ZEstimate', 'ZEstimate', res_addr);	
	    
	} else {
	    if (code != 508) {
		alert ("Got error from Zillow :" + code);
	    }
	}

	$('#zest_wait').hide();

    });
 
}

/*
 * Wrapper for Loc infos
 *
 */

function show_loc_info(type) {
    switch (type) {
    case "tweets": 
	get_tweets();
	break;
    case "zestimate":
	get_zestimate(g_result_address);
	break;
    }

}


///////////////////////////////////////////////////////////////
// Twitter
// 

/*
 * Local Twitter Tweets 
 *
 */

// http://search.twitter.com/search.json?geocode=40.757929%2C-73.985506%2C2mi&rpp=15&callback=?
// http://apiwiki.twitter.com/Twitter-Search-API-Method:-search

function get_tweets() {

    ctr = DS_map.getCenter();
    lat = ctr.lat();
    lng = ctr.lng();
    radius = "7mi";
    
    // &since=2009-04-21

    nr = 50;
    str = 'http://search.twitter.com/search.json?geocode='+ encodeURIComponent(lat+','+lng+','+radius)+'&rpp=' + nr + '&callback=?';
    // alert(str);
    $('#tweet_wait').show();
    $.getJSON(str, 
	      function(data)
        {
	    len = data.results.length;
	    if (! g_result_address) {
		area_str = "Local Tweets";
	    } else {
		area_str = 'Tweets around "' + g_result_address + '"';
	    }
	    // alert("res " + len + " " + navigator.userAgent);
	    inf_str = '<h3><a href="http://www.twitter.com" target="_blank"><img border="0" style="margin-right: 6px;" height="30" src="http://assets0.twitter.com/images/twitter_logo_header.png" alt="Twitter"/></a>'+area_str+' </h3>';
	    // var msie = navigator.userAgent.match("MSIE") ? 1 : 0;;
	    // msie = 0;
	    $.each(data.results, function(i, tweet){
		loc_arr = {};
		if (i < 3) {
		    // alert(tweet.text + "\n " + tweet.location);
		}
		loc = tweet.location.replace(/.*: */,"");
		loc_split = loc.split(",");
		backc = i%2 == 1 ? '#555555' : '#333333';
		paddop = i == 0 ? "6px" : "18px";
		inf_str += '<a style="" border="0" href="http://twitter.com/' + tweet.from_user + '" target="_blank"><img border="0" style="margin-top: 0px; padding-top: '+paddop+'; float: right ;" height="30" src="' + tweet.profile_image_url + '"/></a>';
		inf_str += '<div style="padding-left: 6px; background-color: '+backc+'; padding-top: 9px; padding-bottom: 9px; display: block; border-bottom: 1px outset #ffffff">' + tweet.text + '<div style="font-size: 85%"><i>Location: ' + tweet.location + '; User: <a href="http://twitter.com/' + tweet.from_user + '" target="_blank">' + tweet.from_user + '</a>; Created: '+tweet.created_at.replace("+0000", "(GMT)")+'</i></div></div>';
		// from '+tweet.source+'</div>';
		// debug(inf_str);
		if (0 && ! loc_arr[loc]) {

		    loc_arr[loc] = 1;

		    placemark = DS_ge.createPlacemark(''); 
		    
		    var point = DS_ge.createPoint(''); 
		    point.setLatitude(parseFloat(loc_split[0])); 
		    point.setLongitude(parseFloat(loc_split[1])); 
		    //point.setLatitude(37.59); 
		    //point.setLongitude(-122.234); 
		    placemark.setGeometry(point); 
		    DS_ge.getFeatures().appendChild(placemark); 
		    
		    var balloon = DS_ge.createHtmlDivBalloon('');
		    balloon.setMaxWidth(300);
		    balloon.setFeature(placemark);
		    
		    var div = document.createElement('DIV');
		    div.innerHTML = tweet.text + '<br/>'
			+ 'User: ' + tweet.from_user 
			+ '<img src="'+tweet.profile_image_url + '">';
		    balloon.setContentDiv(div);
		    
		    DS_ge.setBalloon(balloon);

		    google.earth.addEventListener(placemark, 
						  'click', 
						  function(event) {
			var text = inf_str;
			event.preventDefault(); 
			setTimeout(function() {
			    alert(text + "\nXX:" 
				  + event.getTarget().getParentNode().getId()
				  + "\nYY:" + event.getTarget().getType());
			}, 0);
		    });
		    
		} else {
		    // debug("found loc " + loc);
		}

	    });

	    $("#location_details").html(inf_str);

	    show_loc_info_fin();

	    pageTracker._trackEvent('Local Info', 'Tweets', g_result_address);

	    // $("#location_details_close1").draggable();
	    // $("#location_details_wrapper").draggable();

	    // DS_ge.getWindow().setVisibility(false);
	    // g_strv_top = $('#strv1').css("top");
	    // g_ge_top = $('#earth-container').css("top");
	    // alert (g_strv_top + " " + g_ge_top);

	    // $('#strv1').css("top", "-1000px");
	    // $('#earth-container').css("top", "-1000px");

	    //if (len <= 0) {
	    //	setTimeout("get_tweets()", 25000);
	    //}

	});
   
}

function show_loc_info_fin() {
    var clientHeight = document.documentElement.clientHeight;
    // $("#location_details").css("height", Math.round(clientHeight * 0.42) + "px");
    // $("#location_details_wrapper").fadeIn('3600');
    // alert("show zest");
    $("#location_details_wrapper").slideToggle();

    $('#tweet_wait').hide(); 
    
    hide_birds(1);
}

////////////////////////////////////////////////////////////
// radio
//

var g_radio_started = 0;
function start_radio () {

    // alert ("radio ...");
    if (! g_radio_started) {
	$('#radio_iframe2').attr("src", "http://www.labpixies.com/campaigns/radio/radio.html");
	g_radio_started = 1;
    }
}

function RIP(res) {

    req = $.ajax({   type: "GET",
			 url: str, 
			       async: false,
			 dataType: "script",
			 success: 
    function(req_obj, textstatus){
	alert("SUCC " + req_obj + " " + textstatus);
    },
			 dataFilter: 
    function(req_obj, textstatus){
	alert("datafil " + req_obj + " " + textstatus);
    },
			 error: 
    function(req_obj, textstatus, errorThrown){
	alert("error " + req_obj + " " + textstatus + " " + errorThrown);
    }
			 });

// Virtual earth stuff
//    http://msdn.microsoft.com/en-us/library/bb429619.aspx    

    var pixel = be.LatLongToPixel(map.GetCenter(), map.GetZoomLevel());
    
    info += "LatLongToPixel: " + pixel.x + ", " + pixel.y + "\n";
    
    // Check to see if the current birdseye view contains the pushpin pixel point.
    info += "contains pixel " + pinPixel.x + ", " + pinPixel.y + ": " + 
	be.ContainsPixel(pinPixel.x, pinPixel.y, map.GetZoomLevel()) + "\n";
    
    // Check to see if the current view contains the pushpin LatLong.
    info += "contains latlong " + pinPoint + ": " + be.ContainsLatLong(pinPoint) + "\n";
    
    // This method may return null, depending on the selected view and map style.
    info += "latlong: " + map.PixelToLatLong(pixel);
    
}

///////////////////////////////////////////////////////////////
// incidents
// 

function get_incidents(){

    bds=DS_map.getBounds();
    lrlat=bds.getSouthWest().lat();
    ullng=bds.getSouthWest().lng();
    ullat=bds.getNorthEast().lat();
    lrlng=bds.getNorthEast().lng();

    // url='http://platform.beta.mapquest.com/traffic/v1/incidents?key=Dmjtd%7Cluu729ua2h%2Crs%3Do5-5w1s5&callback=MQ_CB&lrlat=37.177785&lrlng=-121.665838&ullat=38.066752&ullng=-122.786356&filters=construction,incidents&inFormat=kvp&outFormat=json';
    //      url='http://platform.beta.mapquest.com/traffic/v1/incidents?key=Dmjtd%7Cluu729ua2h%2Crs%3Do5-5w1s5&callback=MQ_CB&lrlat='+lrlat+'&lrlng='+lrlng+'&ullat='+ullat+'&ullng='+ullng+'&filters=construction,incidents&inFormat=kvp&outFormat=json';
    // http://www.mapquestapi.com/traffic/v1/incidents?key=YOUR_KEY_HERE&callback=handleIncidentsResponse&boundingBox=37.948246,-122.719905,37.536566,-122.200993&filters=construction,incidents&inFormat=kvp&outFormat=json
    url='http://www.mapquestapi.com/traffic/v1/incidents?key=Dmjtd%7Cluu729ua2h%2Crs%3Do5-5w1s5&callback=MQ_CB&boundingBox='+lrlat+','+lrlng+','+ullat+','+ullng+'&filters=construction,incidents&inFormat=kvp&outFormat=json';

      // alert(url);

      if(typeof MQA=="undefined"){window.MQA={}}(function(){MQA.jsonp=function(B){var A=document.createElement("script");A.type="text/javascript";A.src=B;document.body.appendChild(A)};MQA.formatLocation=function(A){var D="",C=["street","adminArea5","postalCode","adminArea4","adminArea3","adminArea1"],B=0;for(;B<C.length;B++){if(A[C[B]]&&A[C[B]].length>0){if(D.length>0){D+=", "}D+=A[C[B]]}}if(A.latLng){D+=" ("+A.latLng.lat+", "+A.latLng.lng+")"}return D}})();

      MQA.jsonp(url);
      
      pageTracker._trackEvent('Incidents', 'Incidents', url);	

      // alert("traff " + url);
      // $.getJSON(url, function(data)
      //$.get(url, function(data)
      //{
      //	  alert(data);
      // });
}

var g_incid_marker = [];
function MQ_CB(response) {

    // alert(g_incid_marker.length);
    if (g_incid_marker.length > 0) {
	// clean markers
	for (k=0; k < g_incid_marker.length; k++) {
	    // alert(g_incid_marker[k]);
	    DS_map.removeOverlay(g_incid_marker[k]);
	}
    }
    
    var incidents = response.incidents;
    if (!incidents || incidents.length <= 0) {
        // alert('no incidents found on this map');
	$('#incid_div').html('No incidents found on this map.');
        return;
    } else {
    }
    // alert(incidents.length);

    shapeCollection = new MQA.ShapeCollection();
    shapeCollection.setName("incidents");
    var i;
    //incident.latitude, 
    //incident.longitude
    //incident.type
    // incident.severity
    //incident.iconURL
    // .shortDesc
    // .fullDesc
    // .startTime
    // .endTime

    var incid_list = "";
    for (i = 0; i < incidents.length; i++) {
        var incident = incidents[i];
        // var latLng = {lat:  incident.latitude, lng:  incident.longitude};
        // var myPoint = new MQA.Poi(latLng);
	var point = new GLatLng( incident.lat, incident.lng)
        var type = parseInt(incident.type);
        var severity = parseInt(incident.severity);

	var baseIcon = new GIcon(G_DEFAULT_ICON);
        baseIcon.image = incident.iconURL;
        baseIcon.iconSize = new GSize(20, 20);
        baseIcon.shadowSize = new GSize(25, 25);
        baseIcon.iconAnchor = new GPoint(9, 9);
        baseIcon.infoWindowAnchor = new GPoint(9, 2);

	markerOptions = { icon:baseIcon };
	g_incid_marker[i] = new GMarker(point, markerOptions);
	// var marker = new GMarker(point);
        // var s = '<div style="color: black; background-color: orange;">' + incident.fullDesc + '('+incident.lat+','+incident.lng+')</div><div>';
        var s = '<div style="color: black; background-color: orange;">' + incident.fullDesc + '</div><div>';
        s += '<b>Start Time:</b> ' + incident.startTime + '<br/>';
        s += '<b>End Time:</b> ' + incident.endTime + '<br/>';
        s += 'All times estimated; ';
	s += '<a href="javascript:void(0);" onClick="javascript: center_on_incid('+incident.lat+','+incident.lng+');">Zoom to Street</a><div id="reset_incid_view" style="display: none;"></div></div>';

	incid_list += '<a href="javascript: void(0);" onClick="javascript: incid_marker_trigger('+i+');" title="'+incident.fullDesc+'">'+(i+1)+'</a>, ';

        // var s = incident.fullDesc + '\n\n';
        //var s = incident.shortDesc + '\n\n';
        //s += 'Start Time: ' + incident.startTime + '\n';
        //s += 'End Time: ' + incident.endTime + '\n';
        //s += '(All times estimated)';

	MQ_CB_create_marker(g_incid_marker[i], s);

    }

    $('#incid_div').html( incidents.length + ' incidents found on this map: ' + incid_list);
    
}

function incid_marker_trigger(i) {	
    GEvent.trigger(g_incid_marker[i], 'click');
}

function MQ_CB_create_marker(mark, s) {	
    GEvent.addListener(mark, "click", function() {
	// mark.openInfoWindowHtml(s);
	// alert(s);
	$('#incid_div2').html(s);
    });
    GEvent.addListener(mark, "mouseover", function() {
	// mark.openInfoWindowHtml(s);
	// alert(s);
	$('#incid_div2').html(s);
    });
    DS_map.addOverlay(mark);
}

var g_incid_save_center, g_incid_save_zoom, g_incid_save_la;
function center_on_incid(lat, lng) {
    // Save view
    g_incid_save_center = DS_map.getCenter();
    g_incid_save_zoom = DS_map.getZoom();
    g_incid_save_la = DS_ge.getView().copyAsLookAt(DS_ge.ALTITUDE_RELATIVE_TO_GROUND);
    $('#reset_incid_view').html(', <a href="javascript: void(0);" onClick="javascript: reset_incid_view();">Reset View</a>');
    $('#reset_incid_view').css({display: "inline"});
    // center on incident
    loc = new GLatLng(lat, lng);
    DS_map.setCenter(loc, 16);
    SyncViews_gloc(loc, 1);
    
    // set altitude
    la = DS_ge.getView().copyAsLookAt(DS_ge.ALTITUDE_RELATIVE_TO_GROUND);
    la.setAltitude(240);
    la.setLatitude(loc.lat());
    la.setLongitude(loc.lng());
    la.setHeading(0);
    DS_ge.getView().setAbstractView(la);
}

function reset_incid_view() {
    DS_map.setCenter(g_incid_save_center, g_incid_save_zoom);
    DS_ge.getView().setAbstractView(g_incid_save_la);
    SyncViews_gloc(g_incid_save_center, 1);

}	


///////////////////////////////////////////////////////////////
// audio
// 

// audio support
// see http://weston.ruter.net/projects/google-tts/

var g_canPlayAudioMP3=0;
var g_wantsPlayAudioMP3=0;
function canPlayAudioMP3(){
    try {
	var audio = new Audio();
	// Shortcut which doesn't work in Chrome (always returns ""); pass through
	// if "maybe" to do asynchronous check by loading MP3 data: URI
	if(audio.canPlayType('audio/mpeg') == "probably") {
	    // g_canPlayAudioMP3=1;
	    offerPlayAudio();
	    return;
	}

	//If this event fires, then MP3s can be played
	audio.addEventListener('canplaythrough', function(e){
	    // g_canPlayAudioMP3=1;
	    offerPlayAudio();
	    return;
	}, false);
	
	//If this is fired, then client can't play MP3s
	audio.addEventListener('error', function(e){
	    // callback(false, this.error)
	}, false);
	
	//Smallest base64-encoded MP3 I could come up with (less than 0.000001 seconds long)
	audio.src = "data:audio/mpeg;base64,/+MYxAAAAANIAAAAAExBTUUzLjk4LjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
	audio.load();

    }
    catch(e){
	// callback(false, e);
    }
}
canPlayAudioMP3();
// alert(navigator.userAgent);

function offerPlayAudio(){
    // alert("added audio");

    g_canPlayAudioMP3=1;

    // turn off for now
    g_canPlayAudioMP3=0;

//     setTimeout(function() {
// 	div = document.getElementById("speaker_div");
// 	// alert("audio " + div);
// 	div.style.display = 'inline';
// 	// document.getElementById('speaker_div').innerHTML='<a href="javascript: void();" onClick="javascript: g_canPlayAudioMP3=1;">Audio</a>';
// 	// $('#speaker_div').html('XXXX');
// 	// g_canPlayAudioMP3=1;
//     }, 1800);
}

var g_activated_audio=0;
function activate_audio(){
    if (!g_activated_audio) {
	g_wantsPlayAudioMP3=1; 
	alert('Audio activated. When moving from one leg of the route to the next the leg will be \'text-to-speeched\' on audio as well. You can click on the leg as well to hear the audio. When activated directions will be in English using the Google text to speech service.');
	$('#audio_speaker').attr("src", "speak-on.jpg");
	g_activated_audio=1;
	DS_goDirections();
	pageTracker._trackEvent('Driver', 'Audio', navigator.userAgent);
	// alert(navigator.userAgent);
    } else {
	g_activated_audio=0;
	g_wantsPlayAudioMP3=0; 
	$('#audio_speaker').attr("src", "speak-off2.jpg");
    }
}

function PlayAudio(str){
    // alert (g_canPlayAudioMP3);
    if(g_canPlayAudioMP3) {
	var audio = document.getElementById('speechOutputAudio');
	url = 'http://translate.google.com/translate_tts?tl=en&q='+encodeURIComponent(str);
	// $('#audio_wrapper').css("display", "inline");
	audio.src = url;
	audio.load(); //this is necessary because can't set audio.currentTime in Chrome (below)
	//audio.addEventListener("ended", function(e){
	//this.currentTime = 0;
	//}, false);
	audio.play();
    }
    else if(0){
	var warning = document.createElement('em');
	warning.className = "error";
	warning.innerHTML = "Either your browser does not support HTML5 Audio or your browser doesn't support playing MP3s, so you must use the download link:";
	audio.parentNode.replaceChild(warning, audio);
    }
    // speechOutput.removeAttribute('hidden');
}
// setTimeout("PlayAudio('turn right next light')", 3500);

///////////////////////////////////////////////////////////////
// cookie stuff
// 

// <SCRIPT LANGUAGE="JavaScript">
// <!--

/*
   name - name of the cookie
   value - value of the cookie
   [expires] - expiration date of the cookie
     (defaults to end of current session)
   [path] - path for which the cookie is valid
     (defaults to path of calling document)
   [domain] - domain for which the cookie is valid
     (defaults to domain of calling document)
   [secure] - Boolean value indicating if the cookie transmission requires
     a secure transmission
   * an argument defaults when it is assigned null as a placeholder
   * a null placeholder is not required for trailing omitted arguments
*/

function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) +
      ((expires) ? "; expires=" + expires.toGMTString() : "") +
      ((path) ? "; path=" + path : "") +
      ((domain) ? "; domain=" + domain : "") +
      ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}


/*
  name - name of the desired cookie
  return string containing value of specified cookie or null
  if cookie does not exist
*/

function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else
    begin += 2;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1)
    end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}


/*
   name - name of the cookie
   [path] - path of the cookie (must be same as path used to create cookie)
   [domain] - domain of the cookie (must be same as domain used to
     create cookie)
   path and domain default if assigned null or omitted if no explicit
     argument proceeds
*/

function deleteCookie(name, path, domain) {
  if (getCookie(name)) {
    document.cookie = name + "=" +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}

// date - any instance of the Date object
// * hand all instances of the Date object to this function for "repairs"

function fixDate(date) {
  var base = new Date(0);
  var skew = base.getTime();
  if (skew > 0)
    date.setTime(date.getTime() - skew);
}

// -->
// </SCRIPT>

//
// geo picture support
//

var g_show_pic_to = 0;
//setTimeout("show_picture()", 7000);
var g_photoid_arr = [];
var g_pic1_marker = 0;
var g_base_pic1_baseIcon;
var g_pic1_refresh_rate = 0;

function show_picture () {
    
    // var t = new Date(); t.setDate(t.getDate() + (2 * 360));
    // setCookie("show_pic1", 1, t);
    clearTimeout(g_show_pic_to);
    bds = DS_map.getBounds();
    sw_lat = bds.getSouthWest().lat();
    sw_lng = bds.getSouthWest().lng();
    ne_lat = bds.getNorthEast().lat();
    ne_lng = bds.getNorthEast().lng();
    
    var start = 0, to = 30;
    url = "http://www.panoramio.com/map/get_panoramas.php?order=popularity&set=public&from="+start+"&to="+to+"&minx="+sw_lng+"&miny="+sw_lat+"&maxx="+ne_lng+"&maxy="+ne_lat+"&callback=?";
    $.getJSON(url, function(data) 
    {
	// alert(data);
	// $(data).each(function(i, item) {
	// alert($(this)[0].photos[i].photo_id);
        //}
	// alert("pid " + data.photos[0].photo_id);
	// obj = data.photos[0];
	for (i=0; i<30 && data.photos[i].photo_id && g_photoid_arr[data.photos[i].photo_id] == 1; i++) 
	{ 	}
	// alert (i);
	obj = data.photos[i];
	if (!obj) {
	    return;
	}
	src = obj.photo_file_url;
	pid = obj.photo_id;
	g_photoid_arr[pid] = 1;
	
	// str = 'Panoramio: <a target="_blank" href="' + obj.photo_url + '">' + obj.photo_title + '</a> from <a target="_blank" href="' + obj.owner_url + '">' + obj.owner_name + "</a>";
	
	// with links
	str_li = obj.type + ': <a target="_blank" href="' + obj.photo_url + '">' + obj.photo_title.substr(0,39) + '</a> from <a target="_blank" href="' + obj.owner_url + '">' + obj.owner_name + "</a>";
	// str = obj.type + ': "' + obj.photo_title.substr(0,45) + '" from ' + obj.owner_name + "";
	str = "Panoramio Photo: '" + obj.photo_title.substr(0,45) + "' from " + obj.owner_name + "";

	// title="'+str+'" 
	// onMouseout="$(this).fadeTo(\'fast\', 0.6);"
	var content = '<center><div id="pic1" style="height: '+(g_birdv1_h-9)+'px"; padding: 0px; display: none;" onClick="show_picture();" ><img style="padding: 0px; border: 1px solid #eee;" onClick="" id="geopic_' + pid + '" src="' + src + '" height="'+(g_birdv1_h-2)+'"><div style="position: relative; bottom: 21px; font-size: 11px; " id="lpic_caption_' + pid + '"><a id="pic1_capt" style="background-color: #666; " target="_new" onMouseover="$(this).stop(); $(this).fadeTo(\'fast\', 0.99);" title="'+str+' (Uploaded: '+obj.upload_date+')" href="'+obj.photo_url+'">'+str+'</a></div></div></center>';
	
	$('#birdv1').hide();
	// $('#pic1_container').fadeOut('500');
	// $('#pic1_container').show();
	// $('#pic1_'+pid).fadeIn('1500');
	$('#pic1_container').html(content);
	$('#pic1_container').fadeIn('5400');
	$('#pic1').fadeIn('4500');
	// alert('#pic1_'+pid);
	// $('#pic1_capt').fadeIn("slow", 0.5);
	$('#pic1_capt').animate({
	       opacity: "0.6" 
			     }, 4500);

	if (g_pic1_marker) {
	    DS_map.removeOverlay(g_pic1_marker);
	}

	// set marker
	baseIcon = new GIcon(G_DEFAULT_ICON);
	g_base_pic1_baseIcon = baseIcon;
        baseIcon.image = src;
        baseIcon.iconSize = new GSize(24, 24);
        baseIcon.shadowSize = new GSize(0,0);
        baseIcon.iconAnchor = new GPoint(0, 0);
        // baseIcon.infoWindowAnchor = new GPoint(9, 2);
	var markerOptions = { icon:  baseIcon };
	g_pic1_marker = new GMarker( new GLatLng(obj.latitude, obj.longitude), markerOptions);
	// alert (obj.latitude + " " + obj.longitude);

	GEvent.addListener(g_pic1_marker, "click", function() {
	    show_picture();
	});

	DS_map.addOverlay(g_pic1_marker);

    });

    g_show_pic_to = setTimeout("show_picture()", 15000);
}

function show_birdsv () {
    
    // var t = new Date(); t.setDate(t.getDate() + (2 * 360));
    // setCookie("show_pic1", 0, t);
    var t = new Date(); t.setDate(t.getDate() + (2 * 360));
    setCookie("show_pic1", 0, t);
    // deleteCookie("show_pic1");
    clearTimeout(g_show_pic_to);
    if (g_pic1_marker) {
	DS_map.removeOverlay(g_pic1_marker);
    }
    $('#pic1_container').hide();
    // $('#birdv1').fadeIn('4500');
    $('#birdv1').show();

}

var g_show_hide_drive_ctrl = 1;  // status of the drive ctrl (open/closed)
var g_iframe_shim_drive_ctrl_orange = 0;
var g_drive_ctrl_width = 0;
function show_hide_drive_ctrl (l_cmd) {

    // alert("show_hide_drive_ctrl cmd");

    if (!g_show_hide_drive_ctrl_enabled) return;

    // alert("show_hide_drive_ctrl");
    // $('#iframe_shim_drive_ctrl').fadeTo('fast', 0.5);
    // $('#iframe_shim_drive_ctrl').css("background-color", "");
    // $('#drive_ctrl_div').css("background-color", "");
    // $('#drive_ctrl_div').fadeTo('fast', 0.5);
    
    if (g_show_hide_drive_ctrl) {
	// hide
	if (l_cmd == "close") {
	    // alert("close");
	    g_show_hide_drive_ctrl = 0; // closed
	    g_drive_ctrl_width = $("#drive_ctrl_div").innerWidth();
	    $('#drive_ctrl_div').animate({ width: '0'}, 600 );
	    $('#iframe_shim_drive_ctrl').animate({ width: '0'}, 600 );
	    if (!g_iframe_shim_drive_ctrl_orange) {
		$('#iframe_shim_drive_ctrl').css("border", "2px solid orange");
// 		setTimeout(function() {
// 		    // TODO 2px creates offset
// 		    $('#iframe_shim_drive_ctrl').css("border", "2px solid white");
// 		    setTimeout(function() {
// 			$('#iframe_shim_drive_ctrl').css("border", "2px solid orange");
// 		    }, 3000);
// 		}, 5000);
	    }
	    g_iframe_shim_drive_ctrl_orange=1;
	    $('#drive_ctrl_small').fadeIn('900');
	    $('#car_speed_slider').fadeIn('900');
	}
    } else {
	// alert("show");
	// show
	if (!g_drive_ctrl_width) g_drive_ctrl_width = 300;
	$('#drive_ctrl_div').animate({ width: g_drive_ctrl_width + "px"}, 600 );
	$('#iframe_shim_drive_ctrl').animate({ width: (21+g_drive_ctrl_width) + "px"}, 600 );
	$('#iframe_shim_drive_ctrl').css("border", "1px solid white");
	DS_controlSimulator("pause");
	g_show_hide_drive_ctrl = 1;
	$('#drive_ctrl_small').fadeOut();
	$('#car_speed_slider').fadeOut();
    }
}

var g_driver_calc_speed_save = 0.0, g_F_init = 0., g_v_init=0.;
var g_driver_calc_slope = 0;
var g_driver_calc_speed_init = 0;
var g_driver_calc_cal_spent = 0;
var g_driver_calc_speed_params = {};
function driver_calc_speed (p_slope) {

    if (!g_driver_calc_speed_init) {
	// init
	f_driver_calc_speed_init();
    }
    // slope s
    // var slo = 10 / 100;
    var slo = p_slope;
    // speed
    // var v = 25 / 3.6; // 25 km/h
    var v = g_driver_calc_speed_save;

    var P = g_driver_calc_speed_params['P']; //Power in Watt
    var M = g_driver_calc_speed_params['M']; //Weight in kg
    // var M = 80; // kg
    var g = 9.81;  
    // var cr = 0.003; // roll
    var cr = 0.003; // roll
    var F_Roll = cr * M * g;
    // alert(F_1Roll);
    var F_Slope = slo * M * g;
    if (F_Slope > 150.) {
	F_Slope = 150.;
    }
    var F_Air = 1.2 * 0.39 * v * v / 2.0;

    if (g_F_init == 0.) {
	g_v_init = nthRoot( (P * 0.93/1.2/0.39*2.) , 3, 12);
	g_F_init = P / g_v_init;
	// console.log("vinit " + g_v_init + "; Finit " + g_F_init);
    }

    if (g_driver_calc_speed_save > 0.) {
	var l_F = Math.max(g_F_init, P / g_driver_calc_speed_save);
    } else {
	var l_F = g_F_init;
    }
    var F_Total = (l_F - F_Roll - F_Slope - F_Air) / 0.93; // efficiency
    // console.log("ftot "+F_Total+" = "+l_F+" - "+F_Roll+" - "+F_Slope+" - "+F_Air);

    // v_new = P / F_Total;
    // var l_ms_tick = DDSimulator.TICK_SIM_MS / 1000.;
    var l_ms_tick = DS_simulator.RealTime_Diff / 1000.;
    // var l_ms_tick = 0.066;
    v_new = v + F_Total * l_ms_tick  / M; // tick in msec
    if (v_new < 0.1) {
	v_new = 0.1;
    }
    // console.log(v_new + "m/s " + v_new * 3.6 + "km/h");
    g_driver_calc_speed_save = v_new;
    g_driver_calc_cal_spent += P * 3.44  / 3.6 * l_ms_tick ; // * 1000 / 3600

    $('#speed_info').show();
    // var content = "Speed info: " + Math.round(v_new *100.0)/100.0 + "m/s " + Math.round(v_new * 3.6 *100.)/100. + "km/h; Slope: " + Math.round(slo *100.0)/100.0;
    // var content = "Speed info: " + v_new.toFixed(2) + "m/s " + (v_new * 3.6).toFixed(2) + "km/h " + (v_new * 3.6 * 0.621).toFixed(2) + " mph; Slope: " + slo.toFixed(2) + "; F_tot = " + F_Total.toFixed(2) + "; kCal = " + (g_driver_calc_cal_spent/1000.).toFixed(2);
    // f_tot
    var content = "Speed info: " + v_new.toFixed(2) + "m/s " + (v_new * 3.6).toFixed(2) + "km/h " + (v_new * 3.6 * 0.621).toFixed(2) + " Mi/h; Slope: " + slo.toFixed(2) + "; kCal = " + (g_driver_calc_cal_spent/1000.).toFixed(2);
    g_driver_calc_slope = Math.round(slo*1000.)/1000.;
    $('#speed_info').html(content);
    // alert (content);
    // console.log(content);

    // update graph
    draw_chart();
    spin_bike_info();
}
// driver_calc_speed();

function f_driver_calc_speed_init () {
    g_driver_calc_speed_init = 1;

    // Params
    g_driver_calc_speed_params['P'] = 120;
    g_driver_calc_speed_params['M'] = 80;
    g_driver_calc_speed_params['revpermin'] = 60;
    g_driver_calc_speed_params['speed_brake_from'] = 3;
    g_driver_calc_speed_params['speed_brake_to'] = 7;
    g_driver_calc_speed_params['speed_brake_direction'] = -1;

    // get bike
    // setTimeout("get_car('bike_woman.kmz', 180, 1, 2.4);" , 6000);

    // UI
    var s_str = '<div id="sptabs" style="font-size: 10px; width:96%;"><ul><li><a href="#sptabs-1">Driving Information</a></li><li><a href="#sptabs-2">Speed over Distance</a></li> <li><a href="#sptabs-3">Height over Distance</a></li><li><a href="#sptabs-4">Calories Burnt</a></li><li><a href="#sptabs-5">Configuration</a></li></ul>';
    s_str+='<div id="sptabs-1" style="background-color: #242424; color: white; height: 210px; padding:3px; font-size: 10px;"" ><hr/><div style="height: 18px;"><div style="float: left;">Power you want to apply: <input onChange="javascript: f_handle_speed_input();" type="text" style="width: 5em;" speech x-webkit-speech id="speed_P" value="'+g_driver_calc_speed_params['P']+'"/> Watt</div><div id="spin_bike_info_1" style="padding-top: 3px; float: left;"></div> </div><hr/><div style="display: none;">Control the driver with speech commands:<br/> <blockquote><INPUT id="speech_input_enabled" NAME="speech_inp_checkbox"  TYPE="checkbox" />Automatically ask for a new speech command every <input onChange=""  type="text" style="width: 3em;" speech x-webkit-speech id="speed_W" value="'+ g_check_speech_cmd_interval +'"/> minutes<br/>Command:  <input onChange="javascript: f_handle_command_input();" type="text" style="width: 9em;" speech x-webkit-speech id="command_id" value=""></input> Available: power {value}, check {value}, stop, resume<div id="show_speech_result" style="display: none;"></div></blockquote><br/></div><div style="float: left;" id="spin_bike_speed_info"></div><div style="float: left;" id="spin_bike_slope_info"></div><div style="float: left;" id="spin_bike_speed2_info"></div></div>';
    // <input type="button" id="speed_params_ok" value="OK"></input>
    s_str+='<div id="sptabs-2">Loading ...</div>';
    s_str+='<div id="sptabs-3">Loading ...</div>';
    s_str+='<div id="sptabs-4">Loading ...</div>';
    s_str+='<div id="sptabs-5" style="background-color: #242424; color: white; font-size: 12px;"><div style="float: left; width: 13em;">Weight: </div><input onChange="javascript: f_handle_speed_input();" type="text" style="width: 3em;" speech x-webkit-speech id="speed_W" value="'+g_driver_calc_speed_params['M']+'"/> kg<br/><div style="float: left; width: 13em;">Typical spinning speed: </div><input onChange="javascript: f_handle_speed_input();" type="text" style="width: 3em;" speech x-webkit-speech id="speed_revmin" value="'+g_driver_calc_speed_params['revpermin']+'"/> revolutions / min<br/><div style="width: 13em; float: left;">Plot brake values from: </div><input onChange="javascript: f_handle_speed_input();" type="text" style="width: 3em;" speech x-webkit-speech id="speed_brake_from" value="'+g_driver_calc_speed_params['speed_brake_from']+'"/><br/><div style="width: 13em; float: left;">Plot brake values to:</div> <input onChange="javascript: f_handle_speed_input();" type="text" style="width: 3em;" speech x-webkit-speech id="speed_brake_to" value="'+g_driver_calc_speed_params['speed_brake_to']+'"/><br/><div style="width: 13em; float: left;">Brake moves with slope:</div> <input onChange="javascript: f_handle_speed_input();" type="text" style="width: 3em;" speech x-webkit-speech id="speed_brake_direction" value="'+g_driver_calc_speed_params['speed_brake_direction']+'"/> (-1: brake moves to lower values; 1: brake moves to higher values)<br/>  </div>        </div>';

    // stop pictures
    show_birdsv ();

    // show spinning info in pic container
    $('#pic1_container').html(s_str);
    // $( "#sptabs" ).tabs({ event: "click" });
    $("#sptabs").tabs({ event: "mouseover" });
    //$("#sptabs").bind ("tabsselect", function(event, ui) {
    //	alert (event + " " + ui);
    // });
	
    $('#birdv1').hide('fast');
    $('#pic1_container').show('fast');

    var el_cmd = document.getElementById("command_id");
    if (el_cmd)	{
	el_cmd.addEventListener('change', f_handle_command_input, false); // normal change by keyboard input
	el_cmd.addEventListener('webkitspeechchange', f_handle_command_input, false); // results from speech server 
    }
    // text-shadow: rgba(0, 0, 0, 0.199219) 0px 2px 5px;
    // window.setTimeout('document.getElementById("command_id").click();', 10000);
    // window.setTimeout('click_speech_input("command_id");', 10000);
    
}

function f_handle_speed_input() {
    g_driver_calc_speed_params['P'] = $('#speed_P').val();
    g_driver_calc_speed_params['M'] = $('#speed_W').val();
    g_driver_calc_speed_params['revpermin'] = Number($('#speed_revmin').val());
    g_driver_calc_speed_params['speed_brake_from'] = Number($('#speed_brake_from').val());
    if (g_driver_calc_speed_params['speed_brake_from'] <= 0.) {
	alert("Brake cannot be less than 0. ... correcting");
	g_driver_calc_speed_params['speed_brake_from'] = 0.05;
    }
    g_driver_calc_speed_params['speed_brake_to'] = Number($('#speed_brake_to').val());
    if (g_driver_calc_speed_params['speed_brake_to'] <= g_driver_calc_speed_params['speed_brake_from']) {
	alert("'Brake to' cannot be less than 'Brake from' ... correcting");
	g_driver_calc_speed_params['speed_brake_to'] = g_driver_calc_speed_params['speed_brake_from'] + 2.;
    }
    g_driver_calc_speed_params['speed_brake_direction'] = Number($('#speed_brake_direction').val());
    if (Math.abs(g_driver_calc_speed_params['speed_brake_direction']) != 1) {
	alert("'Brake direction' must be -1 or 1 ... correcting to -1");
	g_driver_calc_speed_params['speed_brake_direction'] = -1;
    }
    var P = g_driver_calc_speed_params['P'];
    g_v_init = nthRoot( (P * 0.93/1.2/0.39*2.) , 3, 12);
    g_F_init = P / g_v_init;
    g_spinbinfo = 0; g_gchart_ctr = 100; g_spinbinfo_ctr = 100;
    // spin_bike_info();
}

function nthRoot(num, nArg, precArg) {
  var n = nArg || 2;
  var prec = precArg || 12;
 
  var x = 1; // Initial guess.
  for (var i=0; i<prec; i++) {
    x = 1/n * ((n-1)*x + (num / Math.pow(x, n-1)));
  }
 
  return x;
}

//
// draw the different charts over distance
//
var g_gchart = 0;
var g_gchart_height = 0;
// http://code.google.com/intl/apis/chart/interactive/docs/gallery/scatterchart.html
// var g_gchart_opts = {colors: ['#D4A017'], linewidth: 1, legend: 'none', width: 540, height: 210, title: 'Speed Profile [km/h]', hAxis: {title: 'Distance [km]', titleTextStyle: {color: '#eeeeee'}}};
var g_gchart_opts = {linewidth: 3, pointSize: 5, width: 540, height: 210, title: 'Speed Profile [km/h]', hAxis: {title: 'Distance [km]', titleTextStyle: {color: '#333333'}}};
var g_gchart_opts_height = {linewidth: 3, pointSize: 5, width: 540, height: 210, title: 'Height Profile [m]', hAxis: {title: 'Distance [km]', titleTextStyle: {color: '#333333'}}};
var g_gchart_opts_kcal = {linewidth: 3, pointSize: 5, width: 540, height: 210, title: 'Calories Spent [kcal]', hAxis: {title: 'Distance [km]', titleTextStyle: {color: '#333333'}}};
// var g_speed_options = {width: 400, height: 120, redFrom: 50., redTo: 60., min: 0., max: 60.,  yellowFrom: 40., yellowTo: 50., minorTicks: 5};
var g_gchart_data;
var g_gchart_data_height;
var g_gchart_data_kcal;
var g_gchart_ctr = 30;
function draw_chart() {

    if (g_gchart_ctr++ < 20) return;

    g_gchart_ctr = 0;
    if (!g_gchart) {
	// init
	g_gchart = new google.visualization.ScatterChart(document.getElementById('sptabs-2'));
	g_gchart_height = new google.visualization.ScatterChart(document.getElementById('sptabs-3'));
	g_gchart_kcal = new google.visualization.ScatterChart(document.getElementById('sptabs-4'));
	g_gchart_data = new google.visualization.DataTable();
	g_gchart_data.addColumn('number', 'Distance [km]');    
	g_gchart_data.addColumn('number', 'Speed [km/h]');    
	g_gchart_data_height = new google.visualization.DataTable();
	g_gchart_data_height.addColumn('number', 'Distance [km]');    
	g_gchart_data_height.addColumn('number', 'Height [m]');    
	g_gchart_data_kcal = new google.visualization.DataTable();
	g_gchart_data_kcal.addColumn('number', 'Distance [km]');    
	g_gchart_data_kcal.addColumn('number', 'Calories Burnt [kcal]');    
    }

    // Add data to speed and height chart
    g_gchart_data.addRow([ DS_simulator.totalDistance/1000., g_driver_calc_speed_save*3.6 ]);
    g_gchart_data_height.addRow([ DS_simulator.totalDistance/1000., DS_simulator.groundAltitude ]);
    g_gchart_data_kcal.addRow([ DS_simulator.totalDistance/1000., g_driver_calc_cal_spent/1000. ]);
              // console.log(DS_simulator.totalDistance.toFixed(2) + " " + DS_simlator.groundAltitude.toFixed(2));
              // console.log(g_gchart_data.getNumberOfRows());
    var tselected = $('#sptabs').tabs('option', 'selected');
    switch (tselected) {
    case 1:     
	g_gchart.draw(g_gchart_data, g_gchart_opts);
	break;
    case 2:     
	g_gchart_height.draw(g_gchart_data_height, g_gchart_opts_height);
	break;
    case 3:     
	g_gchart_kcal.draw(g_gchart_data_kcal, g_gchart_opts_kcal);
	break;
    }
}

//
// draw spin bike info: brake, slope, speed
//
var g_spinbinfo = 0;
// var g_spinbinfo_height = 0;
// http://code.google.com/intl/apis/chart/interactive/docs/gallery/scatterchart.html
// var g_spinbinfo_opts = {colors: ['#D4A017'], linewidth: 1, legend: 'none', width: 540, height: 210, title: 'Speed Profile [km/h]', hAxis: {title: 'Distance', titleTextStyle: {color: '#eeeeee'}}};
var g_spinbinfo_opts = {chartArea:{left:39,top:24}, linewidth: 3, pointSize: 5, legend: 'none', width: 270, height: 150, title: 'Ergo-Fit Settings: Spinning Speed [revolutions/min]', hAxis: {title: 'Brake', titleTextStyle: {color: '#333333'}}};
// var g_spinbinfo_opts_height = {linewidth: 3, pointSize: 5, width: 540, height: 210, title: 'Height Profile [m]', hAxis: {title: 'Distance', titleTextStyle: {color: '#eeeeee'}}};

// speed and slope graph options
var g_min_slope = -0.2, g_max_slope = 0.2;
var g_speed_options = {width: 400, height: 120, min: 0., max: 60., minorTicks: 5};
var g_spinbinfo_data;
var g_spinbinfo_data_height;
var g_spinbinfo_ctr = 300;
var g_slope_data = 0,  g_speed_data = 0;
var g_slope_chart = 0,  g_speed_chart = 0;
var g_nr_of_brake_points = 12.;
var g_last_brake_sug_idx = 1;
function spin_bike_info() {

    if (!g_slope_data) {
	g_slope_data = new google.visualization.DataTable();
	g_slope_data.addColumn('string', 'Label');
	g_slope_data.addColumn('number', 'Value');
	g_slope_data.addRows(1);
	g_slope_chart = new google.visualization.Gauge(document.getElementById('spin_bike_slope_info'));
    }
    g_slope_data.setValue(0, 0, 'Slope');
    g_slope_data.setValue(0, 1, g_driver_calc_slope);
    if (g_driver_calc_slope > g_max_slope) {
	g_max_slope=Math.ceil(g_driver_calc_slope*10.)/10.;
    }
    if (g_driver_calc_slope < g_min_slope) {
	g_min_slope=Math.floor(g_driver_calc_slope*10.)/10.;
    }
    // console.log("var g_slope_options = {width: 400, height: 120, min: "+g_min_slope+", max: "+g_max_slope+" };");
    eval("var l_slope_options = {width: 400, height: 120, min: "+g_min_slope+", max: "+g_max_slope+" };");
    g_slope_chart.draw(g_slope_data, l_slope_options);

    if (!g_speed_data) {
	g_speed_data = new google.visualization.DataTable();
	g_speed_data.addColumn('string', 'Label');
	g_speed_data.addColumn('number', 'Value');
	g_speed_data.addRows(1);
	g_speed_chart = new google.visualization.Gauge(document.getElementById('spin_bike_speed2_info'));
    }
    g_speed_data.setValue(0, 0, 'Speed');
    g_speed_data.setValue(0, 1, Math.round(g_driver_calc_speed_save * 3.6 * 100.)/100.);
    g_speed_chart.draw(g_speed_data, g_speed_options);

    if (g_spinbinfo_ctr++ < 10) return;

    g_spinbinfo_ctr = 0;
    var br = 0., sp = 0., P = g_driver_calc_speed_params['P'];
    if (!g_spinbinfo) {
	// init
	// console.log("preparing g_spinbinfo");
	g_spinbinfo = new google.visualization.ScatterChart(document.getElementById('spin_bike_speed_info'));
	// g_spinbinfo_height = new google.visualization.ScatterChart(document.getElementById('sptabs-3'));
	g_spinbinfo_data = new google.visualization.DataTable();
	g_spinbinfo_data.addColumn('number', 'Brake');    
	g_spinbinfo_data.addColumn('number', 'Turns [rev/min]');    
	g_spinbinfo_data.addColumn('number', 'Driver'); // show present setting
	g_spinbinfo_data.addColumn('number', 'Suggested'); // show suggested setting
	//g_spinbinfo_data_height = new google.visualization.DataTable();
	//g_spinbinfo_data_height.addColumn('number', 'Distance [m]');    
	//g_spinbinfo_data_height.addColumn('number', 'Height [m]');    
	var l_start = g_driver_calc_speed_params['speed_brake_from'];
	var l_stop = g_driver_calc_speed_params['speed_brake_to'];
	var l_dist = (l_stop - l_start) / g_nr_of_brake_points;
	for (var br = l_start, l_i = 0; l_i <= g_nr_of_brake_points; br=br+l_dist) {
	    sp = P / br * 2.5;
	    g_spinbinfo_data.addRow([ br, sp, undefined, undefined ]);
	    console.log (l_i + ":g_spinbinfo_data: "+ br+":"+sp+" undefined, undefined ");
	    l_i++;
	}
    }
   
    // g_spinbinfo_data.addRow([ DS_simulator.totalDistance.toFixed(2), (g_driver_calc_speed_save*3.6).toFixed(2) ]);
    // console.log(DS_simulator.totalDistance.toFixed(2) + " " + DS_simlator.groundAltitude.toFixed(2));
    // console.log(g_spinbinfo_data.getNumberOfRows());
    var tselected = $('#sptabs').tabs('option', 'selected');
    switch (tselected) {
    case 0: 
	// g_spinbinfo_data.setValue(0,1, 5);    
	sp = g_driver_calc_speed_params['revpermin'];
	br = P / sp * 2.5;
	if (br < g_driver_calc_speed_params['speed_brake_from']) {
	    g_driver_calc_speed_params['speed_brake_from'] = Math.floor(br);
	    $('#speed_brake_from').val(g_driver_calc_speed_params['speed_brake_from']);
	    console.log("Brake value less than display area ... correcting to " + g_driver_calc_speed_params['speed_brake_from']);
	    g_spinbinfo = null; g_spinbinfo_data = null;
	    // $('#spin_bike_speed_info').html("");
	    return;
	}
	if (br > g_driver_calc_speed_params['speed_brake_to']) {
	    g_driver_calc_speed_params['speed_brake_to'] = Math.ceil(br);
	    console.log("Brake value greater than display area ... correcting to " + g_driver_calc_speed_params['speed_brake_to']);
	    $('#speed_brake_to').val(g_driver_calc_speed_params['speed_brake_to']);
	    g_spinbinfo = null; g_spinbinfo_data = null;
	    // $('#spin_bike_speed_info').html("");
	    return;
	}
	var idx = Math.round( (br - g_driver_calc_speed_params['speed_brake_from'])/(g_driver_calc_speed_params['speed_brake_to'] - g_driver_calc_speed_params['speed_brake_from']) *12. );
	// console.log("br = " + br + " idx = " + idx + " " + g_last_brake_sug_idx);
	g_spinbinfo_data.setValue(idx, 2, sp);
	var l_slope_intervall = 0.03;
	g_spinbinfo_data.setValue(g_last_brake_sug_idx, 3, null);
	if (Math.abs(g_driver_calc_slope) >= l_slope_intervall) {
	    // calculate suggested brake
	    var l_brake_sug_idx = idx + (Math.round(g_driver_calc_slope 
						/ l_slope_intervall)) *
		g_driver_calc_speed_params['speed_brake_direction'];
	    console.log("l_brake_sug_idx " + l_brake_sug_idx);
	    if (l_brake_sug_idx > g_nr_of_brake_points || l_brake_sug_idx < 0.) {
		// console.log("1: slope = " + g_driver_calc_slope + " " + l_brake_sug_idx);
		 $('#spin_bike_info_1').html("; Brake value outside of displayed range.");
	    } else {
		var l_spin_val = g_spinbinfo_data.getValue(l_brake_sug_idx, 1);
		// console.log("2: slope = " + g_driver_calc_slope + " " + l_brake_sug_idx + " l_brake_val " + l_spin_val);
		g_spinbinfo_data.setValue(l_brake_sug_idx, 3, l_spin_val);
		g_last_brake_sug_idx = l_brake_sug_idx;
		var l_str = '; Suggested brake: ' + g_spinbinfo_data.getValue(l_brake_sug_idx, 0).toFixed(2) + ' while spinning at ' + Math.round(l_spin_val) + ' rev/min';
		// console.log(l_str);
		$('#spin_bike_info_1').html(l_str);
	    }
	} else {
	    // console.log("3: slope = " + g_driver_calc_slope);
	    // g_spinbinfo_data.setValue(idx, 3, undefined);
	    $('#spin_bike_info_1').html("");
	}  
	g_spinbinfo.draw(g_spinbinfo_data, g_spinbinfo_opts);
	// g_spinbinfo.setSelection([{row:3,column:0},{row:5, column:null}]);
	break;
	// case 2:     g_spinbinfo_height.draw(g_spinbinfo_data_height, g_spinbinfo_opts_height);
	// break;
    }
}

function spin_bike_reset() {
    g_gchart = 0;
    g_spinbinfo = 0;
    g_slope_data = 0;	g_speed_data = 0;
    g_slope_chart = 0;  g_speed_chart = 0;
    $('#pic1_container').html("");
}

// http://codesearch.google.com/#OAMlx_jo-ck/src/third_party/WebKit/LayoutTests/fast/speech/input-onspeechchange-event.html
// http://trac.webkit.org/wiki/Writing%20Layout%20Tests%20for%20DumpRenderTree
// function click_speech_input() {

// // Clicking the speech button should fill in mock speech-recognized text.
// var input = document.getElementById('command_id');
// var x = input.offsetLeft + input.offsetWidth - 4;
// var y = input.offsetTop + input.offsetHeight / 2;
// eventSender.mouseMoveTo(x, y);
// eventSender.mouseDown();
// eventSender.mouseUp();
// }


// Add a startsWith function to String() objects.
String.prototype.startsWith = function(str)
{
    return(data.substr(0, str.length) === str);
}
// Case insensitive version of the above.
String.prototype.startsWithI = function(str)
{
    return(this.toUpperCase().substr(0, str.length) === str.toUpperCase());
}

var g_check_speech_cmd_interval = 5; // min
function f_handle_command_input(e) {

    alert("event e " + e);
    if (e.type == 'webkitspeechchange' && e.results) {
	console.log('Results: ' + e.results.length)
	    for (var i = 0, result; result = e.results[i]; ++i) {
		// Store the top level recognition result.
		if (i == 0)
		    topRecoResult = result;
		console.log("res utter " + result.utterance + " " + result.confidence);
	    } // for()
	if (topRecoResult)   {
	    var cmd = "";
	    $('#show_speech_result').html("Speech result recognized: "+topRecoResult.utterance);
	    $('#show_speech_result').fadeIn("slow");
	    if (topRecoResult.utterance.startsWithI("stop"))    {
		cmd = "stop";
	    }
	    if (topRecoResult.utterance.startsWithI("check")) {
		if (topRecoResult.utterance.toLowerCase() === "check") {
		    cmd = "check";
		} else {
		    cmd = "check";
		    var theUtterance = topRecoResult.utterance.substr("check".length);
		    g_check_speech_cmd_interval = 0. + theUtterance;
		}
	    }
	    console.log("cmd " + cmd + " " + g_check_speech_cmd_interval);
	}
    }
}


// startSpeechInput();

