
/* Merged Plone Javascript file
 * This file is dynamically assembled from separate parts.
 * Some of these parts have 3rd party licenses or copyright information attached
 * Such information is valid for that section,
 * not for the entire composite file
 * originating files are separated by ----- filename.js -----
 */

/* ----- formsubmithelpers.js ----- */
function inputSubmitOnClick(event) {
    if (!event) var event = window.event; // IE compatibility

    if (hasClassName(this, 'submitting')) {
        return confirm(window.form_resubmit_message);
    } else {
        addClassName(this, 'submitting');
    }
    return true;
}

function registerSubmitHandler() {
    var nodes = cssQuery('input[type=submit]');
    for (var i=0; i<nodes.length; i++) {
        var node = nodes[i];
        if (!node.onclick) {
            node.onclick = inputSubmitOnClick;
        }
    }
}
registerPloneFunction(registerSubmitHandler);


/* ----- dom.js ----- */
/* GENERAL DOM FUNCTIONS */

function getElement(objectId) {
    // checkW3C DOM, then MSIE 4, then NN 4.
    
    if(document.getElementById && document.getElementById(objectId)) {
  	return document.getElementById(objectId);
     }
     else if (document.all && document.all(objectId)) {  
  	return document.all(objectId);
     } else {
  	return false;
     }
}

// Precondition: 'Element' is the reference to an element whose class name you
// want to change.
function setClassAttribute(element, value) {
    element.setAttribute('class',value);
    if (element.className) element.setAttribute('className',value); 
}

function getStyleObject(objectId) {
  // checkW3C DOM, then MSIE 4, then NN 4.
  //
  if(document.getElementById && document.getElementById(objectId)) {
	return document.getElementById(objectId).style;
   }
   else if (document.all && document.all(objectId)) {  
	return document.all(objectId).style;
   } 
   else if (document.layers && document.layers[objectId]) { 
	return document.layers[objectId];
   } else {
	return false;
   }
}


function changeDiv(the_div,the_change)
{
  var the_style = getStyleObject(the_div);
  if (the_style != false)
  {
     the_style.display = the_change
  }
}

/*
function changeElementText(div_tagname, inner_span_tagname, newTextString)
{
   var newSpan = document.createElement("span");
   newSpan.setAttribute("id",inner_span_tagname);
   var newText = document.createTextNode(newTextString);
   newSpan.appendChild(newText);

   var titleElm = document.getElementById(div_tagname);
   var spanElm  = document.getElementById(inner_span_tagname);
   titleElm.replaceChild(newSpan,spanElm);
}
*/

function changeSpanText(span_tagname, newTextString)
{
    var span = getElement(span_tagname);
    
    if (span != false) {
        /* kill text node (and any other sub-tags */
        while (span.hasChildNodes()) {
            span.removeChild(span.childNodes[0]);
        }
        /* create new TextNode */
        var newText = document.createTextNode(newTextString);
        span.appendChild(newText);
    }
}

// TODO: Combine changeSpanTextToURL with changeSpanText as they are virtually
// identical.  Minor importance.  
// 11/17/06, BCW changed to take just a URL, not the html text for a link, 
// as it was causing IE problems as previously written
function changeSpanTextToURL(span_tagname, url)

{
    var span = getElement(span_tagname);
    
    if (span != false) {
        /* kill text node (and any other sub-tags */
        while (span.hasChildNodes()) {
            span.removeChild(span.childNodes[0]);
        }
        /* create new TextNode */
        var anchor = document.createElement("a");
        anchor.setAttribute('href', url);
        anchor.setAttribute('target', '_blank');
        anchor.appendChild(document.createTextNode(url));
        span.appendChild(anchor);
    }
}

function changeElementText2(elem_name, newTextString)
{
    var elem = getElement(elem_name);
		elem.innerHTML = newTextString;
}

// TODO: Consider another place for this or rename this file.
function getChildNodeString(element) {
  var str = "";
  var label = "";
  for(j=0; j<element.childNodes.length; j++) {
    label = element.tagName + ".childNodes[" + j + "]: ";
    str += label + element.childNodes[j].tagName + "\n";
    if (element.childNodes[j].hasChildNodes()) {
      str += "  ... child has '" + element.childNodes[j].childNodes.length + "'nodes\n";
      //str += "  " + getChildNodeString(element.childNodes[j]);
    }
  }
  return str;
}

/* checks to see if an image exists as correctly loaded */
function IsImageOk(img) {
    // During the onload event, IE correctly identifies any images that
    // weren't downloaded as not complete. Others should too. Gecko-based
    // browsers act like NS4 in that they report this incorrectly.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth and
    // naturalHeight. These give the true size of the image. If it failed
    // to load, either of these should be zero.
    if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
        return false;
    }

    // No other way of checking: assume it's ok.
    return true;
}


var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();



/* ----- getWindowSize.js ----- */
function getWindowHeight() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement &&
      ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
 // window.alert( 'Width = ' + myWidth +' and Height = ' + myHeight  );
  
  
  return myHeight;
}


function getWindowWidth() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement &&
      ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
 // window.alert( 'Width = ' + myWidth +' and Height = ' + myHeight  );
  
  
  return myWidth;
}






function resize(resizeMap){  
	map_style = getStyleObject("map");  
	districts_style = getStyleObject("districts");
	
	ht = getWindowHeight();
	
	ht = ht-100;
	
	
	w = getWindowWidth();
	w  = w - 420; //added room for cellspacing and padding was: w = w - 400;
  	//w  = w - 400; //added room for cellspacing and padding was: w = w - 400;
 // w = w - 3; //to account for right margin
  if (w < 400) w =400; //don't shrink smaller than 400
	
	//alert(ht);
	if (ht <350) ht = 350;
	
	strHeight = ht + "px";
  strWidth = w + "px";	
	if (resizeMap) map_style.height = strHeight; 
	//alert (BrowserDetect.OS);

  // COMMENTED BY Bryan Wilson 11/16/06: we don't need to resize and crop the district map vertically	  
  //districts_style.height = strHeight;

	firefox_mac_1_5 = BrowserDetect.browser =='Firefox' && BrowserDetect.OS == 'Mac' && 	BrowserDetect.version == '1.5';
	if (  !(firefox_mac_1_5)  ) { // do this unless firefox 1.5 on mac.
  	districts_style.width = strWidth;
  map_style.width = strWidth;
  }
  //alert("district height: " + districts_style.height);
  //alert("district width: " + districts_style.width);
} 



/* ----- utilityBrowserHTTP.js ----- */
/*
UTILITY JAVASCRIPTS FOR HTTP, AJAX REQUESTS/RESPONSES, COOKIES, BROWSER CHECK, ETC. ... 

Author: Bryan Wilson (code by other authors factored to this new file)
Original Creation Date: 2006.08.03

*/

/*
   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));
}


/* ----- unFocus-EventManager.js ----- */
/**
 * unFocus.Utilities.EventManager, version 1.0b (beta) (2005/12/16)
 * Copyright: 2005, Kevin Newman (http://www.unfocus.com/Projects/)
 * License: http://creativecommons.org/licenses/LGPL/2.1/
**/
// Package: unFocus.Utilities
// make sure faux-namespace is available before adding to it
if (!window.unFocus) var unFocus = {};
if (!unFocus.Utilities) unFocus.Utilities = {};

/** Class: EventManager
 *	Provides the interface and functionality to a Subscriber/Subscriber Pattern.
 * 
 **/
/*
Constructor: EventManager
	The Constructor (Prototype) function.

Parameters:
	[type1 [, type2 [, etc.]]] - Optionally sets up an empty array for each named event.
*/
unFocus.Utilities.EventManager = function() {
	this._listeners = {};
	for (var i = 0; i < arguments.length; i++) {
		this._listeners[arguments[i]] = [];
	}
};

unFocus.Utilities.EventManager.prototype = {
	/*
	Method: addEventListener
		Adds an event listener to the specified type.

	Parameters:
		$name		- The event name.
		$listener	- The function to be called when the event fires.
	*/
	addEventListener: function($name, $listener) {
		// check that listener is not in list
		for (var i = 0; i < this._listeners[$name].length; i++)
			if (this._listeners[$name][i] == $listener) return;
		// add listener to appropriate list
		this._listeners[$name].push($listener);
	},
	/*
	Method: removeEventListener
		Removes an event listener.
	
	Parameters:
		$name		- The event name.
		$listener	- The function to be removed.
	*/
	removeEventListener: function($name, $listener) {
		// search for the listener method
		for (var i = 0; i < this._listeners[$name].length; i++) {
			if (this._listeners[$name][i] == $listener) {
				this._listeners.splice(i,1);
				return;
			}
		}
	},
	/* Method: notifyListeners
		Notifies the listeners of an event.
	
	Parameters:
		$name	- The name of event to fire.
		$data	- The object to pass to the subscribed method (the Event Object).
	*/
	notifyListeners: function($name, $data) {
		for (var i = 0; i < this._listeners[$name].length; i++)
			this._listeners[$name][i]($data);
	}
};


/* ----- unFocus-JSFixes.js ----- */
// fix Function.apply
if (!Function.apply) Function.prototype.apply = function(thisArg, argArray) {
	// Create a function reference to the calling object
	thisArg.____apply = this;
	// Build a string that will later execute the function 
	var fnApplyString = "thisArg.____apply(";
	
	// Check that the argArray are according to standards. Must be array...
	if (typeof(argArray) == "object" && typeof(argArray.length) != "undefined") {
		var quote, comma;
		for(i = 0; i < argArray.length; i++){
			// Add quotes only for string values
			quote = typeof(argArray[i]) == "string" ? "\"" : "";
			// add a comma as param-separator for all except the last param
			comma = (i+1) < argArray.length ? "," : "";
			// add the param to the string we are building
			fnApplyString += quote + argArray[i] + quote + comma;
		}
	} else if (typeof(argArray) != "undefined") {
		// argArray is not an array, but it is defined, so we notify that the 
		// argArray must be an array when specified (according to ECMAScript specs)
		throw TypeError;
	}
	
	fnApplyString += ")";
	// eval the expression, now using the right object, function and parameters
	var retVal = eval(fnApplyString);
	// clean up our expando property reference
	delete thisArg.____apply;
	// return the value that the function was to return
	return retVal;
};

// fix array methods - I believe I borrowed this from Dean Edwards's IE7 script - same license ;-)
if (![].push) Array.prototype.push = function() {
	for(var i=0; i<arguments.length; i++)
		this[this.length-1] = arguments[i];
	return this.length;
};


if (![].pop) Array.prototype.pop = function() {
	var $item = this[this.length-1];
	this.length--;
	return $item;
};

if (![].shift) Array.prototype.shift = function () {
	return this.splice(0, 1)[0];
};

if (![].splice) Array.prototype.splice = function (s, d) {
	var max = Math.max,
		min = Math.min,
		a = [], // The return value array
		e,  // element
		i = max(arguments.length - 2, 0),   // insert count
		k = 0,
		l = this.length,
		n,  // new length
		v,  // delta
		x;  // shift count

	s = s || 0;
	if (s < 0) {
		s += l;
	}
	s = max(min(s, l), 0);  // start point
	d = max(min(isNumber(d) ? d : l, l - s), 0);    // delete count
	v = i - d;
	n = l + v;
	while (k < d) {
		e = this[s + k];
		if (!isUndefined(e)) {
			a[k] = e;
		}
		k += 1;
	}
	x = l - s - d;
	if (v < 0) {
		k = s + i;
		while (x) {
			this[k] = this[k - v];
			k += 1;
			x -= 1;
		}
		this.length = n;
	} else if (v > 0) {
		k = 1;
		while (x) {
			this[n - k] = this[l - k];
			k += 1;
			x -= 1;
		}
	}
	for (k = 0; k < i; ++k) {
		this[s + k] = arguments[k + 2];
	}
	return a;
};

if (![].unshift) Array.prototype.unshift = function () {
	this.splice.apply(this,
		[0, 0].concat(Array.prototype.slice.apply(arguments)));
	return this.length;
};


/* ----- unFocus-History.js ----- */
/*
unFocus.History, version 1.9.3 (alpha) (2007/02/13)
Copyright: 2005-2007, Kevin Newman (http://www.unfocus.com/Projects/HistoryKeeper/)
License: http://creativecommons.org/licenses/LGPL/2.1/
*/
//if (typeof unFocus == "undefined") var unFocus = {};

/*
	Class: unFocus.History
		A singleton with subscriber interface (<unFocus.Utilities.EventManager>) 
		that keeps a history and provides deep links for Flash and AJAX apps
*/
unFocus.History = (function() {

// use a closure to avoid poluting the global scope, and to discourage reinstantiation (like a singleton)
function Keeper() {
	// bool: initialize - whether or not the class has been initialized
	var _this = this,
		// set the poll interval here.
		_pollInterval = 200, _intervalID,
		// get the initial Hash state
		_currentHash;

	/*
	method: _getHash
		A private method that gets the Hash from the location.hash property.
	 
	returns:
		a string containing the current hash from the url
	*/
	var _getHash = function() {
		return location.hash.substring(1);
	};
	// get initial hash
	_currentHash = _getHash();
	
	/*
	method: _setHash
		A private method that sets the Hash on the location string (the current url).
	*/
	var _setHash = function($newHash) {
		window.location.hash = $newHash;
	}
	
	/*
	method: _watchHash
		A private method that is called every n miliseconds (<_pollInterval>) to check if the hash has changed.
		This is the primary Hash change detection method for most browsers. It doesn't work to detect the hash
		change in IE 5.5+ or various other browsers. Workarounds like the iframe method are used for those 
		browsers (IE 5.0 will use an anchor creation hack).
	*/
	function _watchHash() {
		var $newHash = _getHash();
		if (_currentHash != $newHash) {
			_currentHash = $newHash;
			_this.notifyListeners("historyChange", $newHash);
		}
	}
	// set the interval
	if (setInterval) _intervalID = setInterval(_watchHash, _pollInterval);
	
	/* 
	Method: _createAnchor
		Various browsers may need an achor to be present in the dom for the hash to actually be set,
		so we add one every time a history entry is made. This has a side effect in many browsers, 
		where if the scroll position of the page is changed, in between history states, this causes
		most browsers to remember the position! It's a bonus.
	*/
	function _createAnchor($newHash) {
		if (!_checkAnchorExists($newHash)) {
			var $anchor = document.createElement("a");
			$anchor.setAttribute("name", $newHash);
			if (/MSIE/.test(navigator.userAgent) && !window.opera)
				$anchor = document.createElement('<a name="'+$newHash+'">'+$newHash+"</a>");
			with ($anchor.style) {
				position = "absolute";
				display = "block";
				top = getScrollY()+"px";
				left = getScrollX()+"px";
			}
			//$anchor.style.display = 'none';
			//$anchor.innerHTML = $newHash;
			document.body.insertBefore($anchor,document.body.firstChild);
			//document.body.appendChild($anchor);
		}
	}
	// simplified function contributed by Micah Goulart
	function _checkAnchorExists($name) {
		if (document.getElementsByName($name).length > 0)
			return true;
	}
	// Keeps IE 5.0 from scrolling to the top every time a new history is entered.
	// Also retains the scroll position in the history (doesn't seem to work on IE 5.5+).
	if (typeof self.pageYOffset == "number") {
		function getScrollY() {
			return self.pageYOffset;
		}
	} else if (document.documentElement && document.documentElement.scrollTop) {
		function getScrollY() {
			return document.documentElement.scrollTop;
		}
	} else if (document.body) {
		function getScrollY() {
			return document.body.scrollTop;
		}
	}
	// clone getScrollY to getScrollX
	eval(String(getScrollY).toString().replace(/Top/g,"Left").replace(/Y/g,"X"));
	
	/*
	method: getCurrentBookmark
		A public method to retrieve the current history string
	
	returns:
		The current History Hash
	*/
	_this.getCurrent = function() {
		return _currentHash;
	};
	
	/*
	method: addHistory
		A public method to add a new history, and set the deep link. This method should be given a string.
		It does no serialization.
	
	returns:
		Boolean - true if supported and set, false if not
	*/
	_this.addHistory = function($newHash) { // adds history and bookmark hash
		// on first call, make an anchor for the root history entry
		_createAnchor(_currentHash);
		// replace with slimmer versions...
		_this.addHistory = function($newHash) {
			if (_currentHash != $newHash) {
				_createAnchor($newHash);
				_currentHash = $newHash;
				_setHash($newHash);
				_this.notifyListeners("historyChange",$newHash);
			}
			return true;
		};
		// ...do first call
		return _this.addHistory($newHash);
	};

	/**
	 * These are the platform specific override methods. Since some platforms (IE 5.5+, Safari)
	 * require almost completely different techniques to create history entries, browser detection is
	 * used and the appropriate method is created. The bugs these fixes address are very tied to the
	 * specific implementations of these browsers, and not necessarily the underlying html engines.
	 * Sometimes, bugs related to history management can be tied even to a specific skin in browsers
	 * like Opera.
	 */
	// Safari 2.04 and less (and WebKit less than 420 - these hacks are not needed by the most recent nightlies)
	// :TODO: consider whether this aught to check for Safari or WebKit - is this a safar problem, or a does it
	// happen in other WebKit based software? OmniWeb (WebKit 420+) seems to work, though there's a sync issue.
	if (/WebKit\/\d+/.test(navigator.appVersion) && navigator.appVersion.match(/WebKit\/(\d+)/)[1] < 420) {
		// this will hold the old history states, since they can't be reliably taken from the location object
		var _unFocusHistoryLength = history.length,
			_historyStates = {}, _form,
			_recentlyAdded = false;
		
		// Setting the hash directly in Safari seems to cause odd content refresh behavior.
		// We'll use a form to submit to a #hash location instead. I'm assuming this works,
		// since I saw it done this way in SwfAddress (gotta give credit where credit it due ;-) ).
		function _createSafariSetHashForm() {
			_form = document.createElement("form");
			_form.id = "unFocusHistoryForm";
			_form.method = "get";
			document.body.insertBefore(_form,document.body.firstChild);
		}
		
		// override the old _setHash method to use the new form
		_setHash = function($newHash) {
			_historyStates[_unFocusHistoryLength] = $newHash;
			_form.action = "#" + _getHash();
			_form.submit();
		}
		
		// override the old _getHash method, since Safari doesn't update location.hash (fixed in nightlies)
		_getHash = function() {
			return _historyStates[_unFocusHistoryLength];
		};
		
		// set initial history entry
		_historyStates[_unFocusHistoryLength] = _currentHash;
		
		// provide alternative addHistory
		_this.addHistory = function($newHash) { // adds history and bookmark hash
			// on first call, make an anchor for the root history entry
			_createAnchor(_currentHash);
			// setup the form fix
			_createSafariSetHashForm();
			// replace with slimmer version...
			// :TODO: rethink this - it's adding an extra scope to the chain, which might
			// actually cost more at runtime than a simple if statement. Can this be done
			// without adding to the scope chain? The replaced scope holds no values. Does
			// it keep it's place in the scope chain?
			_this.addHistory = function($newHash) {
				if (_currentHash != $newHash) {
					_createAnchor($newHash);
					_currentHash = $newHash;
					_unFocusHistoryLength = history.length+1;
					_recentlyAdded = true;
					_setHash($newHash);
					_this.notifyListeners("historyChange",$newHash);
					_recentlyAdded = false;
				}
				return true;
			};
			// ...do first call
			return _this.addHistory($newHash);
		};
		function _watchHistoryLength() {
			if (!_recentlyAdded) {
				var _historyLength = history.length;
				if (_historyLength != _unFocusHistoryLength) {
					_unFocusHistoryLength = _historyLength;
					
					var $newHash = _getHash();
					if (_currentHash != $newHash) {
						_currentHash = $newHash;
						_this.notifyListeners("historyChange", $newHash);
					}
				}
			}
		};
		
		// since it doesn't work, might as well cancel the location.hash check
		clearInterval(_intervalID);
		// watch the history.length prop for changes instead
		_intervalID = setInterval(_watchHistoryLength, _pollInterval);
		
	// IE 5.5+ Windows
	} else if (typeof ActiveXObject != "undefined" && window.print && 
			   !window.opera && navigator.userAgent.match(/MSIE (\d\.\d)/)[1] >= 5.5) {
		/* iframe references */
		var _historyFrameObj, _historyFrameRef;
		
		/*
		method: _createHistoryFrame
			
			This is for IE only for now.
		*/
		function _createHistoryFrame() {
			var $historyFrameName = "unFocusHistoryFrame";
			_historyFrameObj = document.createElement("iframe");
			_historyFrameObj.setAttribute("name", $historyFrameName);
			_historyFrameObj.setAttribute("id", $historyFrameName);
			// :NOTE: _Very_ experimental
			_historyFrameObj.setAttribute("src", 'javascript:;');
			_historyFrameObj.style.position = "absolute";
			_historyFrameObj.style.top = "-900px";
			document.body.insertBefore(_historyFrameObj,document.body.firstChild);
			// get reference to the frame from frames array (needed for document.open)
			// :NOTE: there might be an issue with this according to quirksmode.org
			// http://www.quirksmode.org/js/iframe.html
			_historyFrameRef = frames[$historyFrameName];
			
			// add base history entry
			_createHistoryHTML(_currentHash, true);
		}
		
		/*
		method: _createHistoryHTML
			This is an alternative to <_setHistoryHTML> that is used by IE (and others if I can get it to work).
			This method will create the history page completely in memory, with no need to download a new file
			from the server.
		*/
		function _createHistoryHTML($newHash) {
			with (_historyFrameRef.document) {
				open("text/html");
				write("<html><head></head><body onl",
					'oad="parent.unFocus.History._updateFromHistory(\''+$newHash+'\');">',
					$newHash+"</body></html>");
				close();
			}
		}
		
		/*
		method: _updateFromHistory
			A private method that is meant to be called only from HistoryFrame.html.
			It is not meant to be used by an end user even though it is accessable as public.
		*/
		_this._updateFromHistory = function() {
			// hides the first call to the method, and sets up the real method for the rest of the calls
			_this._updateFromHistory = function($hash) {
				_currentHash = $hash;
				_this.notifyListeners("historyChange", $hash);
			};
		};
		//if (navigator.userAgent.match(/MSIE (\d\.\d)/)[1] < 5.5) {
			_this.addHistory = function($newHash) {
				// do initialization stuff on first call
				_createHistoryFrame();
				
				// replace this function with a slimmer one on first call
				_this.addHistory = function($newHash) { // adds history and bookmark hash
					if (_currentHash != $newHash) {
						// IE will create an entry if there is an achor on the page, but it
						// does not allow you to detect the state change, so we skip inserting an Anchor
						_currentHash = $newHash;
						// sets hash and notifies listeners
						_createHistoryHTML($newHash);
					}
					return true;
				};
				// call the first call
				return _this.addHistory($newHash);
			};
			// anonymouse method - subscribe to self to update the hash when the history is updated
			_this.addEventListener("historyChange", function($hash) { _setHash($hash) });
		//} else { /* IE 5.0 */ }
	
	}
}
Keeper.prototype = new unFocus.Utilities.EventManager("historyChange");

return new Keeper();

})();


//set intitial state variable
var stateVar = '';




/* ----- permalinks.js ----- */
/*
Title: Permalinks.js
This file contains functions relating to browsing to and creating permalinks
to business member profiles ... 

Author: Bryan Wilson
Original Creation Date: 2007.04.19

Modifications to make use of unFocus.History:
unFocus.History (LGPL JS Library) allows us to record hashes in the
browser history and use forward/back buttons, and listen for
when location.hash is changed directly via browser location bar

TO DO:  
? when changed via location bar or bookmark use: navigate to
profile or new state
? when changed via permalink building, don't navigate, just record

unFocus.History object will call a listener event function whenever
location.hash changes.  this function needs to understand whether
we are setting or using a permalink
in my previous test, I was using location.watch("hash")...
and unwatched right before setting permalink then turned .watch()
back on after it was set

I can do something similar now, maybe 

*/

historyListener = function(historyHash) {
  // update the stateVar
  stateVar = historyHash;

  // now build new page view from new hash
  //buildPageFromPermalink();
  //by commenting this out, fixing double-load problem but probably
  //making it so that bookmarks won't work while already on directory
};


/* builds page view from permalink 
   TO DO: see if we can re-use more elegant code from
   unFocus-History.js for parsing hashes */
function buildPageFromPermalink() {
  permalink = parsePermalink();

  if (permalink) {
      //set to display to show the profile associated with this permalink
      displayProfile(permalink);
  } else {
    //default Directory starting display mode
    //displayDistricts();
  }

  //unFocus.History.addEventListener('historyChange', historyListener);
}

/*
reads id passed via the the hash at the end of the page URL
*/
function parsePermalink() {
  permalink = document.location.hash.split("#")[1];
  if (!permalink) return false;
  else return permalink;
}

// removes any business or other id permalinks from browser bar URL
function clearPermalinks() {
  //unFocus.History.removeEventListener
  document.location.hash = "#";
}

// add permalink to browser bar URL, storing a passed id
function createPermalink (id) {
  
  if (BrowserDetect.browser == 'Safari') { 
    document.location.hash = id ;
  } else { document.location.hash = '#' + id; }

  
}

// subscribe to unFocus.History to start listener to hash changes!
unFocus.History.addEventListener('historyChange', historyListener);


/* ----- directoryCategories.js ----- */
/*
JAVASCRIPT RELATED TO CATEGORY BROWSING ... 
manipulating page elements contained in template_categories.pt

Author: Bryan Wilson (code by other authors factored to this new file)
Original Creation Date: 2006.08.03

*/

function toggleCategorySection(forceOn) {
  var the_style = getStyleObject('categoryNavigationSection');
  if (the_style != false)  the_style.display = (the_style.display=='none' || forceOn) ? 'block' : 'none';
  arrowImg = getElement('catSectionToggleArrow');
  if (arrowImg != false) { 
    arrowImg.src = (arrowImg.src.indexOf('_down')==-1 || forceOn) ? 'categoryToggleArrow_down.gif' : 'categoryToggleArrow.gif' ; 
  }
}


function toggleCategoryHighlight(the_div,state) {
	/* switch highlight state of selected category */
  var the_div = getElement(the_div);
  var the_parentDiv = the_div.parentNode;
  setClassAttribute(the_parentDiv, (state=='on') ? 'mainCategoryHighlight' : 'mainCategory' );
}

function toggleDiv(the_div) {
    /*  TODO: (8/3/06-BCW) needs a more descriptive name and/or factoring  */
  

  toggleCategorySection(true);
  var the_style = getStyleObject(the_div);
  //hideAllCategories();      

  if (the_style != false)
  {
    if (the_style.display == 'none')
       {
       hideAllCategories();
       the_style.display = 'block';
       getElement('arrow_'+the_div).src='arrow_wh_open.gif';
       toggleCategoryHighlight(the_div,'on');
       }
    else
       {
       hideAllCategories();
       the_style.display = 'none';
       getElement('arrow_'+the_div).src='arrow_wh_closed.gif';
       toggleCategoryHighlight(the_div,'off');
  
       }
  }

}

function hideAllCategories()
{
   var x=document.getElementsByName("toggleNavigationElements");
   //won't find these elements by attribute name on a div in IE 
   //to do: create a new function to pass all calls to getElementsByName to the following lines for IE
   if (document.all) {
    x = []; //create a new blank array to imitate getElementsByName collection
    for (var i=0;i < document.all.length; i++) {
      if (document.all[i].name=='toggleNavigationElements') {
        x.push(document.all[i]);  
      }
    }
   }
   for (var i = 0; i < x.length; i++) {
      toggleCategoryHighlight(x[i].id,"off");
      var the_style = getStyleObject(x[i].id);
      the_style.display = "none";
      getElement('arrow_'+x[i].id).src='arrow_wh_closed.gif';
   }
}



/* this is modelled after setCategories, but is to display business in all categories */
function displayAllBusiness() {
    /* toggle highlight of category div */
    toggleCategoryHighlight('catTitle-AllBusinesses','on');

    /* set Categories then refresh markers */


    if (getElement('navfieldDistrictID').value == "") {
    	getElement('navfieldDistrictID').value = 'district_all';
    }
    
    getElement('searchGadget').value = "";  /* clear LiveSearch */
    getElement('navfieldSubCategoryIDs').value = 'category_all';
    setSelectedSubCategoryField('All Businesses');
    //BCW titlebar no longer used in BCCSkin :
    //getElement('titleBar').style.display = 'block';
    getElement('navfieldBatchPage').value = 1;
    getElement('navfieldSortOrder').value = 'business_asc';

	  //new category or district and category displayed in title bar  
	  //when you choose a new category, if the district is 'all districts', you don't show
      //the district:  when changing the district, you do display 'all districts'
    var districtTxt = getElement('navfieldDistrictTitle').value;
    var districtTxtLower = getElement('navfieldDistrictTitle').value.toLowerCase();
	  var boolDistrictSet = (districtTxtLower == 'all districts') ? false : true;
	  trueStr = 'Mapping all businesses in ' + districtTxt;
	  falseStr = 'Mapping all businesses';
	  str = boolDistrictSet ?  trueStr : falseStr;

    
  //  if (getElement('navfieldDistrictID').value !='district_all') {
  //  	str = 'All Businesses in ' + getElement('navfieldDistrictID').value;
  //  }
    
    setTitleBar(str);

    /* dynamic Try these ... header text for results list */
    
    str = boolDistrictSet ? 'Results for all ' + districtTxt + ' businesses' : 'Results for all businesses';
    setResultsHdr(str);

    showAJAXStatus();
    updateAJAXStatus("Retrieving list of businesses...");

    DisplayMarkers();

    getElement('navfieldCategoryTitle').value = str;

    /* remove subcategory title display from all category Divs  */

    clearSubcategories();


}


function setCategories(categoryIDs, categoryTitle, parentCatTitle) {
    /* TODO: 2006.8.3 BCW: THIS IS A HORRID GODLIKE FUNCTION!
    FACTOR THIS IF POSSIBLE */

    /* if we are setting one of these, then we should 
       remove highlight from 'All Businesses' */
    toggleCategoryHighlight('catTitle-AllBusinesses','off');
       
    /* set Categories then refresh markers */

    getElement('searchGadget').value = "";  /* clear LiveSearch */
    getElement('navfieldSubCategoryIDs').value = categoryIDs;
    setSelectedSubCategoryField(categoryTitle);
    //BCCSkin getElement('titleBar').style.display = 'block';
    getElement('navfieldBatchPage').value = 1;

// not sure about this line is it necessary?  depends on if we want categories to reset district sort.
    getElement('navfieldSortOrder').value = 'business_asc';
    
    
	  //new category or district and category displayed in title bar  
	  //when you choose a new category, if the district is 'all districts', you don't show
      //the district:  when changing the district, you do display 'all districts'
    var districtTxt = getElement('navfieldDistrictTitle').value;
    var districtTxtLower = getElement('navfieldDistrictTitle').value.toLowerCase();
	  var boolDistrictSet = (districtTxtLower == 'all districts') ? false : true;

	  trueStr = 'Mapping ' + districtTxt + ' businesses in category: ' + categoryTitle;
	  falseStr = 'Mapping all businesses in category: '+ categoryTitle;
	  str = boolDistrictSet ?  trueStr : falseStr;
    setTitleBar(str);

    /* dynamic Try these ... header text for results list */
    str = 'Results for category: ' + categoryTitle;
    setResultsHdr(str);

    showAJAXStatus();
    updateAJAXStatus("Retrieving list of businesses for " + categoryTitle + " category...");

    DisplayMarkers();

    //updateBreadcrumbCategory(categoryTitle); //behavior dropped
    getElement('navfieldCategoryTitle').value = categoryTitle;

    /* remove subcategory title display from all category Divs  */
    clearSubcategories();

	  /* set category title to display chosen subcategory */
    var span = getElement('selectedSubCat-'+parentCatTitle);
    var parentSpan = getElement('catTitle-'+parentCatTitle); 
    var titleTextLength = parentSpan.innerHTML.length+categoryTitle.length;
	  var maxLength = 66;
	  var spanMaxLength = maxLength - parentSpan.innerHTML.length;
    

    /* create new TextNode */      
    var nextTextString = (titleTextLength>maxLength) ? categoryTitle.substring(0,spanMaxLength-4)+"..." :  categoryTitle;
    var newText = document.createTextNode(" > "+nextTextString);
    span.appendChild(newText);
}


/* remove subcategory title display from all category Divs  */
function clearSubcategories() {
		var spanTags = document.getElementsByTagName("span"); 
    var span;
    for (var i=0; i<spanTags.length; i++){
    
        span = spanTags[i];
        if (span.id && span.id.indexOf("selectedSubCat")!=-1)  {

            /* clear any existing text nodes inside span */
            while (span.hasChildNodes()) {span.removeChild(span.firstChild); }     
        }
     }
}


/*
function changeCategoryTitle(newTitle)
{
   var newSpan = document.createElement("span");
   newSpan.setAttribute("id","categoryTitleText");
   var newText = document.createTextNode(newTitle);
   newSpan.appendChild(newText);

   var titleElm = document.getElementById('categoryTitle');
   var spanElm  = document.getElementById('categoryTitleText');
   var replaced = titleElm.replaceChild(newSpan,spanElm);
}
*/


/* ----- directoryDistricts.js ----- */
/*
JAVASCRIPT RELATED TO BOSTON MAIN STREET DISTRICTS ... 
manipulating page elements contained in template_categories.pt

Author: Bryan Wilson (code by other authors factored to this new file)
Original Creation Date: 2006.08.03

*/

/*  DISTRICT-RELATED FUNCTIONS */

function getDistrictName(district_id) {
    var aryDistrictNames = new Array();
    aryDistrictNames['allston'] = 'Allston Village';
    aryDistrictNames['beaconhill'] = 'Beacon Hill';
    aryDistrictNames['bowdoin'] = 'Bowdoin Geneva';
    aryDistrictNames['brighton'] = 'Brighton';
    aryDistrictNames['charlestown'] = 'Charlestown';
    aryDistrictNames['chinatown'] = 'Chinatown';
    aryDistrictNames['dudley'] = 'Dudley Square';
    aryDistrictNames['eastboston'] = 'East Boston';
    aryDistrictNames['egleston'] = 'Egleston Square';
    aryDistrictNames['fieldscorner'] = 'Fields Corner';
    aryDistrictNames['fourcorners'] = 'Four Corners';
    aryDistrictNames['grovehall'] = 'Grove Hall';
    aryDistrictNames['hydejackson'] = 'Hyde/Jackson Square';
    aryDistrictNames['hydepark'] = 'Hyde Park';
    aryDistrictNames['jpcentresouth'] = 'Jamaica Plain Centre/South';
    aryDistrictNames['missionhill'] = 'Mission Hill';
    aryDistrictNames['roslindale'] = 'Roslindale Village';
    aryDistrictNames['stmarks'] = 'St. Mark\'s';
    aryDistrictNames['uphamscorner'] = 'Uphams Corner';
    aryDistrictNames['washingtongateway'] = 'Washington Gateway';
    aryDistrictNames['westroxbury'] = 'West Roxbury';
    
    return aryDistrictNames[district_id];
}

function setDistrict(districtID, districtTitle) {
    /* set District then refresh markers */
    
    
		getElement('searchGadget').value =""; 
    
    getElement('navfieldDistrictID').value = districtID;
    getElement('navfieldDistrictTitle').value = districtTitle;    
    //getStyleObject('titleBar').display = 'block';
    getElement('navfieldBatchPage').value = 1;
    //the following line is optional and depends on business case.
    getElement('navfieldSortOrder').value = 'business_asc';

    businesscategories = getElement('navfieldSubCategoryIDs').value;
    var currentCategory = getElement('navfieldCategoryTitle').value;
    currentCategory = (currentCategory.indexOf('all categories')!=-1) ? 'Mapping all businesses' : currentCategory;
    
    //when you choose a new category, if the district is 'all districts', you don't show
    //the district:  when changing the district, you do display 'all districts'  
    if (businesscategories == "category_all") {
      setTitleBar('Mapping all businesses in ' + districtTitle);
    } else {
      setTitleBar( ( (businesscategories!='') ? 'Mapping '+ ( (districtTitle == 'All Districts')? 'all' : districtTitle ) + ' businesses in category: '+currentCategory : 'Mapping all businesses'+' in '+districtTitle  ));
    }
    //sifr kill: commented out 09/21/06 by ATokar
    //sIFR.replaceElement("#titleBarText", named({sFlashSrc: "sifr-MyriadBold.swf", sColor: "#ffffff", sCase: "upper", sBgColor: "#1C323C" }));

    

    showAJAXStatus(); 
    updateAJAXStatus("Retrieving list of businesses for " + ( (districtTitle.indexOf('Districts')==-1) ? districtTitle + " district..." : districtTitle) );
    
    DisplayMarkers(false); //but we don't want to run hideallcategories
    
    selDistrictElement = getElement('selDistrict');
    for (i = 0; i < selDistrictElement.options.length; i++) {
        if (selDistrictElement.options[i].id == districtID) {
            selDistrictElement.selectedIndex = i;
            break;
        }
    }
    //updateBreadcrumbDistrict(districtTitle); //behavior dropped
    
}

function buildDistrictProfile(district_id) {
     changeSpanText('titleBarText', getDistrictName(district_id));
     //com_stewartspeak_replacement(true,new Array("#titleBarText")); //change title image to display district name
     

     /* add district logo */
     var logoImg = getElement('districtLogo');
     if (logoImg) logoImg.setAttribute('src','districtLogo_'+district_id+'.gif');
     
}


/* ----- directoryGoogleMap.js ----- */
/*
JAVASCRIPT RELATED TO DISPLAY OF THE DIRECTORY GOOGLE MAP ... 
manipulating page elements contained in template_googlemap.pt

Author: Bryan Wilson (code by other authors factored to this new file)
Original Creation Date: 2006.08.03

*/

function DisplayMarkers(hideCats) {
    /* display business markers (pins) on Google Map */
    /* pull the parameters from various input fields */
    businesscategories = getElement('navfieldSubCategoryIDs').value;
    businessdistrict = getElement('navfieldDistrictID').value;
    sortorder = getElement('navfieldSortOrder').value;
    livesearch = getElement('searchGadget').value; /* grab what's in the search box */
    marker_num = 0;
    markers = new Array();
    batchpage = getElement('navfieldBatchPage').value;
    if (batchpage == "") {
        batchpage = 1;
    }

    /* workaround to make sure results list doesn't inch its way down the page */
    var results = getElement('results');
   // var ploneToolbar = getElement('ploneToolbar');
    var footer = getElement('footer');
    if (results != false) {
        results.style.display = 'none';
    }
   // ploneToolbar.style.display = 'none';
    footer.style.display = 'none';

    displayMap();
    if (hideCats!=false) {
        hideAllCategories(); 
    }

    map.clearOverlays();
    var request = GXmlHttp.create();


    ajax_URL = 'ajax.xml?search=' + livesearch + '&businesscategories=' + businesscategories + '&businessdistrict=' + businessdistrict +'&batchpage=' + batchpage +'&sortorder=' +sortorder;
    request.open('GET', ajax_URL, true);

    request.onreadystatechange = function() { // BEGIN 'ONREADYSTATE' FUNCTION
        if (request.readyState == 4) { // BEGIN 'IF' READYSTATE
            var xmlDoc = request.responseXML;
            var businesses = xmlDoc.documentElement.getElementsByTagName("business");
            if (businesses.length >0 ) {
                 var bounds = new GLatLngBounds( );
            }	
            
            for (var i = 0; i < businesses.length; i++) {            
                marker_level = businesses[i].getAttribute("marker_level");
                
                specialOffers = businesses[i].getAttribute("special_offers");
                
                
                if (specialOffers != "") {
                  tab_text  = '<div style ="width: 250px;" ><div class = "labelHeading" id="tab2_heading">Change Offer</div>'+ specialOffers + '</div>';
                } else {
                  description = businesses[i].getAttribute("description");
                  if (description == "") description ="No Information.";
                  tab_text  = '<div style ="width: 250px;" ><div class = "labelHeading" id="tab2_heading">Description</div>'+ description + '</div>';
                }
                
                strText=  tab_text;
               // alert(strText);

                
                createMapMarker(businesses[i].getAttribute("business_id"),
                  parseFloat(businesses[i].getAttribute("lng")), 
                  parseFloat(businesses[i].getAttribute("lat")), 
                  businesses[i].getAttribute("name"), 
                  "javascript:displayProfile('" + businesses[i].getAttribute("business_id") + "')", 
                  "",
                  businesses[i].getAttribute("description"), 
                  businesses[i].getAttribute("addr"), 
                  businesses[i].getAttribute("city"), 
                  businesses[i].getAttribute("state"), 
                  strText,
                  marker_level);


                
                businessPoint = new GLatLng(parseFloat(businesses[i].getAttribute("lat")), parseFloat(businesses[i].getAttribute("lng"))  );
                bounds.extend(businessPoint);   
  
                //var point = new GPoint(parseFloat(markers[i].getAttribute("lng")),
                //parseFloat(markers[i].getAttribute("lat")));
                //var marker = new GMarker(point);
                //map.addOverlay(marker);
            }
         //   if (businesses.length !=0 ) {

              //  var mapcenter = xmlDoc.documentElement.getElementsByTagName("mapcenter");
//alert (" DEFAULT_CENTER_LAT:"+ DEFAULT_CENTER_LAT+ "  DEFAULT_CENTER_LNG: "+ DEFAULT_CENTER_LNG) ;

               // map.centerAndZoom(new GPoint(parseFloat(mapcenter[0].getAttribute("lng")), parseFloat(mapcenter[0].getAttribute("lat")) ), 4);
               // map.setCenter    (new GLatLng(parseFloat(mapcenter[0].getAttribute("lng")), parseFloat(mapcenter[0].getAttribute("lat")) ), map.getBoundsZoomLevel(bounds));
              //  map.setCenter ( DEFAULT_CENTER_LAT, DEFAULT_CENTER_LNG, DEFAULT_MAIN_ZOOM_LEVEL);

            if (businesses.length !=0 ) {
                // center and zoom on the bounds.
                
//                TODO:  get right commands

                var clat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) /2;
                var clng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) /2;
                map.setCenter(new GLatLng(clat,clng), map.getBoundsZoomLevel(bounds));
            }
            var batch_info = xmlDoc.documentElement.getElementsByTagName("batch");
            var total_pages = batch_info[0].getAttribute("totalpages");
            var current_page = batch_info[0].getAttribute("currentpage");    	
            var totalresults_info = xmlDoc.documentElement.getElementsByTagName("totalresults");
            var total_results_count = totalresults_info[0].getAttribute("count");

            createPagingBlock(current_page, total_pages, businesses.length, total_results_count);
            createResultList('resultsTable',businesses);

            /* only hide again if there are results */        
            if (total_results_count > 0) {
                hideAJAXStatus();
            }        
            /* turn these back on AND only show again if there are results */
            if ( (results != false) && (total_results_count>0) ) {
                results.style.display = 'block';
            }
            //ploneToolbar.style.display = 'block';
            footer.style.display = 'block';        
        } // END 'IF' READYSTATE
    } // END 'ONREADYSTATE' FUNCTION
    request.send(null);
}	

function createMapMarker(id, longitude, latitude, name, url, picture, shortDescription, src_address, src_city, src_state, second_page, marker_level) {
    var point = new GPoint(longitude, latitude);
    
    var icon = new GIcon();
    imageURL = getMarkerImageURL(marker_level,'png');
    icon.image = imageURL; 
    icon.shadow ="http://www.google.co.uk/intl/en_uk/mapfiles/shadow50.png";
    icon.iconSize = new GSize(20, 34);
    icon.shadowSize = new GSize(37, 34);
    icon.iconAnchor = new GPoint(9, 34);
    icon.infoWindowAnchor = new GPoint(9, 2);
    icon.infoShadowAnchor = new GPoint(18, 25);
    var marker = new PdMarker((point), icon);
    // TODO: Set tooltip ... does not work atm in IE on Win 2x platform.
    //marker.setTooltip(name);    
	
    // Show this marker's index in the info window when it is clicked
		var defaultAddress = getCookie("defaultAddress");
  
    if (defaultAddress == null || defaultAddress =='') {
      var html1 = '<b><a href ="' + url + '">' + name + '</a></b><br>' + src_address + '<br>' + src_city + ", " + src_state  + '<br>' + '<div id ="directions" class="sansText" ><form id="formDirections" action="http://maps.google.com/maps"  method="get" target="_blank" style="margin-top:10px;"><label for="saddr"><span class="detailText">Get directions to here from:</span><br /></label><input type="text" name="saddr" id="directionsField" tabindex ="1" value="" size="30" /><br><input type="image" value="GO" align="absmiddle" src="go_small.gif" size="30"  onClick = "if(getElement(\'formDirections\').chkRememberFromAddr.checked ) setCookie(\'defaultAddress\', getElement(\'formDirections\').saddr.value,\'\', \'\', \'\', \'\');" /><input type ="hidden" name ="daddr" value ="' + src_address + ', ' + src_city +', ' + src_state + '"><input type="hidden" name="hl" value="en" /><input type="checkbox" name="chkRememberFromAddr" align="middle" checked="true" /><span class="instructionText">remember this address?</span><br>&nbsp;</form></div>';
    } else {
      var html1 = '<b><a href ="' + url + '">' + name + '</a></b><br />' + src_address + '<br>' + src_city + ", " + src_state  + '<br>' + '<div id ="directions" ><form id="formDirections" action="http://maps.google.com/maps"  method="get" target="_blank" style="margin-top:10px;"><label for="saddr"><span class="detailText">Get directions to here from:</span><br /></label><input type="text" name="saddr" id="directionsField" tabindex ="1" value="" size="30" /><br><input type="image" value="GO" align="absmiddle" src="go_small.gif" size="30"  onClick = "if(getElement(\'formDirections\').chkRememberFromAddr.checked ) setCookie(\'defaultAddress\', getElement(\'formDirections\').saddr.value,\'\', \'\', \'\', \'\');" /><input type ="hidden" name ="daddr" value ="' + src_address + ', ' + src_city +', ' + src_state + '"><input type="hidden" name="hl" value="en" /><input type="checkbox" name="chkRememberFromAddr" align="middle" checked="true" /><span class="instructionText">remember this address?</span><br>&nbsp;</form></div>';
    }
    var html2 = second_page;
    
        
    markers[marker_num] = marker;
    page1s[marker_num] = '<div style="white-space:nowrap;">' + html1 + '</div>';
    page2s[marker_num] =  html2;
    label1s[marker_num] = "info";
    label2s[marker_num] = "details";

    
    var infoTabs = [
  new GInfoWindowTab("info", page1s[marker_num] ),
  new GInfoWindowTab("details", page2s[marker_num] )
]; 
    
    var i = marker_num;     // store the marker_num with a function closure
    var html = make_tab(i,1); 



    GEvent.addListener(marker, "click", function() {
      // we need to find alter the html variable in real time.  
      // replace xxxxx with getAddress() text
      
      //because there is a /n coming thru on the other function.
      cookieAddress = getAddressForField();  
      
      if (cookieAddress == "") {
        cookieAddress = "String.fromCharCode(10)";
      } else {
      	cookieAddress = "'" + cookieAddress + "'";
      }
      	
      html = html.replace (/<input type="text" name="saddr" id="directionsField" tabindex ="1" value="(.*?)" size="30" \/>/, 
      '<input type="text" name="saddr" id="directionsField" tabindex ="1" value="" onFocus="getElement(\'formDirections\').saddr.value='+cookieAddress+'" size="30" />'); 
      marker_num = i;       // retrieve the marker_num
      
      markers[marker_num].openInfoWindowHtml(html);
      markers[marker_num].openInfoWindowTabsHtml(infoTabs);
    });
    marker_num++;
    imageURL = getMarkerHoverImageURL(marker_level);
  	marker.setHoverImage(imageURL);
  	marker.setName(id);
      
    map.addOverlay(marker);  
}

				

function recenterMap(business_id) {
    displayMap();
    //map.recenterOrPanToLatLng(new GPoint(lng, lat));
    var marker = map.getFirstMarker();
    while (marker != null)
    {
    	if (marker.getName() == business_id) {
    	    GEvent.trigger(marker, "click");
    	    break;
    	}
    	marker = map.getNextMarker();
    }
}

function getAddress() {

	if (getCookie("defaultAddress")==null || getCookie("defaultAddress")=='') 
		getElement('formDirections').saddr.value = String.fromCharCode(10)

	else
		getElement('formDirections').saddr.value = getCookie("defaultAddress");
	
}

function getAddressForField() {

	if (getCookie("defaultAddress")==null || getCookie("defaultAddress")=='') 
		return '';

	else
		return getCookie("defaultAddress");
	
}

/* INFO-WINDOW TAB-RELATED JAVASCRIPT */

   /* new from alex for 2 tabs */
      // Storage for the stuff thats going to go into the tabbed infowindow
      var markers = [];
      var page1s = [];
      var page2s = [];
      var label1s = [];
      var label2s = [];
      
      // When the tab updated triggers, it doesnt tell us which marker it is associated with
      // (info windows dont have a history of whether they came from a marker or from the map)
      // but we need to know which set of info to use to rebuild the infowindow with the other tab active.
      var marker_num = 0;

   
    
    
      // ==================================================
      // This function updates the tabs when we get a click
      // The function gets called several times for each click, with different information
      // that the API thinks that we might possibly be interested in.
      // For our current purposes we are only interested in the call where the first parameter is "page"
      
      // Note the unusual style of the function name that allows us to reference this function in the infoWindow.addContext() method
      update_tabs = function(a,b,c) {
        if (a == "page") {
        
          var html = make_tab(marker_num, parseFloat(b));
          
    cookieAddress = getAddressForField();  //because there is a /n coming thru on the other function.
    
    if (cookieAddress == "") cookieAddress = "String.fromCharCode(10)";
    else 
      cookieAddress = "'" + cookieAddress + "'";
      
    html = html.replace (/<input type="text" name="saddr" id="directionsField" tabindex ="1" value="(.*?)" size="30" \/>/, 
    '<input type="text" name="saddr" id="directionsField" tabindex ="1" value="" onFocus="getElement(\\\'formDirections\\\').saddr.value='+cookieAddress+'" size="30" />');


          markers[marker_num].openInfoWindowHtml(html);
        }
      }
      
      // ============
      dummy_function = function(a,b,c) {}
      
      

      // ==================================================
      // A function to construct the html for the "p"th tab of the "i"th marker
      // Assume p is either 1 or 2
      function make_tab(i,p) {
        if (p == 1) {
          var html = '<div page="1" label="'  + label1s[i] + '" class="active">' +page1s[i] +'</div>'
                    +'<div page="2" label="'  + label2s[i] + '"></div>';
        }
        else {
          var html = '<div page="1" label="'  + label1s[i] + '">' +page2s[i] +'</div>'
                    +'<div page="2" label="'  + label2s[i] + '" class="active"></div>';
        }
        return html;
      }
/* end new from alex for 2 tabs */

function getMarkerImageURL(marker_level,fileType) {
  switch(marker_level) {
    case '2':
      img_src = 'GMapPinBCC.' + fileType;
      break;
    case '1':
      img_src = 'GMapPinBMS.' + fileType;
      break;            
    case '0':
    default:
      img_src = 'GMapPinDefault.' + fileType;        
  }
  return img_src;
}

function getMarkerHoverImageURL(marker_level) {
  switch(marker_level) {
    case '2':
      img_src = 'GMapPinBCCHover.png';
      break;
    case '1':
      img_src = 'GMapPinBMSHover.png';
      break;            
    case '0':
    default:
      img_src = 'GMapPinDefaultHover.png';        
  }
  return img_src;
}


/* ----- directoryProfile.js ----- */
/*
JAVASCRIPT RELATED TO DISPLAY OF BUSINESS PROFILES ... 
manipulating page elements contained in template_profile.pt

Author: Bryan Wilson (code by other authors factored to this new file)
Original Creation Date: 2006.08.03


Additional comments by Alex Tokar 9-12-06
*/



/* populates/updates template_profile.pt  
 * based on business_id 
 * using an xml feed from profile.xml 
 */
function buildProfile(business_id) {



   //hide profile address block until we have a business to display
   if (getStyleObject('profileAddressBlock')) {
      getStyleObject('profileAddressBlock').display = 'none';  }       


    //given business_id get xml feed for a business 
    var request = GXmlHttp.create();
    request.open('GET', 'profile.xml?businessid=' + business_id, true);
    //changeCategoryTitle('Your current category: ' + businesscategoryTitle);

    request.onreadystatechange = function() {
    if (request.readyState == 4) {

     //if we get a proper response then we can go ahead and
     // build the permalink with the business_id as we know it's a good business
    createPermalink(business_id);
       
    	var xmlDoc = request.responseXML;
    	var businesses = xmlDoc.documentElement.getElementsByTagName("business");

    //handle case where no matching business is found
    if (businesses.length == 0) {
     changeSpanText('profileHeaderText', ''); 
     changeSpanText('directoryTitleText', 'Business Not Found'); 
     changeSpanText('profileDescriptionValue', 'We\'re sorry.  \
                     We were unable to find this business.  Try searching \
                     for the business using the Business Search box at the top right \
                     of the screen or by browsing the categories to the right. \
                     If you still can\'t find the business and you are \
                      certain they should be on our website , please use the \
                     Feedback button at the bottom of the page to let us know \
                     what went wrong. If this is a  \
                     business that should be on our site, please nominate the business \
                     for inclusion in the site.');     

      if (getStyleObject('profileDescription')) {
        getStyleObject('profileDescription').display = 'block';  }                 

      //show small googlemap only once we have a business to display
      if (getStyleObject('googlemapsmall')) {
        getStyleObject('googlemapsmall').visibility = 'hidden'; 
      }      

      //update the window title to show no business was found
      updateWindowTitle('Business Not Found');

     return true;
    }
    
    	for (var i = 0; i < businesses.length; i++) {
    	
        // update Profile elements for this business
        businessName = businesses[i].getAttribute("name")
        changeSpanText('directoryTitleText', 'Business Profile');
        //change profile header text to name of Business
        changeSpanText('profileHeaderTxt',businessName);

        //update the window title to include the business name
        updateWindowTitle(businessName);

        //show small googlemap only once we have a business to display
        if (getStyleObject('googlemapsmall')) {
          getStyleObject('googlemapsmall').visibility = 'visible'; 
        }

        // BCW commented 08/10/06 causing display/CSS problem and //
        // probably not using til past 1.0                       //        
        /*var anchor = getElement('districtProfileLink');
        anchor.setAttribute('href','javascript:displayDistrictProfile("'+ businesses[i].getAttribute("district_id") +'")'); */

        ////////////////////////////////////////////////
        // SHOW/HIDE  PROFILE ELEMENT LABEL AND       //
        // FILL IN PROFILE ELEMENTS BASED ON XML DATA  //
        ////////////////////////////////////////////////

        var description = businesses[i].getAttribute("description");
        var district = getDistrictName(businesses[i].getAttribute("district_id"));
        var addr = businesses[i].getAttribute("addr");
        var addr2 = businesses[i].getAttribute("addr2"); 
        var city = businesses[i].getAttribute("city");
        var state = ', ' + businesses[i].getAttribute("state");
        var postal_code =  businesses[i].getAttribute("postal_code");
        var phone =  businesses[i].getAttribute("phone");
        var hours =  businesses[i].getAttribute("hours");
        var website =  businesses[i].getAttribute("web_site");
        // comented BCW 11/17/06: changeSpanTextToURL no longer requires html code for a link, just a URL
        //var website_url = '<a href="'+website+'" target ="_blank" >'+website+'</a>';
        var special_offers =  businesses[i].getAttribute("special_offers");
        var payments_accepted =  businesses[i].getAttribute("payments_accepted");
        var last_modified =  businesses[i].getAttribute("last_modified");
        var logo_url =  businesses[i].getAttribute("logo_url");

        
        // Business Logo
        strDimension = "";
        if (logo_url != "") {
					var test_image = new Image();
					test_image.src = logo_url;
                        // find resized dimensions, if necessary, by passing max width, height
                        var newLogoDims = getResizedImageDims(test_image.src,146,110);        
                       strDimension = "width=\""+newLogoDims[0]+"\" height=\"" + newLogoDims[1] +"\"";  
	    /*			commmented by BCW 1/31/07
                       width = test_image.naturalWidth;
					height = test_image.naturalHeight;
					if (width > height) {
						strDimension = ' width="146"';
					} else {
						strDimension = ' height="110"';
					}
        */            
				}


        var logo_prefix = '<img id="businessLogoImage" ';
        var logo_src = "src=\"" + logo_url + "\" ";
        var logo_alt = "alt=\"" + businessName + "\" ";
        var logo_title = "title=\"" + businessName + "\" ";
	   var logo_dimension = strDimension;
        var logo_suffix = " />"
        var logo_tag = logo_prefix + logo_src + logo_alt + logo_title;
        logo_tag += logo_dimension + logo_suffix;
                
        //category list built below
        // TODO: TRAC ISSUE 74 -- should we add other metadata here?
        var meta_data = 'Last updated ' + last_modified;
        
        // following 2 will come from Nietech ?
        //var special_offers = 'DUMMY DATA - Special to Boston Community Card members: 15% off on for copies, laser prints, or computer time'; 
        //var payments_accepted = 'DUMMY DATA - Cash, Check, Visa, Mastercard, Discover, American Express';
        
        changeSpanText('profileDescriptionValue', description);            
        changeSpanText('profileDistrictValue', district);
        changeSpanText('profileStreetAddress',addr);
        changeSpanText('profileStreetAddress2',addr2);
        changeSpanText('profileCity',city);
        changeSpanText('profileState',state);
        changeSpanText('profilePostalcode',postal_code);
        changeSpanText('profilePhoneValue',phone);

        //display 2nd address line if there is data 
        if (getStyleObject('profileAddress2')) {
          getStyleObject('profileAddress2').display = (addr2!=null) ? 'block' : 'none';  }
        
        if (hours == "") {
          hours = "No Information";
        }
        changeSpanText('profileHoursValue',hours);
        if (website == "") {
          website = "";
          changeSpanText('profileWebsiteValue', website);
        } else {
          changeSpanTextToURL('profileWebsiteValue', website); //this line causing IE probs with profile display           
        }
        if (special_offers == "") {
          special_offers = "No Information";
        }
        changeSpanText('profileSpecialOffersValue', special_offers);
        if (payments_accepted == "") {
          payments_accepted = "No Information";
        }
        changeSpanText('profilePaymentsAcceptedValue', payments_accepted);
        changeSpanText('profileLastUpdated', meta_data);
            

        setTimeout(function () { changeElementText2('profileLogoValue', logo_tag) },500); //timeout for IE compat

/*
        logo_span = getStyleObject('profileLogoValue'); 
        logo_span.display = "none";
                
	    logo_div = getStyleObject('profileLogo'); 
        logo_div.display = "none";

        if (logo_url != "") {
					logo_div.display = "block";
					logo_span.display = "block";
			  } 
        */
                  
        // WHOLE ELEMENT SHOULD BE HIDDEN IF NO DATA
        if (getStyleObject('profileAddressBlock')) {
          getStyleObject('profileAddressBlock').display = 'block';  } 
        if (getStyleObject('directionsBlock')) {
          getStyleObject('directionsBlock').visibility = 'visible';  }           
        if (getStyleObject('profileLogo')) {
          getStyleObject('profileLogo').display = (logo_url!="") ? 'block' : 'none';  }
        if (getStyleObject('profileDescription')) {
          getStyleObject('profileDescription').display = (description!="") ? 'block' : 'none';  }                   
        if (getStyleObject('profileDistrict')) {
          getStyleObject('profileDistrict').display = (district!="") ? 'block' : 'none';  }
        if (getStyleObject('profilePhone')) {
          getStyleObject('profilePhone').display = (phone!="") ? 'block' : 'none';  }
        if (getStyleObject('profileHours')) {
          getStyleObject('profileHours').display = (hours!="") ? 'block' : 'none';  }
        if (getStyleObject('profileWebsite')) {
          getStyleObject('profileWebsite').display = (website!="") ? 'block' : 'none';  }
        if (getStyleObject('profilePaymentsAccepted')) {
          getStyleObject('profilePaymentsAccepted').display = (payments_accepted!="") ? 'block' : 'none';  }
        if (getStyleObject('profileSpecialOffers')) {
          getStyleObject('profileSpecialOffers').display = (special_offers!="") ? 'block' : 'none';  }            

    	    /////////////////////////////////
    	    // CREATE CATEGORIES HTML LIST //
    	    /////////////////////////////////
    	    
    	        // create the HTML for the categories and subcategories a business belongs to
    	    
    	        ///////////////////////////
    	        // GET CATEGORY XML DATA //
    	        ///////////////////////////
    	    
    	    var categories = xmlDoc.documentElement.getElementsByTagName("category");
         if (getStyleObject('profileCategories')) {
            getStyleObject('profileCategories').display = (categories.length>0) ? 'block' : 'none';  }
                        
    	       /////////////////////////////////////////////////////////////
    	       // IF NO CATEGORIES PRESENT, DON'T DISPLAY //
    	       /////////////////////////////////////////////////////////////
 		   	

    	       /////////////////////////////////////////////////
    	       // IF CATEGORIES ARE PRESENT, CREATE HTML LIST //
    	       /////////////////////////////////////////////////

            
    	    if (categories.length > 0) {
    	    
                ///////////////////
                // UPDATE HEADER //
                ///////////////////
    	    
    	       changeElementText2 ('profileCategoriesHeader', 'Listed in categories');

                ///////////////////
                // CATEGORY DATA //
                ///////////////////
                
    	       var profileCategoriesText = '<P class="bodyText">';

    	       for (var j = 0; j < categories.length; j++) {
    	       
    	             /////////////////////////////
    	             // GET CATEGORY ATTRIBUTES //
    	             /////////////////////////////

                   subcategoryID = categories[j].getAttribute("subcategoryID");      
                 subcategoryName = categories[j].getAttribute("subcategoryName");   
                      categoryID = categories[j].getAttribute("categoryID");
                    categoryName = categories[j].getAttribute("categoryName");
      siblingBusinessCategoryIDs = categories[j].getAttribute("siblingBusinessCategoryIDs");
          	          
    	             /////////////////////////////
    	             // CREATE JAVASCRIPT LINKS //
    	             /////////////////////////////

    	          subcategoryLink = "javascript:setCategories('" + siblingBusinessCategoryIDs + "','" + subcategoryName + "','" + categoryID + "');toggleCategoryHighlight('cat-" + categoryID + "','on')";

    	          categoryLink = "javascript:toggleDiv('cat-" + categoryID + "')";
    	          
    	             //////////////////////////////////
    	             // CREATE LINE OF CATEGORY INFO //
    	             //////////////////////////////////

    	          categoryLine = '<A HREF="' + categoryLink + '">' + categoryName + '</A> -> <A HREF="' + subcategoryLink + '">' + subcategoryName + '</A><BR>';
				
    	             /////////////////////////////
    	             // ADD LINE TO OUTPUT HTML //
    	             /////////////////////////////

				  profileCategoriesText += categoryLine;
    	       }

    	       profileCategoriesText += '</P>';

    	             /////////////////
    	             // UPDATE PAGE //
    	             /////////////////
           setTimeout(function () { changeElementText2 ('profileCategoriesValue', profileCategoriesText) }, 500);
    	      }
          
    	    //}

        /////////////////////////////
        // BUILD PROFILE EDIT LINK //
        ////////////////////////////

         buildEditProfileLink(business_id);

            

            // POPULATE HIDDEN ADDRESS FIELD TO USE BY COOKIE STORAGE //
            // FOR GOOGLEMAP DIRECTIONS LINK                         //
            var addressText =  businesses[i].getAttribute("addr") + ', ' + businesses[i].getAttribute("city") +', ' + businesses[i].getAttribute("state");
            changeElementText2('profileHiddenDaddrField', '<input type ="hidden" name ="daddr" value ="'+addressText+'">');
            var cookieAddress = getAddressForField();
            setTimeout(function () {
              changeElementText2('profileDirectionsField','<input type="text" id="directionsField" size="42" name="saddr" value="'  +  cookieAddress  +  '" tabindex ="1" />') }, 500);            

            tinymap.panTo(new GLatLng(parseFloat(businesses[i].getAttribute("lat")), parseFloat(businesses[i].getAttribute("lng"))), 4);
            var point = new GLatLng(businesses[i].getAttribute("lat"), businesses[i].getAttribute("lng"));


            var marker_level = businesses[i].getAttribute("marker_level");

            var icon = new GIcon();
            imageURL = getMarkerImageURL(marker_level,'png');
            icon.image = imageURL; 
            icon.shadow ="http://www.google.co.uk/intl/en_uk/mapfiles/shadow50.png";
            icon.iconSize = new GSize(20, 34);
            icon.shadowSize = new GSize(37, 34);
            icon.iconAnchor = new GPoint(9, 34);
            icon.infoWindowAnchor = new GPoint(9, 2);
            icon.infoShadowAnchor = new GPoint(18, 25);
            var marker = new PdMarker((point), icon);



            marker.setTooltip(businesses[i].getAttribute("name"));
						//imageURL = getMarkerHoverImageURL(marker_level);
					//	marker.setHoverImage(imageURL);
            GEvent.addListener(marker, "click", function() {                
              marker.openInfoWindowHtml("<div style='white-space:normal;min-width:250px;max-width:300px;width:expression(\'300px\')'><b>" + businessName + "</b><br />" + addr + "</div>");
              //marker.setDetailWinHTML("<div style='white-space:nowrap;'>" + businesses[i].getAttribute("name") + "</div>");
            });
            tinymap.clearOverlays();
            tinymap.addOverlay(marker);
            setTimeout(function () { GEvent.trigger(marker, "click") } ,500);            
              
        	
    	   //createMapMarker(parseFloat(businesses[i].getAttribute("lng")), parseFloat(businesses[i].getAttribute("lat")), businesses[i].getAttribute("title"), businesses[i].getAttribute("url"), "", businesses[i].getAttribute("description"), businesses[i].getAttribute("addr"), businesses[i].getAttribute("city"), businesses[i].getAttribute("state"));
      	//var point = new GPoint(parseFloat(markers[i].getAttribute("lng")),
    	//					   parseFloat(markers[i].getAttribute("lat")));
      	//var marker = new GMarker(point);
      	//map.addOverlay(marker);
    	}

        //var mapcenter = xmlDoc.documentElement.getElementsByTagName("mapcenter");
        //map.centerAndZoom(new GPoint(parseFloat(mapcenter[0].getAttribute("lng")), parseFloat(mapcenter[0].getAttribute("lat")) ), 4);

        //createResultList('resultsTable',businesses);
        //hideAJAXStatus();
        //var resultSection = getElement('resultSection');
        //if (resultSection != false)
        //  resultSection.style.display = 'block';
      }
    }
    request.send(null);

}

function buildEditProfileLink(business_id) {

    // apply the correct href attribute link for "Edit this Profile / Is This Your Business" link 
    // send to edit form if they have corect permissions or send to Is This Your Business page otherwise

    var editProfileLink=getElement('editProfileLink');  //find anchor tag by id
    var editProfile=getElement('editProfile');  //find div tag by id
    
    styleEditProfile = getStyleObject(editProfile);
    styleEditProfile.display ="none";
    
    
    //var thisIsMyBusinessLink=getElement('thisIsMyBusinessLink');
    
   // alert(getElement('navfieldCurrentUser').value);
   // alert(business_id);
   // alert(getElement('navfieldCurrentUser').value == business_id);
    
   


   if (getElement('navfieldCurrentUser').value == business_id || getElement('navfieldManagerRole').value == 1) {    
   
   // if (getElement('navfieldCurrentUser').value == business_id ) {    
    
      editProfileLink.setAttribute("href", "loadProfileEdit?businessid="+business_id);
      setClassAttribute(editProfileLink, 'canEditProfile');
      setClassAttribute(editProfile, 'canEditProfile');
      changeSpanText('editProfileLinkValue', 'Edit this Business Profile');
      styleEditProfile.display ="block";

    
    } else if ( getElement('navfieldCurrentUser').value =="") {  //anon user not logged in
    
      editProfileLink.setAttribute("href", "../join-now/enroll-your-business/assertMyBusiness");
      setClassAttribute(editProfileLink, 'cannotEditProfile');
      setClassAttribute(editProfile, 'cannotEditProfile');
      changeSpanText('editProfileLinkValue', 'Is this your business?');
      styleEditProfile.display ="block";

    

    } else {
    
    
      //leave dead for now  
      //this message is for wasabisan because he loves this kind of structure
      
     
      editProfileLink.setAttribute("href", "../businesses/assertMyBusiness");
      setClassAttribute(editProfileLink, 'cannotEditProfile');
      setClassAttribute(editProfile, 'cannotEditProfile');
      changeSpanText('editProfileLinkValue', '');

      //but note!  not displaying at this time...      
    
    }
    

    //todo: set class
    //    if (editProfileLink) editProfileLink.setAttribute("href", "portal_memberdata/bms" + business_id +"/base_edit");
    //if (editProfileLink) editProfileLink.setAttribute("href", "loadProfileEdit?businessid="+business_id);
    //else if (thisIsMyBusinessLink) thisIsMyBusinessLink.setAttribute("href", "../businesses/assertMyBusiness");
    

}

function getResizedImageDims(imgSrc,maxWidth,maxHeight) {
    var test_img = new Image();
    test_img.src = imgSrc;

    var natWidth = test_img.naturalWidth || test_img.width;
    var natHeight = test_img.naturalHeight || test_img.height;
    //alert ("natural Width:" + natWidth + ", natural Height:" + natHeight);

    //find which dimension is a greater percentage of the maximum for that dimension
    var yScaleRatio = natHeight/maxHeight;
    var xScaleRatio = natWidth/maxWidth;
    //alert ( "xScaleRatio:" + xScaleRatio + " yScaleRatio:" + yScaleRatio); 

	//scale both dimensions so that the larger of the two original dimensions fits its new dimension exactly
	var scaleRatio= (xScaleRatio>=yScaleRatio) ? (1/xScaleRatio) : 1/yScaleRatio; 
    
	newWidth = Math.round(natWidth*scaleRatio,0); 
     newHeight = Math.round(natHeight*scaleRatio,0);    
    
    var newLogoDims = new Array();
    newLogoDims[0] = newWidth; 
    newLogoDims[1] = newHeight;

    return newLogoDims;

}


/* ----- directoryResults.js ----- */
/*
JAVASCRIPT RELATED TO DISPLAY OF DIRECTORY RESULTS FROM SEARCH AND CATEGORY BROWSING ... 
manipulating page elements contained in template_results.pt

Author: Bryan Wilson (code by other authors factored to this new file)
Original Creation Date: 2006.08.03

*/

/* AJAX - BUILD RESULTS PAGING BLOCK */
function createPagingBlock(current_page, total_pages, current_business_count, total_results_count) {

 if (current_business_count <1) {
 
  showAJAXStatus();
  updateAJAXStatus("No businesses available for selected criteria");
 
 };

//	alert("total_pages: " + total_pages );
	
//	alert( "   current_page: " + current_page);
	
//	alert( "  pagecount: " +page_count);
	
//	alert("current batch of businesses: " + current_business_count);
	
//	alert("  Total businesses: " + total_results_count);

 	var max_batch_pages_to_list = 5; //should be an odd number.
	var prev_page;
	var next_page;
	var prev_string ="";
	var next_string = "";
	var last_page;
	var last_page_string ="";
	var first_page =1;
	var first_page_string ="";
	var starting_string ="<strong>Page:</strong> ";
	var recordsPerPage = 10;
	
	var page_list ="";
	total_pages = parseInt(total_pages);
	
	
	
	
	// define previous link 
	prev_page = parseInt(current_page) -1;
	
	if (prev_page <1 ) {
		prev_string += "&nbsp;";

	} else {
		prev_string += '&nbsp;&nbsp;<a href="javascript:setBatchPage('+prev_page+')"><img src="arrow_back.gif" width="14" height="14" align="middle" alt="previous page" title="previous page" border="0" /></a>';
	}
		
		
		
	if (current_page  <= first_page) {
		first_page_string += "&nbsp;";

	} else {
		first_page_string += '&nbsp;&nbsp;<a href="javascript:setBatchPage('+first_page+')"><img src="arrow_first.gif" width="14" height="14" align="middle" alt="go to first page" title="go to first page" border="0" /></a>';
	}

	if (current_page  >= total_pages) {
		last_page_string += "&nbsp;";

	} else {
		last_page_string += '&nbsp;&nbsp;<a href="javascript:setBatchPage('+total_pages+')"><img src="arrow_last.gif" width="14" height="14" align="middle" alt="go to last page" title="go to last page" border="0" /></a>';
	}

		
		
		
		
	// define next link  
	next_page = parseInt(current_page)  + 1;
	
//	alert("prev_page: " + prev_page);
//	alert("next_page: " + next_page);
//	alert("total_pages: " + total_pages);
//	alert("current_page: " + current_page);


//		var debug_string;
//		debug_string =  "prev_page: " + prev_page + "  ";
//	debug_string += "next_page: " + next_page  + "  ";
//	debug_string +="total_pages: " + total_pages  + "  ";
//	debug_string +="current_page: " + current_page + "  ";
	

	
	
	if (next_page > total_pages ) {
		next_string = "&nbsp;";
	} else {
		next_string = '&nbsp;&nbsp;&nbsp;<a href="javascript:setBatchPage('+next_page+')"><img src="arrow_next.gif" width="14" height="14" align="middle" alt="next page" title="next page" border="0" /></a>';
	}
	

	// define page_list
		
	var begin;
	var end;
	var firstResult;
	var lastResult;
	

	if (total_pages <= max_batch_pages_to_list) {
		begin =1 ;
		end = total_pages; 
	} else {
	
		begin = current_page-parseInt((max_batch_pages_to_list-1)/2);
		if (begin >total_pages-(max_batch_pages_to_list-1)) begin = total_pages-(max_batch_pages_to_list-1);

		if (begin < first_page) begin= first_page;
		
		end = begin + max_batch_pages_to_list -1;
		if (end > total_pages) end = total_pages;
	
	}
	
	
	for (i = begin; i<= end; i++) {

			
		if ( i == begin && current_page == first_page) {
		} else {
			page_list = page_list + ( (i!=begin) ? '&nbsp;&nbsp;&#183;' : '' ) +'&nbsp;&nbsp;';
		}
		
		
		if ( i  == current_page) {
			firstResult = (i-1) * recordsPerPage + 1;
			lastResult = firstResult + recordsPerPage - 1;
			lastResult = (lastResult>total_results_count) ? total_results_count : lastResult;

			page_list = page_list + '<span class="selectedPage">' + i +'</span>';
		
		} else {
		
			page_list = page_list + '<a href ="javascript:setBatchPage(' + i +')">' + i +'</a>';
		}
		
	}
	
	
	

  var summary_string = '&nbsp;&nbsp;&nbsp;(Showing ' + firstResult + '-' + lastResult + ' of ' + total_results_count+ ')';
  
  var divtext =  starting_string + first_page_string + prev_string + page_list + next_string +last_page_string + summary_string;
	
//	debug_string +="current_business_count: " + current_business_count  + "  ";
//	debug_string +="total_results_count: " + total_results_count  + "  ";
//	changeElementText2( 'debug_line', debug_string );
  
// alert(divtext);


	changeElementText2( 'pagingBlock', divtext );

	
}

/* AJAX - BUILD RESULTS LIST FUNCTIONS */
function createResultList(table_tagname, businesses) {

    var row;
    var cell;
    var anchor;
    var img;
    var span;
    var i;
    var sortOrder = getSortOrderField();

    var resultsTable = getElement(table_tagname);
    /* erase any pre-existing children of table_tagname */
    while (resultsTable.hasChildNodes())
    	{
    	  resultsTable.removeChild(resultsTable.firstChild);
    	}
    
    /* create a new results list */
    
    /* header for results list, sort funcitonality */
    row = document.createElement("tr");

    cell = document.createElement("th");
    cell.setAttribute('width', '32');
    cell.setAttribute('height', '23');
    setClassAttribute(cell, 'noSort');    
    
    cell.appendChild(document.createTextNode('Map it'));
    row.appendChild(cell);    

    cell = document.createElement("th");
    cell.setAttribute('height', '23');
    cell.setAttribute('id', 'businessSortTableHeader');
    
    if (sortOrder == 'business_desc') {
	    setClassAttribute(cell, 'sortdown'); 
	  } else if (sortOrder == 'business_asc') {
	    setClassAttribute(cell, 'sortup'); //default sort order
	  } else { 
	    setClassAttribute(cell, ''); //side ways arrow.
	  }
	    
    cell.setAttribute('title', 'Sort by Business Name');
    cell.onclick = function() { toggleSortOrder("business"); };
    cell.appendChild(document.createTextNode('Business Name (view details)'));
    row.appendChild(cell);    

    cell = document.createElement("th");
    cell.setAttribute('id', 'districtSortTableHeader');
    
    if (getSortOrderField() == 'district_desc') {
	    setClassAttribute(cell, 'sortdown'); 
	  }	else if (getSortOrderField() == 'district_asc') {
	    setClassAttribute(cell, 'sortup'); //default sort order
	  } else { 
	    setClassAttribute(cell, ''); //side ways arrow.
	  }
    
    cell.setAttribute('height', '23');
    cell.setAttribute('title', 'Sort by District');
    cell.onclick = function() { toggleSortOrder("district"); };
    cell.appendChild(document.createTextNode('District'));
    row.appendChild(cell);
    resultsTable.appendChild(row);
    /*  end: header for results list, sort funcitonality */
    


/* from here on is where the rows are set */
    for (i = 0; i < businesses.length; i++) {
        business_id = businesses[i].getAttribute("business_id");
          row = document.createElement("tr");
          if (i % 2 == 0) setClassAttribute(row, 'evenRow'); 
          row.setAttribute('onMouseOver','for (var i=0;i<this.childNodes.length;i++){this.childNodes[i].style.backgroundColor=\'#FFF7C8\';}');
          row.onMouseOver=function () { //required for IE compatibility, instead of using setAttribute
          	for (var i=0;i<this.childNodes.length;i++){ 
          		this.childNodes[i].style.backgroundColor='#FFF7C8';
          	}
          }; 
          row.setAttribute('onMouseOut','for (var i=0;i<this.childNodes.length;i++){this.childNodes[i].style.backgroundColor=\'\';}');
          row.onMouseOut=function () {  //required for IE compatibility, instead of using setAttribute
          	for (var i=0;i<this.childNodes.length;i++){ 
          		this.childNodes[i].style.backgroundColor='';
          	}
          };

        /* Google Map Pin */
        anchor = document.createElement("a");
        var javascript_string = 'javascript: recenterMap("'+ business_id + '")';
        anchor.setAttribute('href', javascript_string);
        
        marker_level = businesses[i].getAttribute("marker_level");

        var tool_tip_title='';
        
        switch(marker_level) {
        	case '0':
        		tool_tip_title='Other Business';
        		break;
        	case '1':
        		tool_tip_title='Local Main Streets Member';
        		break;
        	case '2':
        		tool_tip_title ='Accepts the Boston Community Change Card';
        		break;
        	default:
        	  tool_tip_title ='';
        	  break;
       }
       anchor.setAttribute('title', tool_tip_title);
        
        img = anchor.appendChild(document.createElement("img"));
        imageURL = getMarkerImageURL(marker_level,"gif");
        img.setAttribute('src', imageURL);
        
        
        anchor.appendChild(img);

        cell = document.createElement("td");
        cell.appendChild(anchor);        
        row.appendChild(cell);
        
        /* Business Name, Address and Phone */
        anchor = document.createElement("a");
        anchor.setAttribute('href','javascript:displayProfile("'+ business_id +'")');
        anchor.setAttribute('title','View business profile');

        cell=document.createElement("td");
        var anchorpointer = cell.appendChild(anchor)
        anchorpointer.appendChild(document.createTextNode(businesses[i].getAttribute("name")));
        cell.appendChild(document.createElement("br"));
        span = cell.appendChild(document.createElement("span"));
        setClassAttribute(span, 'detailText');
        span.appendChild(document.createTextNode(businesses[i].getAttribute("addr")));

        row.appendChild(cell);

        /* District */
        /*  TODO: point to a district profile */
        //anchor.setAttribute('href','javascript:displayDistrictProfile("'+businesses[i].getAttribute("district_id")+'");void(0);');
        //anchor.setAttribute('title','View District profile');
       
       
        district_id = businesses[i].getAttribute("district_id");
        district_title = getDistrictName(district_id);
       
        cell=document.createElement("td");
        setClassAttribute(cell, 'detailText');

        anchor = document.createElement("a");
        anchor.setAttribute('href','javascript:setDistrict("'+district_id+'", "' + district_title +'");void(0);');
        anchor.setAttribute('title','View District Google Map');
        anchorpointer = cell.appendChild(anchor);
        anchorpointer.appendChild(document.createTextNode(district_title));
        row.appendChild(cell);

        /* Row complete, let's add it to the table */
        resultsTable.appendChild(row);
    }
}

/* Populate results list based on Search Box */
function setSearch() {


    resetHiddenFields();
    resetDistrictDropDown();
		hideAllCategories();
    livesearch = getElement('searchGadget').value;
    ajaxsearch = getElement('LSIEFix');

    if (ajaxsearch) ajaxsearch.style.display='none';

    /* Did user fill anything into the search box? */
    if (livesearch == "") {
        alert("Please fill in the Search Box before pressing Go");
    } else {
        
	        /* Bring back the search */

        /* clear Category navigation field (don't reset District or Sort Order) */
        getElement('navfieldSubCategoryIDs').value = "";

			/* clear selected subcategory text from Categories */
			clearSubcategories(); 

			/* clear livesearch div */

        setResultsHdr('Results for search term: ' + livesearch);
        setTitleBar('Mapping businesses with the search term: ' + livesearch);
        
        showAJAXStatus();
        updateAJAXStatus("Retrieving list of businesses with search term: " + livesearch + " ...");

        DisplayMarkers(false);

        //updateBreadcrumbSearch(livesearch); //behavior dropped
    }
}



/* AJAX Status Functions */
function showAJAXStatus() {
    var status = getStyleObject('ajaxStatus');
    var results = getStyleObject('results');
    if (status != false)
      status.display = 'block';
    if (results != false)
      results.display = 'none';
}

function hideAJAXStatus() {
    var status = getElement('ajaxStatus');
    var results = getElement('results');
    if (status != false) {
      status.style.display = 'none';
    }
    if (results != false) {
      results.style.display = 'block';
    }
}

function hidePagingBlock() {
    var pb = getElement('pagingBlock');
    if (pb != false)
      pb.style.display = 'none';
}

function updateAJAXStatus(msg) {
    var newSpan = document.createElement("span");
    newSpan.setAttribute("id","ajaxStatusText");
    var newText = document.createTextNode(msg);
    newSpan.appendChild(newText);

    var titleElm = getElement('ajaxStatus');
    var spanElm  = getElement('ajaxStatusText');
    var replaced = titleElm.replaceChild(newSpan,spanElm);
}

// TODO: This function should be moved when refactoring to a more appropriate location.
// Also, note that this function is almost identical to switchSortOrder, defined in
// buildGoogleJavaScript.py, which should be combined or refactored simultaneously.
// This function is currently used exclusively by IE compatability code for
// event handling onclick.  Probably the best choice is a file for all sort-related functions.
function toggleSortOrder(sortCategory) {
    /* set Categories then refresh markers */
    if (sortCategory =='business') {
    	switch (getSortOrderField()) {    	
    		case "business_desc":
    		  setSortOrder("business_asc", 'sortup', '');
    			break;
    		case "business_asc":
    			setSortOrder("business_desc", 'sortdown', '');
    			break;
    		default: 
    		  setSortOrder("business_asc", 'sortup', '');
    			break;
    	}
    }			
    if (sortCategory =='district') {
    	switch (getSortOrderField()) {
    		case "district_desc":
    		  setSortOrder("district_asc", 'sortup', '');
    			break;
    		case "district_asc":
    		  setSortOrder("district_desc", 'sortdown', '');
    			break;
    		default: 
    		  setSortOrder("district_asc", 'sortup', '') ;
    			break;
    	}
    }			
    	            
    selectedSubCategory = getSelectedSubCategoryField();
    showAJAXStatus();

    var friendlySortName = (sortCategory == 'business') ? 'business name' : 'district';
    updateAJAXStatus("Sorting businesses by " + friendlySortName);
    
    DisplayMarkers(false);
}



function setBatchPage(batchpage) {
	/* set batch_ID then refresh Google map markers */
	
	
	getElement('navfieldBatchPage').value = batchpage;
	
	ajax_message  = 'Retrieving page ' + batchpage;
	
	updateAJAXStatus( ajax_message );
	showAJAXStatus();

	DisplayMarkers(false);
}

function setSortOrder(navFieldOrder, distHeader, busHeader) {
    setSortOrderField(navFieldOrder);
    getElement('districtSortTableHeader').className = distHeader;
    getElement('businessSortTableHeader').className = busHeader;  
}

function getSortOrderField() {
    return getElement('navfieldSortOrder').value;
}

function setSortOrderField(navFieldOrder) {
    getElement('navfieldSortOrder').value = navFieldOrder;
    return navFieldOrder
}

// TODO: THe selectedSubCategory fields should be moved to a hidden field accessor/modifier
// file ... or better, write a singleton class for each of these.
function getSelectedSubCategoryField() {
    return getElement('navfieldSelectedSubCategory').value;
}

function setSelectedSubCategoryField(navfieldSubCategory) {
    getElement('navfieldSelectedSubCategory').value = navfieldSubCategory;
    return navfieldSubCategory
}


// TODO: Either change resultsHdr to have a SPAN and use changeSpanText as in 
// 'setTitleBar' or something else or whatever.
function setResultsHdr(newImageText) {

    the_el = getStyleObject('resultsHdr');
    if (the_el != false) the_el.display = 'block';
      
    var resultsHdrTxt = getElement('resultsHdrTxt');
    
    while (resultsHdrTxt.hasChildNodes()) { 		
    		resultsHdrTxt.removeChild(resultsHdrTxt.firstChild);
    }
    var newResultsHdrText = document.createTextNode(newImageText);
    resultsHdrTxt.appendChild(newResultsHdrText);
    
    //change title image to display category name via sIFR swf 
    //com_stewartspeak_replacement(true,new Array("#resultsHdr")); 
    //alert('resultsHdrTxt innerHTML: '+getElement("resultsHdrTxt").innerHTML);
    
    //sifr kill: commented out 09/21/06 by ATokar
    //sIFR.replaceElement("#resultsHdrTxt", named({sFlashSrc: "sifr-MyriadBold.swf", sColor: "#ffffff", sCase: "upper", sBgColor: "#455A6E" }));
}

// TODO: This function is depricated.  New function is 'toggleSortOrder', but
// check to see if there are any references to this function.
function switchSortOrder(sortCategory) {
    /* set Categories then refresh markers */

		if (sortCategory =='business') {

			switch (getElement('navfieldSortOrder').value) {
			
				case "business_desc":
					getElement('navfieldSortOrder').value = "business_asc";
					getElement('businessSortTableHeader').className = 'sortup';
					getElement('districtSortTableHeader').className = '';
					
					break;
				
				case "business_asc":
					getElement('navfieldSortOrder').value = "business_desc";
					getElement('businessSortTableHeader').className = 'sortdown';
					getElement('districtSortTableHeader').className = '';
					break;
					
				default: 
					getElement('navfieldSortOrder').value = "business_asc";
					getElement('businessSortTableHeader').className = 'sortup';
					getElement('districtSortTableHeader').className = '';
					break;
				
			}
		}			

		if (sortCategory =='district') {

			switch (getElement('navfieldSortOrder').value) {
			
				case "district_desc":
					getElement('navfieldSortOrder').value = "district_asc";
					getElement('districtSortTableHeader').className = 'sortup';
					getElement('businessSortTableHeader').className = '';
					break;
				
				case "district_asc":
					getElement('navfieldSortOrder').value = "district_desc";
					getElement('districtSortTableHeader').className = 'sortdown';
					getElement('businessSortTableHeader').className = '';
					break;
					
				default: 
					getElement('navfieldSortOrder').value = "district_asc";
					getElement('districtSortTableHeader').className = 'sortup';
					getElement('businessSortTableHeader').className = '';
					break;
				
			}
		}			
			
		
    var resultsHdr = getElement('resultsHdr');

    while (resultsHdr.firstChild.hasChildNodes()) { resultsHdr.firstChild.removeChild(resultsHdr.firstChild.firstChild); } 
   
    var newResultsHdrText=document.createTextNode('Results for: '+getElement('navfieldSubCategoryIDs').value);
    resultsHdr.firstChild.appendChild(newResultsHdrText);
    
    showAJAXStatus();
    updateAJAXStatus("Retrieving list of businesses for " + getElement('navfieldSubCategoryIDs').value + " category...");

    DisplayMarkers(false);

}


/* ----- directoryTitle.js ----- */
/*
JAVASCRIPT RELATED TO DISPLAY OF DIRECTORY VIEW TITLES AND BREADCRUMBS ... 
manipulating page elements contained in template_title.pt

Author: Bryan Wilson (code by other authors factored to this new file)
Original Creation Date: 2006.08.03

*/


function setTitleBar(newTitleBarImageText) {
    changeSpanText('directoryTitleText', newTitleBarImageText);
}

// TODO: Remove depricated breadcrumb code from directoryResults.js,
//   directoryDistricts.js, and directoryCategories.js.
// TODO: Remove file 'businessmember.js' from source control.

// function updateBreadcrumbs() {
//  /* TO-DO: See if this is needed: empty function as of 2006.8.3 BCW */   
// }
// 
// function updateBreadcrumbSearch(searchterm) {
//     updateBreadcrumbCategory('Search: \'' + searchterm +'\'');
// }
// 
// function updateBreadcrumbDistrict(msg) {
//     var newSpan = document.createElement("span");
//     newSpan.setAttribute("id","breadcrumb_districtText");   // add so new tag has same id=""
//     var newText = document.createTextNode(msg);
//     newSpan.appendChild(newText);
// 
//     var titleElm = getElement("breadcrumb_district");
//     var spanElm  = getElement("breadcrumb_districtText");
//     var replaced = titleElm.replaceChild(newSpan,spanElm);
// 
//     /* if this is not a search, then reset Category Breadcrumb */
//     if (getElement('searchGadget').value == "") {    
//         if (getElement('navfieldSubCategoryIDs').value == "") {
//             updateBreadcrumbCategory('No Category Chosen');
//         }
//     }   
// }
// 
// function updateBreadcrumbCategory(msg) {
//     var newSpan = document.createElement("span");
//     newSpan.setAttribute("id","breadcrumb_categoryText");   // add so new tag has same id=""
//     var newText = document.createTextNode(msg);
//     newSpan.appendChild(newText);
// 
//     var titleElm = getElement("breadcrumb_category");
//     var spanElm  = getElement("breadcrumb_categoryText");
//     var replaced = titleElm.replaceChild(newSpan,spanElm);    
// 
//     /* if this is not a search, then reset District Breadcrumb */
//     if (getElement('searchGadget').value == "") {
//         if (getElement('navfieldDistrictID').value == "") {
//             updateBreadcrumbDistrict('No District Chosen')
//         }
//     }
// 
// }


/* ----- directoryView.js ----- */
/*
JAVASCRIPT RELATED TO VIEW/DISPLAY STATE OF DIRECTORY ... 
manipulating display/hiding of templates profile/districtProfile/Googlemap/welcome etc.

Author: Bryan Wilson (code by other authors factored to this new file)
Original Creation Date: 2006.08.03

*/

function updateWindowTitle(newTitle) {
    //oldTitle on a Plone site should end with an em-dash followed by the portal title
    //title tag uses utf-8-encoded em-dash: first we need it decoded  for
    //javascript via unicode
    mdash = String.fromCharCode('8212');

    if (document.title) {
      oldTitle = document.title.split(mdash);     
      if (oldTitle.length > 1) {
        portalTitle = oldTitle[1]; 
      } else portalTitle = '';
      
      document.title = newTitle + ' ' + mdash + portalTitle;
    }
    else return false;
}

function displayWelcome() {

    /* TODO (8/3/06-bcw): can probably eventually get rid of this function: welcome no longer a 
    page state but a separate html page: will navigate into directory from 
    base url ? 

    (24/4/07-bcw): actually, we may want to reinstate the welcome state in order to 
    improve usability: abrupt context change when changing to directory */

    //remove any id's stored in the browser bar URL
    clearPermalinks();

    //update window title to display just 'Business Directory
    updateWindowTitle('Business Directory');

    /* disable "map" and "content" areas, turn on "welcome" */
    //var the_el = getStyleObject('content');
    //if (the_el != false) the_el.display = 'block';

    the_el = getStyleObject('profile');
    if (the_el != false) {
      the_el.position = "absolute";
      the_el.left = "-6000px";
      ///the_el.width = "1px";
      the_el.zIndex = "-1";
    }     

    the_el = getStyleObject('district');
    if (the_el != false) the_el.display = 'none';  

    the_el = getStyleObject('districts');
    if (the_el != false) the_el.display = 'block';

    the_el = getStyleObject('map');
    if (the_el != false) {
      the_el.position = "absolute";
      the_el.left = "-5000px";
      the_el.zIndex = "-1";
    }

    the_el = getStyleObject('googlemapsmall');
    if (the_el != false) the_el.visibility = 'hidden';     

    the_el = getStyleObject('directionsBlock');
    if (the_el != false) the_el.visibility = 'hidden';        
    
    setTitleBar("The Boston Community Change Business Directory");

}

function displayDistricts() {

    //remove any id's stored in the browser bar URL
    clearPermalinks();   

    //update window title to display just 'Business Directory
    updateWindowTitle('Business Directory');    

    /* disable "map" and "content" areas */
    //var the_el = getStyleObject('content');
    //if (the_el != false)  the_el.display = 'block';

    the_el = getStyleObject('profile');
    if (the_el != false) {
      the_el.position = "absolute";
      the_el.left = "-6000px";
      the_el.zIndex = "-1";
    }

    /* show profile Edit Tool : may still not show up if user does not have permissions */  
    the_el = getStyleObject('editProfile');
    if (the_el != false) the_el.display = 'none';

    the_el = getStyleObject('district');
    if (the_el != false) the_el.display = 'none';  

    the_el = getStyleObject('districts');
    if (the_el != false) the_el.display = 'block';

    the_el = getStyleObject('map');
    if (the_el != false) {
      the_el.position = "absolute";
      the_el.left = "-5000px";
      the_el.zIndex = "-1";
    }

    the_el = getStyleObject('mapKey');
    if (the_el != false) the_el.display = 'none';   
    
    the_el = getStyleObject('googlemapsmall');
    if (the_el != false) the_el.visibility = 'hidden';    

    the_el = getStyleObject('directionsBlock');
    if (the_el != false) the_el.visibility = 'hidden';        
    
    setTitleBar("Boston Main Streets Districts");

}

function displayDistrictProfile(district_id) {

    //remove any id's stored in the browser bar URL
    clearPermalinks();

    //update window title to display District Name
    //updateWindowTitle();    

    /* turn off "content" and "map" and "welcome" and "district", turn on "profile" */
    //var the_el = getStyleObject('content');
    //if (the_el != false) the_el.display = 'none';
  
    the_el = getStyleObject('profile');
    if (the_el != false) {
      the_el.position = "absolute";
      the_el.left = "-6000px";
      the_el.zIndex = "-1";
    }

    /* show profile Edit Tool : may still not show up if user does not have permissions */  
    the_el = getStyleObject('editProfile');
    if (the_el != false) the_el.display = 'block';      
      
    the_el = getStyleObject('welcome');
    if (the_el != false) the_el.display = 'none';

    
    the_el = getStyleObject('map');
    if (the_el != false) {
      the_el.position = "absolute";
      the_el.left = "-5000px";
      the_el.zIndex = "-1";
    }

    the_el = getStyleObject('mapKey');
    if (the_el != false) the_el.display = 'none';   

    the_el = getStyleObject('googlemapsmall');
    if (the_el != false) the_el.visibility = 'hidden';    

    the_el = getStyleObject('directionsBlock');
    if (the_el != false) the_el.visibility = 'hidden';   
 
    the_el = getStyleObject('district');
    if (the_el != false)
      the_el.display = 'block';
      the_el.visibility = 'visible';
      buildDistrictProfile(district_id);
    
}

function displayMap() {

    //remove any id's stored in the browser bar URL
    clearPermalinks(); 

    //update window title to display just 'Business Directory
    updateWindowTitle('Business Directory');
    
    /* enable "map" and "content" areas, turn off "welcome" and "profile" and "district" */
    //var the_el = getStyleObject('content');
    //if (the_el != false) the_el.display = 'block';

    the_el = getStyleObject('mapKey');   
    if (the_el != false) {
      the_el.display = 'block';      
    }
 
    the_el = getStyleObject('districts');
    if (the_el != false) {
      the_el.display = 'none';
    }
      
    the_el = getStyleObject('profile');
    if (the_el != false) {
      the_el.position = "absolute";
      the_el.left = "-6000px";
      the_el.zIndex = "-1";
    }

    /* show profile Edit Tool : may still not show up if user does not have permissions */  
    the_el = getStyleObject('editProfile');
    if (the_el != false) the_el.display = 'none';   
            
    the_el = getStyleObject('profileCannotEdit');
    if (the_el != false) the_el.display = 'none';      
      
    the_el = getStyleObject('district');
    if (the_el != false) the_el.display = 'none';  

    the_el = getStyleObject('map');
    if (the_el != false) {
      the_el.position = "relative";
      the_el.left = "0px";
      the_el.zIndex = "1";
    }

    the_el = getStyleObject('googlemapsmall');
    if (the_el != false) the_el.visibility = 'hidden';    

    the_el = getStyleObject('directionsBlock');
    if (the_el != false) the_el.visibility = 'hidden';        

    
}

function displayProfile(businessmember_id, clear_category_browse_state) {
    
    if (!clear_category_browse_state) {
        clear_category_browse_state = 0;
    }    
    if (clear_category_browse_state) {
        resetHiddenFields();
        resetCategoryBrowseView();
    }
    
    /* turn off "content" and "map" and "welcome" and "district", turn on "profile" */
    //var the_el = getStyleObject('content');
    //if (the_el != false)  the_el.display = 'none';
  
    the_el = getStyleObject('district');
    if (the_el != false) the_el.display = 'none';

    the_el = getStyleObject('districts');
    if (the_el != false) the_el.display = 'none';
      
    /* show profile Edit Tool : may still not show up if user does not have permissions */  
    the_el = getStyleObject('editProfile');
    if (the_el != false) the_el.display = 'block';

    the_el = getStyleObject('map');
    if (the_el != false) {
      the_el.position = "absolute";
      the_el.left = "-5000px";
      the_el.zIndex = "-1";
    }

    the_el = getStyleObject('mapKey');
    if (the_el != false) the_el.display = 'none';   

    the_el = getStyleObject('directionsBlock');
    if (the_el != false) the_el.visibility = 'hidden';        
 
    the_el = getStyleObject('profile');
    if (the_el != false) {
      buildProfile(businessmember_id);
      the_el.position = "relative";
      the_el.zIndex = "1";
      the_el.left = "0px";
      the_el.visibility = 'visible'; 
      the_el.width = "auto"; 
      /* profile set to hidden when page is loaded; workaround to insure googlemapsmall works */
    }
    
    /* scroll up to top of map */  
    
}

function resetHiddenFields() {   
    // Hidden Fields
    getElement("navfieldCategoryTitle").value = "all categories";    
    getElement("navfieldSubCategoryIDs").value = "all categories";    
    setSelectedSubCategoryField("");
    
    /* TODO: Make into accessor/modifier and check for other instances and refactor*/
    getElement("navfieldDistrictID").value = "";
    
    /* TODO: Make into accessor/modifier and check for other instances and refactor*/
    getElement("navfieldDistrictTitle").value = "all districts";
    
    setSortOrderField("business_asc");
    setBatchPage(1);
}

function resetCategoryBrowseView() {
    // AJAX
    clearSubcategories();
    resetDistrictDropDown();
    setResultsHdr("Results");
    turnOffCategoryHighlights();
    hideAJAXgetStyleObject();
    
//    hidePagingBlock();
}

/* set district drop down to all districts */
function resetDistrictDropDown() {
    selDistrictElement = getStyleObject('selDistrict');
    selDistrictElement.selectedIndex = 0;
}


/* TODO: This is a crappy kludge, think of a better way to do it */
function turnOffCategoryHighlights() {
    /* TODO: The function name 'toggleCategoryHighlight' is a misnomer imo */
    toggleCategoryHighlight('cat-business','off');
    toggleCategoryHighlight('cat-education','off');
    toggleCategoryHighlight('cat-food','off');
    toggleCategoryHighlight('cat-health','off');
    toggleCategoryHighlight('cat-home','off');
    toggleCategoryHighlight('cat-retail','off');    
}




