/* Copyright 2007 Google Inc.
 * All Rights Reserved
 */

/*
 * Main web client mapping application to view Map databases
 * published by Fusion.
 *
 * optional URL parameters:
 *   ll             : override default initial view latitude & longitude
 *   z              : override default initial zoom level
 *   search_timeout : override default search timeout value
 *   debug          : enables a debug dialog
 */

/*
 * preference constants
 */
var INITIAL_VIEW_LAT = 32.898;
if (typeof(INITIAL_VIEW_LAT_OVERRIDE) != "undefined") {
  if (INITIAL_VIEW_LAT_OVERRIDE > -90 &&
      INITIAL_VIEW_LAT_OVERRIDE < 90) {
    INITIAL_VIEW_LAT = INITIAL_VIEW_LAT_OVERRIDE;
  }
}

var INITIAL_VIEW_LON = -110.39;
if (typeof(INITIAL_VIEW_LON_OVERRIDE) != "undefined") {
  if (INITIAL_VIEW_LON_OVERRIDE > -180 &&
      INITIAL_VIEW_LON_OVERRIDE < 180) {
    INITIAL_VIEW_LON = INITIAL_VIEW_LON_OVERRIDE;
  }
}

var MAX_ZOOM_LEVEL = 23;
if (typeof(MAX_ZOOM_LEVEL_OVERRIDE) != "undefined") {
  if (MAX_ZOOM_LEVEL_OVERRIDE > 0 && MAX_ZOOM_LEVEL_OVERRIDE < MAX_ZOOM_LEVEL)
    MAX_ZOOM_LEVEL = MAX_ZOOM_LEVEL_OVERRIDE;
}

var INITIAL_VIEW_ZOOM = 6;
if (typeof(INITIAL_VIEW_ZOOM_OVERRIDE) != "undefined") {
  if (INITIAL_VIEW_ZOOM_OVERRIDE > 0 &&
      INITIAL_VIEW_ZOOM_OVERRIDE <= MAX_ZOOM_LEVEL) {
    INITIAL_VIEW_ZOOM = INITIAL_VIEW_ZOOM_OVERRIDE;
  }
}

if (typeof(FUSION_MAP_SERVER_OVERRIDE) != "undefined") {
  FUSION_MAP_SERVER = FUSION_MAP_SERVER_OVERRIDE;
}

var FUSION_PATH = FUSION_MAP_SERVER + "/maps/mapfiles/";


// how long to wait (in milliseconds) before determining the search failed
var SEARCH_TIMEOUT = 5000;  // 5 seconds seems OK

/*
 * interface to add additional tile layers
 */
var layer_manager = null;

/*
 * the Google Fusion Maps API object
 */
var map;

var searchresults_docker;
var myplaces_docker;
var layers_docker;
var search_manager = null;
var DebugMsg = null;
var placemark_manager = null;

// allow user to override the default search timeout
// this could be useful when debugging slow network connections
// for example, append "?search_timeout=10000" on URL for 10 second timeout
var search_timeout = SEARCH_TIMEOUT;
// override with "?ll=32.898,-100.30" on URL
var initial_view = new GLatLng(INITIAL_VIEW_LAT, INITIAL_VIEW_LON);
// override with "?z=8" on URL
var initial_zoom = INITIAL_VIEW_ZOOM;
var map = null;
function LoadMap() {
  InitBaseIcon();

  var fusionmap_elem = FindElement("map_canvas");
  if (!fusionmap_elem) {
    alert("Cannot initialize map!  HTML document is corrupt.");
    return;
  }

  if (GetPageURLParameter("ll")) {
    var latlng = GetPageURLParameter("ll").split(',');
    if (latlng.length == 2) {
      initial_view = new GLatLng(parseFloat(latlng[0]), parseFloat(latlng[1]));
    }
  }
  // Get the default view if the initial view is not already initialized.
  if (initial_view == 0)
    initial_view = new GLatLng(INITIAL_VIEW_LAT, INITIAL_VIEW_LON);

  if (GetPageURLParameter("z")) {
    initial_zoom = parseInt(GetPageURLParameter("z"));
  }

  if (GetPageURLParameter("search_timeout")) {
    search_timeout = GetPageURLParameter("search_timeout");
  }

  if (GBrowserIsCompatible()) {
		
  
	  
	  
	  
    // We need a new div element for GMap to own.
    var map_elem = CreateElement(fusionmap_elem, "div", "map");
    map = new GFusionMap(map_elem);
	map = map;
	try {
		//map.setCenter(new GLatLng(-76, 39), 8);
		//map.setMapType(G_PHYSICAL_MAP);
		
		map.enableDoubleClickZoom();
		map.enableContinuousZoom();	
		
		smallMapView = new GOverviewMapControl();
		map.addControl(smallMapView);
		
		scaleControl = new GScaleControl();
		map.addControl(scaleControl);		
		
		map.addControl(myDragZoom);	
		//map.addControl(new ministryCopyRight());				
		
		GEvent.addListener(map,"mousemove", function(point) {
			deneme = document.getElementById("mouseCoords");
			deneme.innerHTML = "X : " + point.x.toFixed(4) + ", Y : " + point.y.toFixed(4);
		}); 
	}
	catch (e)
	{
	}
    map.setCenter(initial_view, initial_zoom);
    map.showInitialFusionLayers();

    // enable debug msg dialog if requested
    // to enable debug mode, append "?debug" on URL
    if (GetPageURLParameter("debug")) {
      debug_dialog = new Dialog(fusionmap_elem, "debug_dialog",
          "DEBUG MESSAGES", "600px", "200px");
      debug_dialog.Show();
      debug_dialog.AppendText(navigator.userAgent);
      DebugMsg = function(txt) { debug_dialog.AppendText(txt); }
    } else {
      DebugMsg = function() {}
    }

    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.addControl(new GOverviewMapControl());
    scale_control = new GScaleControl();
    map.addControl(scale_control);
    new GKeyboardHandler(map);
    map.enableDoubleClickZoom();
    map.enableScrollWheelZoom();
    Resize();
    InitializeLayers(fusionmap_elem);
    placemark_manager = new PlacemarkManager(fusionmap_elem);
    InitializeSearch(fusionmap_elem);
  }

}
function GetElementStyle(elem, style) {
  var computed_style = document.defaultView.getComputedStyle(elem, null);
  return computed_style.getPropertyValue(style);
}
function Resize() {
  var new_height = -1;
  var new_width = -1;

  var header_elem = FindElement("header_bar");
  var sidepanel_elem = FindElement("sidepanel");

  var navTool_Element = FindElement("navToolbar");
  var statusWindow_Element = FindElement("statusWindow");
  var mainWindow_Element = FindElement("mainWindow");
//  alert(document.parentNode.nodeName);
//  document.getElementsByName

    
  if (!IsBrowser("MSIE")) {   // Firefox, Safari, etc.
    if (statusWindow_Element) {
		FindElement("mainWindow").style.height = (document.body.clientHeight - parseInt(GetElementStyle(statusWindow_Element, "height"))) + "px";
		if (navTool_Element) {
			new_height = parseInt(GetElementStyle(mainWindow_Element, "height")) - parseInt(GetElementStyle(navTool_Element, "height"));
		}
    }
	else
	{
		if (navTool_Element) {
			new_height = document.body.clientHeight - parseInt(GetElementStyle(navTool_Element, "height"));
		}
	}
	new_width = document.body.clientWidth;
    if (sidepanel_elem) {
      new_width = new_width -65;
    }
  } else {                    // MSIE
  	if (statusWindow_Element) {
		FindElement("mainWindow").style.height = (document.body.clientHeight - parseInt(statusWindow_Element.currentStyle.height)) + "px";
		if (navTool_Element) {
			new_height = parseInt(mainWindow_Element.currentStyle.height) - parseInt(navTool_Element.currentStyle.height);
		}
    }
	else
	{
		if (navTool_Element) {
			new_height = document.body.clientHeight - parseInt(navTool_Element.currentStyle.height);
		}
	}
	
    new_width = document.body.clientWidth;
    if (sidepanel_elem) {
      new_width = new_width -
          parseInt(sidepanel_elem.currentStyle.width);
    }
  }

  FindElement("fusion_map").style.height = "500px";
  FindElement("fusion_map").style.width = "500px";
  if (sidepanel_elem)
    sidepanel_elem.style.height = new_height + "px";
}

function InitializeLayers(parent) {
  // if we can find a sidepanel element, place the layer controls in it
  // otherwise, create a floating dialog
  if (layers_docker) {
    var pane = layers_docker.AddPane("");
    layer_manager = new GF_Layers(pane.GetBodyDiv());
    pane.Show();
  } else {
    var layers_dialog = new Dialog(parent, "layers_dialog", "Layers");
    layers_dialog.Show();
    layer_manager = new GF_Layers(layers_dialog.GetBodyDiv());
  }

  // fusion built layers
  var layer_count = map.getFusionLayerCount();
  if (layer_count > 0) {
  
    var allLayers = "";
    var visLayers = "";
    for (var lyr = 0; lyr < layer_count; ++lyr) {
        allLayers += map.getFusionLayerName(lyr) + ",";
        if (map.isFusionLayerVisible(lyr) == true)
            visLayers += map.getFusionLayerName(lyr) + ",";
    }
    allLayers = allLayers.substring(0, allLayers.length-1);
    visLayers = visLayers.substring(0, visLayers.length-1);
    addLayerToIdList("Visible Layers", visLayers);
    addLayerToIdList("All Layers", allLayers);
    
    
    for (var lyr = 0; lyr < layer_count; ++lyr) {
      addLayerToIdList(map.getFusionLayerName(lyr), map.getFusionLayerName(lyr));
      addLayerToQueryList(map.getFusionLayerName(lyr), map.getFusionLayerName(lyr));
      layer_manager.AddLayer(map.getFusionLayerName(lyr),
                             map.getFusionLayerIcon(lyr),
                             map.isFusionLayerVisible(lyr),
                             FusionCheckLayerToggle(lyr),
                             "checkbox");
    }
  }
}
function FusionCheckLayerToggle(layerId) {
  return function() {
    if (map.isFusionLayerVisible(layerId))
    {
      map.hideFusionLayer(layerId);
    }
    else
    {
      map.showFusionLayer(layerId);
    }
    
    var elSel = document.getElementById('idLayerList');
    var selIdx = elSel.selectedIndex;
    var layer_count = map.getFusionLayerCount();
    if (layer_count > 0) 
    {
        var visLayers = "";
        for (var lyr = 0; lyr < layer_count; ++lyr) 
        {
            if (map.isFusionLayerVisible(lyr) == true)
                visLayers += map.getFusionLayerName(lyr) + ",";
        }
        visLayers = visLayers.substring(0, visLayers.length-1);
        elSel.remove(0);
        var elOptNew = document.createElement('option');
        elOptNew.text = "Visible Layers";
        elOptNew.value = visLayers;
        var elOptOld = elSel.options[0];  
        try 
        {
          elSel.add(elOptNew, elOptOld); // standards compliant; doesn't work in IE
        }
        catch(ex) 
        {
          elSel.add(elOptNew, 0); // IE only
        }
    }
    elSel.selectedIndex = selIdx;
  };
}

function addLayerToQueryList(text, value)
{
    try
    {
        var elOptNew = document.createElement('option');
        elOptNew.text = text;
        elOptNew.value = value;
        queries.push(value + "|||OFF|||");
        var elSel = document.getElementById('TableOneList');
        try {
            elSel.add(elOptNew, null); // standards compliant; doesn't work in IE
        }
        catch(ex) {
            elSel.add(elOptNew); // IE only
        }
    }
    catch(ex2) {
    }
}
function addLayerToIdList(text, value)
{
    var elOptNew = document.createElement('option');
    elOptNew.text = text;
    elOptNew.value = value;
    var elSel = document.getElementById('idLayerList');
    try {
        elSel.add(elOptNew, null); // standards compliant; doesn't work in IE
    }
    catch(ex) {
        elSel.add(elOptNew); // IE only
    }
}


function FusionRadioLayerToggle(layerId) {
  return function() {
    var layer_count = map.getFusionLayerCount();
    for (var lyr = 0; lyr < layer_count; ++lyr) {
      if (lyr != layerId) {
        map.hideFusionLayer(lyr);
      }
    }
    map.showFusionLayer(layerId);
  };
}

/******************************************************************************
 * Search
 ******************************************************************************/

var results_container;

function InitializeSearch(map_elem) {
  try
  {
      // only configure searching if the search_box div can be found
      var search_box = FindElement("search_box");
      if (!search_box || !search_tab_defs || search_tab_defs.length == 0)
        return;

      // install 'loading...' status message object
      var loading_msg = CreateElement(document.body, "div", "loader");
      loading_msg.style.visibility = 'hidden';
      loading_msg.appendChild(document.createTextNode("loading..."));

      // install search tabs here
      var search_tabs = new Tab(search_box);

      for (t = 0; t < search_tab_defs.length; ++t) {
        var search_def = search_tab_defs[t];
        var tab_body = search_tabs.AddTab(search_def.tabLabel);

        // assemble search boxes
        var form_elem = CreateElement(tab_body, "form");

        // Create elements with id's that are unique for each tab
        // by appending the tab id.
        var table = CreateElement(form_elem, "table", "search_input_table");
        var tbody = CreateElement(table, "tbody");
        var input_row = CreateElement(tbody, "tr", "search_input_row");
        var label_row = CreateElement(tbody, "tr", "search_label_row");

        // Used if there would be more than one input per form
        // 2 are possible now, but maybe more in the future?
        var arg_num = 0;
        while (search_def.args[arg_num]) {
          var label = CreateElement(label_row, "td");
          // Use innerHTML to avoid escaping html tags.
          //label.innerHTML = search_def.args[arg_num].screenLabel;
          var td = CreateElement(input_row, "td");
          var text_input = CreateInputElement(td, "text");
          text_input.className = "search_text";
          text_input.id = "search_text" + arg_num;
          text_input.style.width = "300px";
          search_def.args[arg_num].search_element = text_input;

          ++arg_num;
        }

        var row_elem = CreateElement(input_row, "td");
        var submit_btn = document.createElement("input");
        submit_btn.setAttribute("type", "submit");
        submit_btn.setAttribute("value", "Search");
        row_elem.appendChild(submit_btn);
//        var row_elem2 = CreateElement(input_row, "td");
//        var cancel_btn = document.createElement("input");
//        cancel_btn.setAttribute("type", "button");
//        cancel_btn.setAttribute("value", "Clear");
//        cancel_btn.onclick =  ClearFunc();
//        row_elem2.appendChild(cancel_btn);
        // Set the on submit callback to refer to this search_def.
        form_elem.onsubmit =  SearchFunc(search_def);

      }
    }
    catch (ex)
    {
        alert(ex);
    }
  search_manager = new SearchManager(map_elem);
}
function ClearFunc() {
    try
    {
        if (geOn)
            searchManager2.reset();
        else
            search_manager.Reset();
        var count = 0;
        while(document.getElementById('search_text'+count))
        {
            document.getElementById('search_text'+count).value = '';
            count++;
        }
    }
    catch (ex)
    {
        alert(ex);
    }
    return false;
}
function SearchFunc(tabdef) {
  return function() {
    SubmitSearch(tabdef);
    return false;
  }
}

function SubmitSearch(tabdef, vals) {
if (dijit.byId('search_frame'))
{
    dijit.byId('search_frame').open=false;
    dijit.byId('search_frame').toggle();
}
  StartLoading();

  var baseUrl = tabdef.url;
  if (baseUrl.indexOf('?') == -1)
    baseUrl += '?';

  for (var a = 0; a < tabdef.args.length; ++a) {
    if (tabdef.args[a].search_element.value != "") {
      baseUrl += '&' + tabdef.args[a].urlTerm + '=' +
        window.encodeURIComponent(tabdef.args[a].search_element.value);
    }
  }
  var geocoder = new GF_Geocoder();
  geocoder.query(baseUrl,
                 function(results) {
                   EndLoading();
                   HandleResults(results)
                 });
}

function HandleResults(reply) {
  if (reply.success == false) {
    alert("Search failed!\n\nMessage: " + reply.failureMessage);
    return;
  }

  // cleanup any previous results only if the search was successful
  search_manager.Reset();

  DebugMsg("displayKeys: " + reply.displayKeys);
  DebugMsg("flyToFirstElement: " + reply.flyToFirstElement);
  DebugMsg("success: " + reply.success);
  if (reply.responses.length != undefined)
    DebugMsg("responses.length = " + reply.responses.length);

  for (var r = 0; r < reply.responses.length; ++r) {
    var response = reply.responses[r];

    DebugMsg("[" + r + "] datastoreName: " + response.datastoreName);
    DebugMsg("[" + r + "] success: " + response.success);
    if (response.success == false) {
        search_manager.AddFailedSearch();
        
      
    } else {
      if (response.data != undefined) {
        DebugMsg("[" + r + "] data.length: " + response.data.length);
        for (var d = 0; d < response.data.length; ++d) {
          var data = response.data[d];
          DebugMsg("element # " + d + " raw-->" + data);
          if (!data || !data.lon)
            break;
          DebugMsg("--> [" + d + "] lon: " + data.lon);
          DebugMsg("--> [" + d + "] lat: " + data.lat);
          DebugMsg("--> [" + d + "] name: " + data.name);
          if (data.description)
            DebugMsg("--> [" + d + "] description: " + data.description);
          if (data.snippet)
            DebugMsg("--> [" + d + "] snippet: " + data.snippet);

          var txt = "";
          if (data.name)
            txt += "Name: " + data.name + "<br>";
          if (data.description)
            txt += data.description + "<br>";

          search_manager.AddMarker(data);
          map.setZoom(17);
          resetTools();
        }
      }
    }
  }

  search_manager.GotoFirstResult();
}

function StartLoading() {
  var loading_msg = FindElement("loader");
  if (loading_msg) {
    loading_msg.style.visibility = 'visible';
  }
}

function EndLoading() {
  var loading_msg = FindElement("loader");
  if (loading_msg) {
    loading_msg.style.visibility = 'hidden';
  }
}

/******************************************************************************
 * SearchManager class
 ******************************************************************************/
function SearchManager(map_elem) {
  this.results_map_markers = [];
  this.first_result = null;
  this.open_info_window = false;

  this.showme = null;

  var div;
  if (searchresults_docker) {
    var pane = searchresults_docker.AddPane("");
    div = pane.GetBodyDiv();
    this.showme = function() { pane.Show(); };
    //pane.AddCloseButton(this, function() { this.Reset(); });
  } else {
    var results_dialog = new Dialog(map_elem, "search_dialog",
        "Search Results", "400px", "200px");
    div = results_dialog.GetBodyDiv();
    this.showme = function() { results_dialog.Show(); };
  }
  this.search_results_div = div;
  var table = CreateElement(div, "table", "search_results_table");
  this.search_results_tbody = CreateElement(table, "tbody");
}

SearchManager.prototype.Reset = function() {
  // cleanup map markers
  for (var i = 0; i < this.results_map_markers.length; i++)
    map.removeOverlay(this.results_map_markers[i]);
  this.results_map_markers.length = 0;
  RemoveAllChildren(this.search_results_tbody);
  //this.search_results_tbody = null;
  this.first_result = null;
  if (this.open_info_window) {
    map.closeInfoWindow();
    this.open_info_window = false;
  }
}

SearchManager.prototype.GotoFirstResult = function() {
  if (this.first_result)
    map.panTo(this.first_result);
}
SearchManager.prototype.AddFailedSearch = function() {
    var tr = CreateElement(this.search_results_tbody, "tr");
    var text_td = CreateElement(tr, "td");
    var name_div = CreateElement(text_td, "div", "search_results_name");
    name_div.innerHTML = "0 Results Found";
    this.showme();
}

SearchManager.prototype.AddMarker = function(cfg) {
  var index = this.results_map_markers.length;
  var point = new GLatLng(cfg.lat, cfg.lon);
  if (index == 0)
    this.first_result = point;

  var desc = "";
  if (cfg.description)
    desc = cfg.description;
  var popup = CreateInfoBody(cfg.name, desc, "Save to My Places",
      function() {
        placemark_manager.AddPlacemark({txt: cfg.name,
                                        lat: cfg.lat,
                                        lng: cfg.lon,
                                        zoom: map.getZoom()}, true);
        //search_manager.Reset();
        placemark_manager.Save();
      });

  var marker = CreateMarker(point, popup, this.results_map_markers.length);

  // keep track of info window openings in order to close
  // when the search results are cleared
  GEvent.bindDom(marker, "infowindowopen", this,
                 function() { this.open_info_window = true; });
  GEvent.bindDom(marker, "infowindowclose", this,
                 function() { this.open_info_window = false; });

  map.addOverlay(marker);
  this.results_map_markers.push(marker);

  var tr = CreateElement(this.search_results_tbody, "tr");
  var icon_td = CreateElement(tr, "td", "search_results_icon");
  // drop icons after A-Z has been used
  var img_elem = CreateElement(icon_td, "img");
  if (index < 26) {
    var letter = String.fromCharCode("A".charCodeAt(0) + index);
    img_elem.setAttribute("src", FUSION_PATH + "marker" + letter + ".png");
  } else {
    img_elem.setAttribute("src", FUSION_PATH + "marker.png");
  }
  img_elem.style.cursor = "pointer";
  GEvent.bindDom(img_elem, "click", this, this.NewCenterViewFunc(point));

  var text_td = CreateElement(tr, "td");
  // name should always be defined
  var name_div = CreateElement(text_td, "div", "search_results_name");
  name_div.innerHTML = cfg.name;
  // only show snippet if one is defined
  if (cfg.snippet != undefined) {
    var snippet_div = CreateElement(text_td, "div", "search_results_snippet");
    snippet_div.innerHTML = cfg.snippet;
  }

  this.showme();
}

SearchManager.prototype.NewCenterViewFunc = function(pos) {
  return function(e) {
    map.setZoom(17);
    map.panTo(pos);
    cancelEvent(e);
    return false;
  }
}

function CreateInfoBody(label, body_text, btn_name, btn_func) {
  var info_div = document.createElement("div");
  var name_div = CreateElement(info_div, "div", "search_popup_name");
  name_div.innerHTML = label;
  var  body_div = CreateElement(info_div, "div", "search_popup_body");
  body_div.innerHTML = body_text;

  var btn = CreateElement(info_div, "a", "info_window_btn");
  btn.href = 'javascript:void(0)';
  btn.appendChild(document.createTextNode(btn_name));

  GEvent.bindDom(btn, 'click', this, function(e) {
    btn_func();
    cancelEvent(e);
    return false;
  });

  return info_div;
}

// Create a base icon for all of our markers that specifies the
// shadow, icon dimensions, etc.
var baseIcon = 0; // To be initialized in LoadMap().

// Initialize variables in LoadMap() after all javascript has been loaded.
function InitBaseIcon() {
	baseIcon = new GIcon();
	baseIcon.shadow = FUSION_PATH + "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);
	baseIcon.infoShadowAnchor = new GPoint(18, 25);
}

function CreateMarker(point, popup_body, index) {
  var icon;
  // only specialize the marker icon if the index is A-Z
  if ((index != null) && (index < 26)) {
    var letter = String.fromCharCode("A".charCodeAt(0) + index);
    var icon = new GIcon(baseIcon);
    icon.image = FUSION_PATH + "marker" + letter + ".png";
  }
  var marker = new GMarker(point, icon);
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindow(popup_body);
  });
  return marker;
}

/******************************************************************************
 * Geocoder class
 ******************************************************************************/

function GF_Geocoder() {
  // create a global store object where all callbacks are added/deleted
  if (!window.__gf_queryStore) {
    window.__gf_queryStore = {};
  }
}

GF_Geocoder.prototype.query = function(baseUrl, handler) {
  // generate unique id for this "script"
  var id = "gf_query_" + new Date().getTime();

  // if the script never loads we need a way to cancel the request
  var timeout = window.setTimeout(NewErrorCallback(id, handler, baseUrl, 403), search_timeout);

  window.__gf_queryStore[id] = NewCallback(this, id, handler, timeout);

  var script = document.createElement("script");
  script.type = "text/javascript";
  script.id = id;
  script.charset = "UTF-8";
  script.src = baseUrl + "&cb=__gf_queryStore." + id;
  //DebugMsg("adding script tag: " + script.src);
  try {
    document.getElementsByTagName("head")[0].appendChild(script);
  } catch(err) {
    alert("Error!");
  }
}

function RemoveScriptNode(id) {
  var script = document.getElementById(id);
  if (script && script.nodeName == "SCRIPT") {
    script.parentNode.removeChild(script);
  }
}

function NewErrorCallback(id, handler, query, error) {
  return function() {
    RemoveScriptNode(id);
    handler(NewErrorReply(query, error));
    if (id && window.__gf_queryStore[id]) {
      delete window.__gf_queryStore[id];
    }
    alert("Search Failed.");
  }
}

function NewCallback(geocoder, id, handler, timeout) {
  return function(reply) {
    window.clearTimeout(timeout);
    RemoveScriptNode(id);
    handler(reply);
    delete window.__gf_queryStore[id];
  };
}

function NewErrorReply(query, errorCode) {
  return {
    success: false,
    searchTerm: query,
    failureMessage: "network error"
  };
}

/******************************************************************************
 * Tile Layer Checkbox Management
 ******************************************************************************/

function GF_Layers(parent) {
  var form = CreateElement(parent, "form", "layers_container");
  var table = CreateElement(form, "table", "tile_layers");
  this.main_tbody = CreateElement(table, "tbody");
}

/*
 * input_type must be "radio" or "checkbox"
 */
GF_Layers.prototype.AddLayer = function(text, icon, init_state,
                                        click_func, input_type) {

  var row = CreateElement(this.main_tbody, "tr");

  // configure checkbox
  var td = CreateElement(row, "td");
  var input_elem;

  if (input_type == 'radio') {
    input_elem = CreateRadioInputElement(td, 'radioLayer');
  } else {
    input_elem = CreateInputElement(td, input_type);
  }
  
  GEvent.bindDom(input_elem, "click", this, click_func);

  if (init_state == true) {
    input_elem.checked = "checked";
  } else {
    input_elem.checked = "";
  }

  // configure (optional) icon image
  td = CreateElement(row, "td");  // always create the 'td' for spacing reasons
  if (icon) {
    var img_elem = CreateElement(td, "img");
    img_elem.setAttribute("src", icon);
    img_elem.setAttribute("align", "texttop");
  }

  // configure label string
  td = CreateElement(row, "td");
  var span = CreateElement(td, "span");
  CreateTextNode(span, text);
}

/******************************************************************************
 * A simple placemark system
 *
 * Placemark data config structure:
 *   var txt (string) - Label
 *   var lat (float)  - Latitude of point
 *   var lng (float)  - Longitude of point
 *   var zoom (int)   - Zoom level
 *
 ******************************************************************************/
var MYPLACES_COOKIE = 'myplaces';

function PlacemarkManager(parent) {
    try
    {
  this.placemark_defs = [];
  this.handler;
  this.main_widget;
  if (myplaces_docker) {
    var pane = myplaces_docker.AddPane("");
    this.main_widget = pane;
  } else {
    var placemark_dialog = new Dialog(parent, "placemark_dialog", "My Places");
    this.main_widget = placemark_dialog;
  }

  var form = CreateElement(this.main_widget.GetBodyDiv(),
      "form", "myplaces_container");
  var table = CreateElement(form, "table");
  this.main_tbody = CreateElement(table, "tbody");

  var placemark_cookie = GetCookieValue(MYPLACES_COOKIE);
  if (placemark_cookie) {
    var placemarks = placemark_cookie.split('|');
    for (var p = 0; p < placemarks.length; ++p) {
      var parms = placemarks[p].split(':');
      if (parms.length == 4) {
        var def = {
          txt: unescape(parms[0]),
          lat: parseFloat(parms[1]),
          lng: parseFloat(parms[2]),
          zoom: parseInt(parms[3], 10)
        };
        this.AddPlacemark(def, false);
      } else {
        DebugMsg("Bad placemark cookie: " + placemarks[p]);
      }
    }
  }

  var add_btn = CreateElement(this.main_widget.GetFooterDiv(), 'a');
  add_btn.href = 'javascript:void(0)';
  GEvent.bindDom(add_btn, 'click', this, function(e) {
    var center = map.getCenter();
    this.NewPlacemarkAtPoint(center);
    cancelEvent(e);
    resetTools();
    return false;
  });
  add_btn.appendChild(document.createTextNode("Add"));

  this.main_widget.Show();
  }
  catch (ex)
  {
    alert(ex);
  }
}

PlacemarkManager.prototype.Save = function() {
  var me = this;
  var cookie = "";

  for (var p = 0; p < me.placemark_defs.length; ++p) {
    if (cookie)
      cookie += '|';
    cookie += escape(me.placemark_defs[p].txt) +
        ':' + me.placemark_defs[p].lat +
        ':' + me.placemark_defs[p].lng +
        ':' + me.placemark_defs[p].zoom;
  }
  var date = new Date();
  date.setTime(date.getTime()+315360000000);/* expires one year from now */
  cookie += "; expires="+date.toGMTString(); 
  SetCookieValue(MYPLACES_COOKIE, cookie);
}

PlacemarkManager.prototype.Delete = function(def) {
  var me = this;
  for (var p = 0; p < me.placemark_defs.length; ++p) {
    if (me.placemark_defs[p] == def) {
      me.placemark_defs.splice(p, 1);
      def.entry_elem.parentNode.removeChild(def.entry_elem);
      this.Save();
      break;
    }
  }
}

PlacemarkManager.prototype.NewPlacemarkAtPoint = function(point) {
  var div_elem = document.createElement("div");
  div_elem.style.padding = "0px 10px 0px 10px";
  var table_elem = CreateElement(div_elem, "table");
  var tbody = CreateElement(table_elem, "tbody");
  var row0 = CreateElement(tbody, "tr");
  var row0_c0 = CreateElement(row0, "td");
  row0_c0.appendChild(document.createTextNode("Label:"));
  var row0_c1 = CreateElement(row0, "td");
  var form_elem = CreateElement(row0_c1, "form");
  var label_elem = CreateInputElement(form_elem, "text");
  label_elem.style.width = "200px";

  var row1 = CreateElement(tbody, "tr");
  var row1_c0 = CreateElement(row1, "td");
  row1_c0.appendChild(document.createTextNode("Latitude:"));
  var row1_c1 = CreateElement(row1, "td");
  row1_c1.appendChild(document.createTextNode(point.lat()));

  var row2 = CreateElement(tbody, "tr");
  var row2_c0 = CreateElement(row2, "td");
  row2_c0.appendChild(document.createTextNode("Longitude:"));
  var row2_c1 = CreateElement(row2, "td");
  row2_c1.appendChild(document.createTextNode(point.lng()));

  var row3 = CreateElement(tbody, "tr");
  var row3_c0 = CreateElement(row3, "td");
  row3_c0.appendChild(document.createTextNode("Zoom:"));
  var row3_c1 = CreateElement(row3, "td");
  row3_c1.appendChild(document.createTextNode(map.getZoom()));

  var btn_div_elem = CreateElement(div_elem, "div");
  btn_div_elem.align = "right";
  btn_div_elem.style.borderTop = "1px solid gray";
  btn_div_elem.style.padding = "4px 0px";
  btn_form_elem = CreateElement(btn_div_elem, "form");
  var cancel_btn = CreateInputElement(btn_form_elem, "button");
  cancel_btn.value = "Cancel";
  var ok_btn = CreateInputElement(btn_form_elem, "button");
  ok_btn.value = "OK";

  var marker = new GMarker(point, {draggable:true});
  // TODO: support dragging the marker someday
  // var marker = new GMarker(point, { draggable: true });
  // marker.enableDragging();
  
  GEvent.bindDom(label_elem, "keypress", this, function(e) {
    if (e.keyCode == 13)
    {
        if (label_elem.value) {
          placemark_manager.AddPlacemark({
            txt: label_elem.value,
            lat: point.lat(),
            lng: point.lng(),
            zoom: map.getZoom()
          }, true);
          map.getInfoWindow().hide();
          map.removeOverlay(marker);
          placemark_manager.Save();
        } else {
          alert("Label is required");
        }
        cancelEvent(e);
    }
  });

  GEvent.bindDom(ok_btn, "click", this, function(e) {
    if (label_elem.value) {
      placemark_manager.AddPlacemark({
        txt: label_elem.value,
        lat: point.lat(),
        lng: point.lng(),
        zoom: map.getZoom()
      }, true);
      map.getInfoWindow().hide();
      map.removeOverlay(marker);
      placemark_manager.Save();
    } else {
      alert("Label is required");
    }
    cancelEvent(e);
    return false;
  });
  GEvent.bindDom(cancel_btn, "click", this, function(e) {
    map.getInfoWindow().hide();
    map.removeOverlay(marker);
    cancelEvent(e);
    return false;
  });
  
  GEvent.addListener(marker, "dragstart", function() {
    map.getInfoWindow().hide();
  });
  GEvent.addListener(marker, "dragend", function() {
      var point = marker.getPoint();
      var div_elem = document.createElement("div");
      div_elem.style.padding = "0px 10px 0px 10px";
      var table_elem = CreateElement(div_elem, "table");
      var tbody = CreateElement(table_elem, "tbody");
      var row0 = CreateElement(tbody, "tr");
      var row0_c0 = CreateElement(row0, "td");
      row0_c0.appendChild(document.createTextNode("Label:"));
      var row0_c1 = CreateElement(row0, "td");
      var form_elem = CreateElement(row0_c1, "form");
      var label_elem = CreateInputElement(form_elem, "text");
      label_elem.style.width = "200px";

      var row1 = CreateElement(tbody, "tr");
      var row1_c0 = CreateElement(row1, "td");
      row1_c0.appendChild(document.createTextNode("Latitude:"));
      var row1_c1 = CreateElement(row1, "td");
      row1_c1.appendChild(document.createTextNode(point.lat()));

      var row2 = CreateElement(tbody, "tr");
      var row2_c0 = CreateElement(row2, "td");
      row2_c0.appendChild(document.createTextNode("Longitude:"));
      var row2_c1 = CreateElement(row2, "td");
      row2_c1.appendChild(document.createTextNode(point.lng()));

      var row3 = CreateElement(tbody, "tr");
      var row3_c0 = CreateElement(row3, "td");
      row3_c0.appendChild(document.createTextNode("Zoom:"));
      var row3_c1 = CreateElement(row3, "td");
      row3_c1.appendChild(document.createTextNode(map.getZoom()));

      var btn_div_elem = CreateElement(div_elem, "div");
      btn_div_elem.align = "right";
      btn_div_elem.style.borderTop = "1px solid gray";
      btn_div_elem.style.padding = "4px 0px";
      btn_form_elem = CreateElement(btn_div_elem, "form");
      var cancel_btn = CreateInputElement(btn_form_elem, "button");
      cancel_btn.value = "Cancel";
      var ok_btn = CreateInputElement(btn_form_elem, "button");
      ok_btn.value = "OK";
      
      GEvent.bindDom(ok_btn, "click", this, function(e) {
        if (label_elem.value) {
          placemark_manager.AddPlacemark({
            txt: label_elem.value,
            lat: point.lat(),
            lng: point.lng(),
            zoom: map.getZoom()
          }, true);
          map.getInfoWindow().hide();
          map.removeOverlay(marker);
          placemark_manager.Save();
        } else {
          alert("Label is required");
        }
        cancelEvent(e);
        return false;
      });
      GEvent.bindDom(cancel_btn, "click", this, function(e) {
        map.getInfoWindow().hide();
        map.removeOverlay(marker);
        cancelEvent(e);
        return false;
      });
    
    marker.openInfoWindow(div_elem);
  });
  GEvent.addListener(marker, "click", function() {
    GEvent.bindDom(ok_btn, "click", this, function(e) {
        if (label_elem.value) {
          placemark_manager.AddPlacemark({
            txt: label_elem.value,
            lat: point.lat(),
            lng: point.lng(),
            zoom: map.getZoom()
          }, true);
          map.getInfoWindow().hide();
          map.removeOverlay(marker);
          placemark_manager.Save();
        } else {
          alert("Label is required");
        }
        cancelEvent(e);
        return false;
      });
      GEvent.bindDom(cancel_btn, "click", this, function(e) {
        map.getInfoWindow().hide();
        map.removeOverlay(marker);
        cancelEvent(e);
        return false;
      });
    
    marker.openInfoWindow(div_elem);
  });
  map.addOverlay(marker);
  marker.openInfoWindow(div_elem);
}

PlacemarkManager.prototype.AddPlacemark = function(cfg, visible) {
  // assemble the 'myplaces' entry
  //DebugMsg("Add 'My Places': " + cfg.txt);
  try
  {
  if (dijit.byId('myplaces_frame'))
  {
      dijit.byId('myplaces_frame').open=false;
      dijit.byId('myplaces_frame').toggle();
  }
  var row = CreateElement(this.main_tbody, "tr");
  cfg.entry_elem = row;

  var td = CreateElement(row, "td");
  var input_elem = CreateInputElement(td, "checkbox", "layer_check");
  if (visible == true) {
    input_elem.checked = "checked";
  }

  td = CreateElement(row, "td");
  var a = CreateElement(td, "a");
  a.href = 'javascript:void(0)';
  
  var popup_body = document.createElement("div");
  var bold_label = CreateElement(popup_body, "b");
  bold_label.appendChild(document.createTextNode(cfg.txt));
  CreateElement(popup_body, "br");
  CreateElement(popup_body, "br");
  var delete_btn = CreateElement(popup_body, "a", "placemark_delete_btn");
  delete_btn.href = 'javascript:void(0)';
  delete_btn.appendChild(document.createTextNode("Delete"));
  GEvent.bindDom(delete_btn, 'click', this, function(e) {
    map.getInfoWindow().hide();
    map.removeOverlay(marker);
    placemark_manager.Delete(cfg);
    cancelEvent(e);
    return false;
  });
  var t2 = '<div><b>' + cfg.txt + '</b><br><br><a id="poop" href="javascript:void(0)">Delete</a> </div>';
  
  GEvent.bindDom(a, 'click', this, function(e) {
    if (geOn)
    {
        //alert(t);
        geePanTo(cfg.lat, cfg.lng, 17);
        input_elem.checked = "checked";
        var measurePlacemark = ge.createPlacemark('');
        measurePlacemark.setName('');
        ge.getFeatures().appendChild(measurePlacemark);
      
        // Create point
        var point = ge.createPoint('');
        point.setLatitude(cfg.lat);
        point.setLongitude(cfg.lng);
        measurePlacemark.setGeometry(point);
        measurePlacemark.setDescription(t2);
    }
    else
    {
        map.setCenter(new GLatLng(cfg.lat, cfg.lng), 17);
        /* Smooth panning seem to not work very well
         * map.setZoom(cfg.zoom);
         * map.panTo(new GLatLng(cfg.lat, cfg.lng)); */
         input_elem.checked = "checked";
         marker.show();
    }
    cancelEvent(e);
    return false;
  });
  a.appendChild(document.createTextNode(cfg.txt));




  if (geOn)
  {
//        try
//        {
//            ge.getFeatures().removeChild(measurePlacemark); 
//        }
//        catch (ex)
//        {
//        }
        if (visible)
        {
            var measurePlacemark = ge.createPlacemark('');
            measurePlacemark.setName('');
            ge.getFeatures().appendChild(measurePlacemark);
          
            // Create point
            var point = ge.createPoint('');
            point.setLatitude(cfg.lat);
            point.setLongitude(cfg.lng);
            measurePlacemark.setGeometry(point);
            measurePlacemark.setDescription(t2);
        }
  }
  else
  {
      // build the pushpin
      var marker = new GMarker(new GLatLng(cfg.lat, cfg.lng));
      GEvent.addListener(marker, "click", function() {
        marker.openInfoWindow(popup_body);
      });
      map.addOverlay(marker);
      if (!visible)
        marker.hide();
    }
  }
  catch(ex)
  {
    alert('232' + ex);
  }

  GEvent.bindDom(input_elem, "click", this, function(e) {
    /* invert state of checked because we get the signal
     * before the form element does */
        if (geOn)
        {
            if (input_elem.checked)
            {
                var measurePlacemark = ge.createPlacemark('');
                measurePlacemark.setName('');
                ge.getFeatures().appendChild(measurePlacemark);
              
                // Create point
                var point = ge.createPoint('');
                point.setLatitude(cfg.lat);
                point.setLongitude(cfg.lng);
                measurePlacemark.setGeometry(point);
                measurePlacemark.setDescription(t2);
            }
            else
            {
            
            }
        }
        else
        {
            if (!input_elem.checked) {
                marker.hide();
            } else {
                marker.show();
            }
        }
  });

  

  this.placemark_defs.push(cfg);

}

/******************************************************************************
 * SidePanel class
 ******************************************************************************/
function SidePanel(parent) {
  this.main_div = CreateElement(parent, "div");
}

SidePanel.prototype.AddPane = function(text) {
  return new Frame(this.main_div, text);
}

/******************************************************************************
 * Frame class
 ******************************************************************************/
function Frame(parent, text) {
  this.main_div = CreateElement(parent, "div", "sidepanel_pane");
  this.main_div.style.visibility = 'hidden';
  this.main_div.style.padding = "0px 4px 4px 4px";

  this.caption_div = CreateElement(this.main_div, "div", "frame_caption");
  var caption_txt = document.createTextNode(text);
  this.caption_div.appendChild(caption_txt);

  this.body_div = CreateElement(this.main_div, "div", "frame_body");
  this.footer_div = CreateElement(this.main_div, "div", "frame_footer");
}

Frame.prototype.GetCaptionDiv = function() {
  return this.caption_div;
}

Frame.prototype.GetBodyDiv = function() {
  return this.body_div;
}

Frame.prototype.GetFooterDiv = function() {
  return this.footer_div;
}

Frame.prototype.Show = function() {
  this.main_div.style.visibility = 'visible';
}

Frame.prototype.Hide = function() {
  this.main_div.style.visibility = 'hidden';
}

//Frame.prototype.AddCloseButton = function(obj, close_func) {
//  this.close_btn = CreateElement(this.caption_div, "img");
//  this.close_btn.setAttribute("src", "images/close.gif");
//  this.close_btn.setAttribute("alt", "Close");
//  this.close_btn.style.position = "absolute";
//  this.close_btn.style.top = "0px";
//  this.close_btn.style.right = "0px";
//  this.close_btn.style.cursor = 'auto';

//  if (close_func) {
//    GEvent.bindDom(this.close_btn, 'click', obj, close_func);
//  }
//  GEvent.bindDom(this.close_btn, 'click', this, this.Hide);
//}


/******************************************************************************
 * Tab class
 ******************************************************************************/
function Tab(parent) {
  var main_table = CreateElement(parent, "table");
  var body = CreateElement(main_table, "tbody");
  var row1 = CreateElement(body, "tr");
  var td = CreateElement(row1, "td");
  var div = CreateElement(td, "div", "tabLabels");
  var tab_table = CreateElement(div, "table");
  var tab_tbody = CreateElement(tab_table, "tbody");
  this.tab_row = CreateElement(tab_tbody, "tr");

  var row2 = CreateElement(body, "tr");
  var pane_data = CreateElement(row2, "td");
  this.pane_div = CreateElement(pane_data, "div");

  this.tabs = [];
  this.panes = [];

  this.active = null;
}

Tab.prototype.AddTab = function(label) {
  var td = CreateElement(this.tab_row, "td");
  var tab_div = CreateElement(td, "div");
  this.tabs[label] = tab_div;
  var a = CreateElement(tab_div, "a");
  a.href = 'javascript:void(0)';
  GEvent.bindDom(a, 'click', this, function(e) {
    this.SetActive(label);
    cancelEvent(e);
    return false;
  });
  a.appendChild(document.createTextNode(label));

  var pane_div = CreateElement(this.pane_div, "div", "tabPane");
  this.panes[label] = pane_div;

  if (!this.active) {
    this.active = label;
    tab_div.className = 'selectedTab';
  } else {
    tab_div.className = 'unselectedTab';
    pane_div.style.display = 'none';
  }

  return pane_div;
}

Tab.prototype.SetActive = function(label) {
  if (this.active != label) {
    this.tabs[this.active].className = 'unselectedTab';
    this.panes[this.active].style.display = 'none';
    this.active = label;
    this.tabs[this.active].className = 'selectedTab';
    this.panes[this.active].style.display = '';
    this.active = label;
  }
}

/******************************************************************************
 * Dialog class
 ******************************************************************************/

function Dialog(parent, style_id, txt, width, height) {
  this.main_div = CreateElement(parent, "div", style_id);
  this.main_div.style.visibility = "hidden";

  // dialog caption bar
  this.caption = CreateElement(this.main_div, "div", "frame_caption");
  this.caption.style.cursor = "move";
  var caption_txt = document.createTextNode(txt);
  this.caption.appendChild(caption_txt);

  this.close_btn = CreateElement(this.caption, "img");
  GEvent.bindDom(this.close_btn, 'click', this, this.Hide);
  this.close_btn.setAttribute("src", "images/close.gif");
  this.close_btn.setAttribute("alt", "Close");
  this.close_btn.style.position = "absolute";
  this.close_btn.style.top = "0px";
  this.close_btn.style.right = "0px";
  this.close_btn.style.cursor = 'auto';

  // dialog body
  this.body_div = CreateElement(this.main_div, "div", "frame_body");
  if (width) {
    this.body_div.style.width = width;
    this.body_div.style.height = height;
  }
  this.body_div.style.cursor = 'auto';
  GEvent.bindDom(this.body_div, "mousedown", this, function(e) {
    cancelEvent(e);
  });

  // dialog footer - used for controls
  this.footer_div = CreateElement(this.main_div, "div", "frame_footer");

  // use maps API to make dialog draggable
  this.drag_obj = new GDraggableObject(this.main_div, {container:parent});
}

Dialog.prototype.GetBodyDiv = function() {
  return this.body_div;
}

Dialog.prototype.GetFooterDiv = function() {
  return this.footer_div;
}

Dialog.prototype.Show = function() {
  this.main_div.style.visibility = 'visible';
}

Dialog.prototype.Hide = function() {
  this.main_div.style.visibility = 'hidden';
}

Dialog.prototype.AppendText = function(txt) {
  this.body_div.appendChild(document.createTextNode(txt));
  CreateElement(this.body_div, "br");
  var h = this.body_div.scrollHeight;
  // adjust scroll to show this new content
  this.body_div.scrollTop = this.body_div.scrollHeight;

}

Dialog.prototype.AppendSearchResults = function(results) {
  var results_div = CreateElement(this.body_div, "div", "search_results");
  for (var p = 0; p < results.length; p++) {
    var img_elem = CreateElement(results_div, "img");
    var letter = String.fromCharCode("A".charCodeAt(0) + p);
    img_elem.setAttribute("src", FUSION_PATH + "marker" + letter + ".png");
    results_div.appendChild(document.createTextNode(results[p].snippet));
    CreateElement(results_div, "br");
  }
}

/******************************************************************************
 * Utility functions
 ******************************************************************************/

function cancelEvent(e) {
  if (window.event) {
    window.event.cancelBubble = true;
    window.event.returnValue = false;
  } else {
    e.preventDefault();
    e.stopPropagation();
  }
}

// determines what browser is being used
// typical types are: "Firefox" and "MSIE"
function IsBrowser(type) {
  return navigator.userAgent.match(type);
}


function CreateElement(parent, type, /* optional */ id) {
  var elem = document.createElement(type);
  if (id)
    elem.setAttribute("id", id);
  parent.appendChild(elem);
  return elem;
}

function CreateInputElement(parent, type, /* optional */ id) {
  var elem = document.createElement('input');
  elem.setAttribute('type', type);
  if (id)
    elem.setAttribute('id', id);
  parent.appendChild(elem);
  return elem;
}

function CreateRadioInputElement(parent, name, /* optional */ id) {
  var elem;
  try {
    elem = document.createElement('<input type="radio" name="' + name + '" />');
  } catch(err) {
    elem = document.createElement('input');
    elem.setAttribute('type', 'radio');
    elem.setAttribute('name', name);
  }
  if (id)
    elem.setAttribute('id', id);
  parent.appendChild(elem);
  return elem;
}

function CreateTextNode(parent, text) {
  parent.appendChild(document.createTextNode(text));
}

function FindChildById(elem, node_id) {
  for (var child = elem.firstChild; child != null; child = child.nextSibling) {
    if (child.id == node_id)
      return child;
  }
  return null;
}

function FindElement(id) {
  return (document.getElementById) ? document.getElementById(id)
                                   : document.all[id];
}

function RemoveAllChildren(node) {
  while (node.hasChildNodes())
    node.removeChild(node.firstChild);
}

/**
 * Gets the value of a parameter in the current page's URL
 *
 * @param {String} param  URL parameter to extract
 * @return {String || Boolean}  Extracted parameter.
 */
function GetPageURLParameter(param) {
  return GetURLParameter(window.location.href, param);
}


/**
 * Gets the value of a parameter from a URL
 *
 * @param {String} url  URL to extract from
 * @param {String} param parameter to extract
 * @return {String || Boolean}  Extracted parameter.
 */
function GetURLParameter(url, param) {
  // Look for a portion after the question mark:
  var halves = url.split('?');
  if (halves.length < 2) {
    return false;
  }
  // The second half contains the search parameters:
  var pairs = halves[1].split("&");
  for (var i = 0; i < pairs.length; i++) {
    var names = pairs[i].split("=");
    if (names[0] == param) {
      if (names.length > 1) {
        return names[1];
      } else {
        return true;  // A parameter with no = returns true
      }
    }
  }
  return false;
}

function GetCookieValue(name) {
  name = name + '=';
  var allcookies = document.cookie;
  var pos = allcookies.indexOf(name);
  if (pos != -1) {
    var start = pos + name.length;
    var end = allcookies.indexOf(';', start);
    if (end == -1)
      end = allcookies.length;
    return allcookies.substring(start, end);
  }
  return "";
}

function SetCookieValue(name, value) {
  document.cookie = name + '=' + value;
}
