
  var map;
  var geocoder;
  var deja = false;

  var user_latitude;
  var user_longitude;
  var user_county;

  var practice_names = Array();
  var practice_details = Array();
  var practice_phones = Array();
  var practice_towns = Array();
  var practice_lats = Array();
  var practice_longs = Array();
  var practice_dists = Array();

  var obj_divs = Array();

  function GLoad()
  {
    if (GBrowserIsCompatible())
    {
      map = new GMap2(document.getElementById("map"));
      //map.setCenter(new GLatLng(55, -4.5), 5);
      map.addControl(new GSmallMapControl());
      map.addControl(new GMapTypeControl());
      geocoder = new GClientGeocoder();
      geocoder.setBaseCountryCode('UK');
    }
    else
      alert ("Please use Internet Explorer 7, Firefox 2 or Safari to view this page.");
  }

  function addEvent( obj, type, fn )
  {
  	if (obj.addEventListener)
  		obj.addEventListener( type, fn, false );
  	else if (obj.attachEvent)
  	{
  		obj["e"+type+fn] = fn;
  		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
  		obj.attachEvent( "on"+type, obj[type+fn] );
  	}
  }

  //window.addEventListener('load', GLoad, false);
  addEvent(window, 'unload', GUnload, false);     
  
  /**
   * Search on a post code
   */
  function searchPostCode(postcode)
  {
    var address;

    if (deja == false)
    {
      deja = true;
      GLoad();
    }

    address = document.getElementById('id-el-search-postcode').value;
    geocoder.getLocations(address, geocoderCallback);
  }

  /**
   * Capture the call-back from the geocoder object
   */
  function geocoderCallback(response)
  {
    if (!response || response.Status.code != 200)
    {
      /**
       * Show some error message - inline HTML?
       */
      alert("Unable to Geocode: please check your postcode and try again.");
    }
    else
    {
      /**
       * Clear all previous pointers
       */
      map.clearOverlays();

      /**
       * Decode the response and store the (lat, long)
       */
      obj_placemark = response.Placemark[0];
      
      user_latitude = obj_placemark.Point.coordinates[1];
      user_longitude = obj_placemark.Point.coordinates[0];

      if (obj_placemark.AddressDetails.Country.AdministrativeArea && obj_placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea)
        user_county = obj_placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName;

      /**
       * Centre the map on our location
       */
      obj_latlong = new GLatLng(user_latitude, user_longitude);          
      map.setCenter(obj_latlong, 11);

      /**
       * Now go get the local practices
       */
      window.setTimeout('getLocalPractices()', 10)
    }
  }
  
  
  
  
  /**
   * Centre the map on a (lat,long).
   */
  function setCentre(event)
  {
    if (event["target"])
      i = event["target"]["myid"];
    else
      i = event["srcElement"]["myid"];
    
    var obj_latlong = new GLatLng(practice_lats[i], practice_longs[i]);
    map.setCenter(obj_latlong, 11);
    var msg = "<b>" + practice_names[i] + "</b><br />" + practice_phones[i];
    map.openInfoWindowHtml(obj_latlong, msg);
  }



  /**
   * Add markers for each practice
   */
  function plotLocalPractices()
  {
    /**
     * Iterate through the practices, plotting and drawing each.
     */
    var i = 0;
    var count = practice_names.length;

    obj_results = document.getElementById('results');
  
    while (obj_results.firstChild)
       obj_results.removeChild(obj_results.firstChild);

    for (i = 0; i < count; ++i)
    {
      obj_divs[i] = document.createElement("div");
      obj_divs[i].style.paddingTop = "0.25em";
      obj_divs[i].style.paddingLeft = "0.25em";
                
      t_node_1 = document.createElement("strong");
    
      t_node_2 = document.createTextNode(practice_names[i] + ' ');
      t_node_1.appendChild(t_node_2);
      t_node_3 = document.createTextNode(practice_phones[i]);
      t_node_1.appendChild(t_node_3);
      
      t_node_4 = document.createElement("br");
      
      t_node_5 = document.createTextNode(practice_dists[i] + ' miles away ');
      t_node_6 = document.createElement("a");
      addEvent(t_node_6, 'click', setCentre);
      t_node_6.myid = i;
      t_node_7 = document.createTextNode('[Show]');
      t_node_6.appendChild(t_node_7);
      
      t_node_8 = document.createTextNode(' ' + practice_details[i] + ', ' + practice_towns[i]);

    
      obj_divs[i].appendChild(t_node_1);
      obj_divs[i].appendChild(t_node_4);
      obj_divs[i].appendChild(t_node_5);
      obj_divs[i].appendChild(t_node_6);
      obj_divs[i].appendChild(t_node_8);
      obj_results.appendChild(obj_divs[i]);

      obj_latlong = new GLatLng(practice_lats[i], practice_longs[i]);
      map.addOverlay(makeMagicMarker(obj_latlong, i));
    }
    
    document.getElementById('caveats').style.display = '';
  }

  function makeMagicMarker(latlng, number)
  {
    var marker = new GMarker(latlng);
  
    GEvent.addListener( marker,
                        "click",
                        function()
                        {
                          var msg = "<b>" + practice_names[number] + "</b><br />" + practice_phones[number];
                          map.openInfoWindowHtml(latlng, msg);
                          showPracticeDetails(number);
                        }
                      );
  
    return marker;
  }


  /**
   * Shared practice details show/unshow.
   */
  function showPracticeDetails(x)
  {
    /**
     * Unshow all previous details
     */
    var i = 0;
    var count = practice_names.length;

    for (i = 0; i < count; ++i)
    {
      obj_divs[i].style.backgroundColor = '#ffffff';
    }
  
    /**
     * Show new details
     */
    obj_divs[x].style.backgroundColor = '#ddffdd';
  }



  /**
   * Retrieve the practice details.
   */
  function getLocalPractices()
  {
    /**
     * Execute RPC call
     */
     xmlrpcTimeout = 15;

     params = new Array();
     params['latitude'] = user_latitude;
     params['longitude'] = user_longitude;
     params['county'] = user_county;

     xdata = XMLHttpFormRequest('optSearch', params); 
     XMLHttpMakeRequest("/rpc.php", xdata, getLocalPracticesCb);
  }



  /**
   * Catch the callback from the XML-RPC operation.
   */
  function getLocalPracticesCb(attribs)
  {
    if (attribs == undefined)
      return;

    /**
     * Decode response
     */
    practice_names = attribs['names'];
    practice_details = attribs['details'];
    practice_towns = attribs['towns'];
    practice_phones = attribs['phones'];
    practice_lats = attribs['lats'];
    practice_longs = attribs['longs'];
    practice_dists = attribs['dists'];
  
    /**
     * Pass to plotting routine
     */
    plotLocalPractices();
  }



  function print_r(obj)
  {
    alert (return_r(obj));
  }



  function return_r(obj, offset)
  {
    var o;

    o = "";
    if (!offset)
      offset = 0;

    for (i = 0; i < offset; i++)
      o += "- - "; 

    if (typeof obj == typeof new Array)
    {
      r = o + "Array\n" + o + "(\n";

      for (key in obj)
        r +=  o + "- - [" + key + "]" + return_r(obj[key], offset+1) + "\n";

      r += o + ")\n";
      return r;
    }
    else
      return o + obj;

  }
