//$Id: common.js,v 1.120 2009/11/13 02:18:02 nick Exp $
// common functions

function getEl(id)
{
	return document.getElementById(id);
}

String.prototype.trim = function ()
{
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

AjaxFormSubmit =
{
	frame : function(c)
	{
		var n = 'f' + Math.floor(Math.random() * 999999);
		var d = document.createElement('DIV');
		d.innerHTML = '<iframe style="display:none" src="about:blank" id="'+n+'" name="'+n+'" onload="AjaxFormSubmit.loaded(\''+n+'\')"></iframe>';
		document.body.appendChild(d);

		newEl = document.getElementById(n);
		if (c && typeof(c.onComplete) == 'function')
			newEl.onComplete = c.onComplete;

		return n;
	},

	form : function(f, name)
	{
		f.setAttribute('target', name);
	},

	submit : function(f, c)
	{
		AjaxFormSubmit.form(f, AjaxFormSubmit.frame(c));
		if (c && typeof(c.onStart) == 'function')
			return c.onStart();
		else
			return true;
	},

	loaded : function(id)
	{
		var i = document.getElementById(id);
		if (i.contentDocument)
			var d = i.contentDocument;
		else if (i.contentWindow)
			var d = i.contentWindow.document;
		else
			var d = window.frames[id].document;

		if (d.location.href == "about:blank")
			return;
		if (typeof(i.onComplete) == 'function')
		{
			var text = d.body.innerHTML;
			i.onComplete(text);
		}
	}
}

function toggleDisplay(id)
{
	el = getEl(id);
	if (!el)
		return;
	if (el.style.display == 'block')
		el.style.display = 'none';
	else
		el.style.display = 'block';
}
function toggleDisplayOn(id)
{
	el = getEl(id);
	if (!el)
		return;
	var val='block';
	if (el.tagName.toLowerCase()=='tr')
		val='table-row';
	el.style.display = val;
}
function toggleDisplayOff(id)
{
	el = getEl(id);
	if (!el)
		return;
	el.style.display = 'none';
}

function getElementPos(element)
{
  var coords = {x: 0, y: 0};
  do {
    coords.x += element.offsetLeft;
    coords.y += element.offsetTop;
  }
  while ((element = element.offsetParent));
  return coords;
}

function setElementPos(element, coords)
{
	element.style.left = coords.x+"px";
	element.style.top = coords.y+"px";
}

function fitOnScreen(element, marginSize)
{
	winWidth = getWinWidth() - 2*marginSize;
	winHeight = getWinHeight() - 2*marginSize;

	if (element.offsetWidth > winWidth)
		element.style.width = winWidth+"px";
	if (element.offsetHeight > winHeight)
		element.style.height = winHeight+"px";
}

function centerElement(element)
{
	var left = parseInt((getWinWidth() - element.offsetWidth)/2);
	var top = parseInt((getWinHeight() - element.offsetHeight)/2);
	if (left < 0)
		left = 0;
	if (top < 0)
		top = 0;
	var coords = {x: left, y: top};
	setElementPos(element, coords);
}

function NewWindow(theurl,thename,w,h,scroll)
{
  var left = (screen.width-w)/2;
  var top = (screen.height-h)/2;
  var settings  ='height='+h+',';
      settings +='width='+w+',';
      settings +='top='+top+',';
      settings +='left='+left+',';
      settings +='scrollbars='+scroll+',';
      settings +='resizable=yes';
 	thewin = window.open(theurl,thename, settings);
 	thewin.focus();
}

function getWinWidth()
{
    if (window.innerWidth) return window.innerWidth - 18;
    else if (document.documentElement && document.documentElement.clientWidth)
  		return document.documentElement.clientWidth;
    else if (document.body && document.body.clientWidth)
  		return document.body.clientWidth;
  	else if (document.body && document.body.parentNode && document.body.parentNode.clientWidth)
 		return document.body.parentNode.clientWidth;
}

function getWinHeight()
{
    if (window.innerHeight) return window.innerHeight - 18;
  	else if (document.documentElement && document.documentElement.clientHeight)
  		return document.documentElement.clientHeight;
  	else if (document.body && document.body.clientHeight)
  		return document.body.clientHeight;
  	else if (document.body && document.body.parentNode && document.body.parentNode.clientHeight)
  		return document.body.parentNode.clientHeight;
}

function showWindowShade(displayMode) // block or none
{
	el = document.getElementById('windowShade');
	if (!el)
		return;

	if (displayMode == 'block')
	{
		el.style.width=document.body.scrollWidth+'px';
		el.style.height=document.body.scrollHeight+'px';
	}
	el.style.display = displayMode;
}

function TextFormattingPopup() {
	var html = "<a href='javascript:void(0);' onclick=\"javascript:NewWindow('/scripts/TextFormatRules.php', 'TextFormattingRules', 700, 500, 'yes');\"><small>MORE TEXT FORMATTING FEATURES</small></a>";
	document.write(html);
}

function PreviewMessagePopup(textid) {
	var html = "<img src='/img/preview.gif' width=12 height=12 style='vertical-align:middle';>&nbsp;<a href='javascript:void(0);' onclick=\"javascript:NewWindow('/scripts/PreviewMessagePopup.php?textelementid="+textid+"', 'PreviewMessagePopup', 700, 450, 'yes');\"><small>PREVIEW MESSAGE TEXT</small></a>";
	document.write(html);
}

function Popup(label, url, x, y) {
	var html = "<a href='javascript:void(0);' onclick=\"javascript:NewWindow('" + url +"', 'Popup', "+x+", "+y+", 'yes');\">"+label+"</a>";
	document.write(html);
}



function onRouteFinderTypeChanged()
{
	type = document.getElementById('type').value;

	aTypes = new Array('rock', 'boulder', 'aid', 'ice', 'mixed');

	for (i=0; i<aTypes.length; i++)
	{
		display = aTypes[i] == type ? 'inline' : 'none';
		document.getElementById('diffMin'+aTypes[i]).style.display = display;
		document.getElementById('diffMax'+aTypes[i]).style.display = display;
	}
	if (type == 'rock')
		document.getElementById('typeOptions').style.display = 'inline';
	else
		document.getElementById('typeOptions').style.display = 'none';
}

function ChangeRating(id, action)
{
	if (action != 'clearRating')
	{
		showWindowShade('none');
		Tooltip.hide();
	}

	var str = 'id=' + id + '&action=' + action;
	if (action == 'saveRating')
	{
		els = document.changeRatingForm.elements;
		for (i=0; i<els.length; i++)
			str += '&' + els[i].name + '=' + els[i].value;
		// show trashcan
		document.getElementById('RouteRatingClear').style.visibility='visible';
	}
	else if (action == 'clearRating')
	{
		// hide trashcan
		document.getElementById('RouteRatingClear').style.visibility='hidden';
	}
	else
	{
		return;
	}

	if (!CheckLogin("We'll keep track of your rating for each route, but you have to sign up so we know who you are."))
		return;

	makeXmlHttpRequest("/scripts/XmlHttpRequest.php?"+str)
	document.getElementById('personalRating').innerHTML = "<img src='/img/wait_bar.gif'>";
}

function setStars(starGroupId, id, newScore)
{
	if (!CheckLogin("We'll keep track of your score for each route, but you have to sign up so we know who you are."))
		return;

	makeXmlHttpRequest("/scripts/XmlHttpRequest.php?action=saveScore&starGroupId="+starGroupId+"&id="+id+"&score="+newScore)
	document.getElementById('starGroup_'+starGroupId).innerHTML = "<img src='/img/wait_bar.gif'>";
}

function getTodoText(inList, routeId) {
	if (!inList) {
		return '<a href="javascript: todoRoute(' + routeId + ', \'add\');">Add this route</a>';
	} else {
		return 'On the list <a href="javascript: todoRoute(' + routeId + ', \'del\');"><img src="/img/trash.gif\" width=10 height=11 border=0></a>';
	}
}

function todoRoute(routeId, action)
{
	if (!CheckLogin("We'll keep track of your todo list, but you have to sign up so we know who you are."))
		return;

	url = '/scripts/XmlHttpRequest.php?action=' + action + 'Todo&routeId=' + routeId;
	makeXmlHttpRequest(url)
	if (action=='del')
		text=getTodoText(0, routeId);
	else
		text=getTodoText(1, routeId);
	document.getElementById('todoText').innerHTML = text;
}

function ShowCalendar(dateInputId)
{
	document.getElementById(dateInputId).select();
	setTimeout("calendar.select(document.getElementById('"+dateInputId+"'),'dateAnchor','yyyy-MM-dd')", 100);
}

function AddTick(routeId, today)
{
	var html = "<form method='post' name='addTickForm'><table cellpadding=3 cellspacing=0>";
	html += "<tr><td align='right'><p>Date:</p></td>";
	html += "<td>";
	html += "<input type='hidden' name='id' value='"+routeId+"'>";
	html += "<input type='text' name='date' id='date' value='"+today+"' size='12' onfocus='ShowCalendar(\"date\")'>";
	html += "<a href='#' onClick='ShowCalendar(\"date\"); return false;' ";
	html += "name='dateAnchor' ID='dateAnchor'><img hspace='5' src='/img/cal.gif' border='0' width='16' height='16' align='absmiddle'></A>";
	html += "</td></tr>";
	html += "<tr><td align='right' valign='top'><p>Notes:<br /></p></td>";
	html += "<td><textarea cols=23 rows=3 name='comments' onKeyPress='if (this.value.length >= 100) alert(\"Your comment can have up to 100 characters.  You have \"+(this.value.length+1)+\".\");'></textarea></td></tr>";
	html += "<tr><td colspan='2' align='center'><p><a href='javascript:SaveTick(\"save\")'>Save</a> - ";
	html += "<a href='javascript:SaveTick(\"cancel\")'>Cancel</a></p></td></tr>";
	html += "</table></form>";

	showWindowShade('block');
	doToolTip(null, html, false,'topright',document.getElementById('TickHref'),'#eee', 280);
}

function DelTick(routeId, id)
{
	url = '/scripts/XmlHttpRequest.php?action=delTick&id=' + routeId + '&tickId=' + id;

	makeXmlHttpRequest(url)
	document.getElementById('tickHtml').innerHTML = "<img src='/img/wait_bar.gif'>";
}


function CheckLogin(msg)
{
	msg += "\n\nComplete the quick and easy signup now?";
	if (isLoggedIn())
		return true;
	else
	{
		if (confirm(msg))
			document.location.href='/scripts/Signup.php';
		return false;
	}
}

function SaveTick(action)
{
	showWindowShade('none');
	Tooltip.hide();
	if (action == 'save')
	{
		if (!CheckLogin("We'll keep track of your ticks for each route, but you have to sign up so we know who you are."))
			return;

		url = "/scripts/XmlHttpRequest.php?action=saveTick";
		els = document.addTickForm.elements;
		for (i=0; i<els.length; i++)
			url += '&' + els[i].name + '=' + escape(els[i].value);

		makeXmlHttpRequest(url)
		document.getElementById('tickHtml').innerHTML = "<img src='/img/wait_bar.gif'>";
	}
}


function getValueFromQueryString(name, queryString)
{
	if (queryString==null) return '';
    start = queryString.indexOf(name+'=', 0);
    if (start < 0)
    	return '';
    start += name.length+1;
	end = queryString.indexOf ("&", start);
	if (end == -1)
        end = queryString.length;
    return unescape(queryString.substring(start, end));
}


var clientSideTargetElement;
function clientSideInclude(url,id) {
  req = false;
  // For Safari, Firefox, and other non-MS browsers
  if (window.XMLHttpRequest) {
    try {
      req = new XMLHttpRequest();
    } catch (e) {
      req = false;
    }
  } else if (window.ActiveXObject) {
    // For Internet Explorer on Windows
    try {
      req = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        req = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {
        req = false;
      }
    }
  }
 clientSideTargetElement = document.getElementById(id);
 if (!clientSideTargetElement) {
  alert("Bad id " + id +
   "passed to clientSideInclude." +
   "You need a div or span element " +
   "with this id in your page.");
  return;
 }
  if (req) {
    // Synchronous request, wait till we have it all
    req.onreadystatechange = clientSideIncludeReqChange;
    req.open('GET', url, true);
    req.send(null);

  } else {
    element.innerHTML =
   "Sorry, your browser does not support " +
      "XMLHTTPRequest objects. This page requires " +
      "Internet Explorer 5 or better for Windows, " +
      "or Firefox for any system, or Safari. Other " +
      "compatible browsers may also exist.";
  }
}

function clientSideIncludeReqChange() {
    clientSideTargetElement.innerHTML = req.responseText;
}

function makeXmlHttpRequest(url)
{
//document.location.href=url;
//return;

    if (window.XMLHttpRequest)
    	req = new XMLHttpRequest();
    else if (window.ActiveXObject)
        req = new ActiveXObject("Microsoft.XMLHTTP");
    if (!req)
    {
    	alert("Your browser is outdated (missing XMLHttpRequest). This feature will not work on your broswer.");
    	return;
    }
    req.onreadystatechange = processReqChange;
    // add some randomness to prevent caching
    url += '&rand=' + Math.random()
    // and do it
    req.open("GET", url, true);
    req.send(null);
}

function processReqChange()
{
   // only if req shows "loaded"
    if (req.readyState == 4)
    {
        if (req.status == 200) // only if "OK"
        {
        	// get the data
        	str = req.responseText;
        	var error = String;
        	error = getValueFromQueryString('showError', str);
        	if (error.length)
        		alert(error);
        	action = getValueFromQueryString('action', str);
        	if (action == 'delTodo' || action =='addTodo')
        	{
        	}
        	else if (action == 'getPPData')
        	{
				PPShow(getValueFromQueryString('peopleHtml', str));
        	}
        	else if (action == 'saveRating' || action == 'clearRating')
        	{
        		rating = getValueFromQueryString('newRating', str);
				setTimeout("document.getElementById('personalRating').innerHTML = rating", 100);
        	}
        	else if (action == 'saveTick' || action == 'delTick')
        	{
        		html = unescape(getValueFromQueryString('tickHtml', str));
				setTimeout("document.getElementById('tickHtml').innerHTML = html", 100);
        	}
        	else if(action == 'saveScore')
        	{
        		// get values from scripts
	        	count = getValueFromQueryString('count', str);
	        	id = getValueFromQueryString('id', str);
	        	newScore = getValueFromQueryString('score', str);
	        	avg = getValueFromQueryString('avg', str);

	        	//-----------------
	        	// update the page
	        	//-----------------

	        	// change text display in route header (average score)
				if (document.getElementById('starSummaryText')) document.getElementById('starSummaryText').innerHTML = starSummaryText(avg,count)

				// change star display in route header
				if (document.getElementById('routeStars')) document.getElementById('routeStars').innerHTML = starsHtml(avg, 'avg');

				// change star display in leftnav
				leftNavSelectedRouteStars = document.getElementById('leftNavSelectedRouteStars');
				if (leftNavSelectedRouteStars) {
					if (newScore>0)
					   // show the stars in 'user' mode (yellow)
					   leftNavSelectedRouteStars.innerHTML = starsHtml(newScore, 'user');
					else
					   // user cleared the score, show in 'leftnav' mode
					   leftNavSelectedRouteStars.innerHTML = starsHtml(avg, 'leftnav');
				}

        	}
        	else if (action=='rateThis') {
        	}
        	else // the object picker has no action
        	{
        		// eval any js in response
        		aResults = req.responseText.match(/\<script.*?\>(.*?)\<\/script\>/);
        		if (aResults)
        			eval(aResults[1]);

        		if (gActivePicker)
        		{
		        	gActivePicker.setLoadedHtml(gActivePicker.sLoadedHtmlCurSelKey, req.responseText);
					setTimeout("gActivePicker.draw(false);", 100);
        		}
        	}
        }
        else
        {
            alert("There was a problem retrieving the data:" + req.statusText +" for action:"+ action);
        }
    }
}




//--------------------------------
//--------------------------------
//--------------------------------
//--------------------------------
//  Start Object Picker

gActivePicker = null;
gAreas = new Array();
function ObjectPicker(iSelectedId, sObjectType, iMultiSelect, aSelectedObjectIds, sFormInputId)
{
	this.iSelectedId = iSelectedId; // which area is currently selected, usually start with root
	this.sObjectType = sObjectType; // required: AREA, IMAGE, AREA_OR_ROUTE
	this.iMultiSelect = iMultiSelect; // required: 0,1
	this.aSelectedObjectIds = aSelectedObjectIds; // required: array of existing selections, can be empty
	this.sFormInputId = sFormInputId; // required: where the object Ids are set

	this.aInputsToHide = new Array();
	this.sOnClose = '';
	this.sDisplayTitleId = '';
	this.aLoadedHtml = new Array();
	this.sLoadedHtmlCurSelKey = '';
	this.sTextDisplayId = '';
	this.aDisallowedObjectIds = new Array();
}

ObjectPicker.prototype.setTextDisplayId = function(id)
	{this.sTextDisplayId = id;}

ObjectPicker.prototype.addDisallowedObjectId = function(id)
	{this.aDisallowedObjectIds['i'+id]=1;}

ObjectPicker.prototype.setSelectedId = function(iSelectedId)
	{this.iSelectedId = iSelectedId;}

ObjectPicker.prototype.setOnCloseCode = function(sCode)
	{this.sOnClose = sCode;} // run this when ObjectPicker is Done

ObjectPicker.prototype.setLoadedHtml = function(sKey, sHtml)
	{this.aLoadedHtml[sKey] = sHtml;} // run this when ObjectPicker is Done

ObjectPicker.prototype.setDisplayTitleId = function(sDisplayTitleId)
	{this.sDisplayTitleId = sDisplayTitleId;} // show the selected object titles in this id

ObjectPicker.prototype.setInputsToHide = function(aInputsToHide)
	{this.aInputsToHide = aInputsToHide;} // IE needs to have some inputs hidden

ObjectPicker.prototype.removeSelection = function(id)
{
	for (var i=0; i<this.aSelectedObjectIds.length; i++)
	{
		if (this.aSelectedObjectIds[i] == id)
		{
			this.aSelectedObjectIds.splice(i,1);
			this.draw(false);
			return;
		}
	}
}

ObjectPicker.prototype.addSelection = function(id)
{
	for (var i=0; i<this.aSelectedObjectIds.length; i++)
	{
		if (this.aSelectedObjectIds[i] == id)
		{
			alert('Already in the list.');
			return;
		}
	}
	if (this.aDisallowedObjectIds['i'+id])
	{
		alert('Object not allowed');
		return;
	}
	this.aSelectedObjectIds.push(id);
	this.draw(false);
}

ObjectPicker.prototype.create = function()
{
	if (!doToolTip)
		return;

	for(i=0; i<this.aInputsToHide.length; i++)
	{
		if (document.getElementById(this.aInputsToHide[i]))
			document.getElementById(this.aInputsToHide[i]).style.visibility = 'hidden';
	}

	showWindowShade('block');
	gActivePicker = this;
	this.draw(true);
}

ObjectPicker.prototype.draw = function(bLoadIfNecessary)
{
	this.sLoadedHtmlCurSelKey = "type="+this.sObjectType+"&multi="+this.iMultiSelect+"&id="+this.iSelectedId;
	var html = this.aLoadedHtml[this.sLoadedHtmlCurSelKey];
	if (!html && bLoadIfNecessary)
	{
		makeXmlHttpRequest("/scripts/XmlHttpRequest.php?action=getObjectPickerHtml&"+this.sLoadedHtmlCurSelKey);
		html = '<p><img src="/img/wait_bar.gif">&nbsp;&nbsp;Loading data...</p>';
		el = document.getElementById("ObjectPickerGuts");
		if (el)
		{
			el.innerHTML = html;
			return;
		} // else create the tooltip below
	}
	doToolTip(null, html, false,'center',null,'#eee', 480);

	dataDiv = document.getElementById('ObjectPickerAreaList');
	if (dataDiv) // means we'll also have a curSels div
	{
		aPos1 = getElementPos(dataDiv);
		selected = document.getElementById('CurrentObjectPickerSelection');
		aPos2 = getElementPos(selected);
		offset = aPos2['y'] - aPos1['y'];
		if (offset > 300)
			dataDiv.scrollTop = offset-50;

		// show the current selections
		var curSelHtml = '';
		if (this.iMultiSelect)
		{
			curSelHtml = "Pick an area on the left";
			if (!this.aDisallowedObjectIds['i'+this.iSelectedId])
			{
				curSelHtml += ", or <br /><input type=button onclick='gActivePicker.addSelection("+this.iSelectedId+")' "+
				"value='Add "+gAreas[this.iSelectedId]+"'>"
			}
			curSelHtml += "<br /><br />Your current selections:<div id='ObjectPickerSelectedObjectList'>";
			for (var i=0; i<this.aSelectedObjectIds.length; i++)
			{
				id = this.aSelectedObjectIds[i];
				title = gAreas[id];
				curSelHtml += "<p><a href='javascript:gActivePicker.removeSelection("+id+")'><img border=0 src='/img/trash.gif' /></a> "+title+"</p>";
			}
			if (!this.aSelectedObjectIds.length)
				curSelHtml += "&nbsp;&nbsp;<p><em>none</em></p>";
			curSelHtml += "<br /><p>Click Done when you have finished.</p>";
		}
		else
		{
			curSelHtml += "You have selected <b>"+gAreas[this.iSelectedId]+"</b>.<br /><br />Click Done if you are finished or make another selection."
			this.aSelectedObjectIds = Array();
			this.aSelectedObjectIds.push(this.iSelectedId);
		}
		document.getElementById('curSels').innerHTML = curSelHtml;
	}
}

ObjectPicker.prototype.close = function(bSaveNewLocation)
{
	if (bSaveNewLocation)
	{
		var aIds = new Array();
		var aTitles = new Array();
		for (var i=0; i<this.aSelectedObjectIds.length; i++)
		{
			id = this.aSelectedObjectIds[i];
			aIds.push(id);
			aTitles.push(gAreas[id]);
		}
		if (this.sTextDisplayId.length)
			document.getElementById(this.sTextDisplayId).innerHTML = aTitles.join(', ');
		document.getElementById(this.sFormInputId).value = aIds.join(' ');
		eval(this.sOnClose);
	}
	Tooltip.hide();
	showWindowShade('none');
	gActivePicker = null;

	for(i=0; i<this.aInputsToHide.length; i++)
	{
		if (document.getElementById(this.aInputsToHide[i]))
			document.getElementById(this.aInputsToHide[i]).style.visibility = 'visible';
	}
}

//  End Object Picker
//--------------------------------
//--------------------------------
//--------------------------------
//--------------------------------

//--------------------------------
//--------------------------------
//--------------------------------
//--------------------------------
//  Start People Picker

function PersonPickedFromList(id, name)
{
	aPeopleInPhoto['i'+id] = name;
	ListPeopleInPhoto();
	PPClose();
}

function PPClose()
{
	Tooltip.hide();
	showWindowShade('none');

	if (typeof PPInputsToHide != 'undefined')
	{
		for(i=0; i<PPInputsToHide.length; i++)
			document.getElementById(PPInputsToHide[i]).style.visibility = 'visible';
	}
}

function PPGetNames()
{
	name = document.getElementById('name').value;
	if (name.length < 2)
	{
		alert('Enter at least two letters of a username.');
		return false;
	}
	url = "/scripts/XmlHttpRequest.php?action=getPPData&name="+name;
	document.getElementById("PPNameForm").innerHTML = '<img src="/img/wait_bar.gif"> Loading data...';
	makeXmlHttpRequest(url);
}

function PPShow(listHtml)
{
	if (!doToolTip)
		return;

	showWindowShade('block');

	if (listHtml.length == 0)
		listHtml = '<font color="gray">Use the form above to find a user.</font>';
	else
		listHtml = '<b>Select a user from the list below:</b><br>'+listHtml;

	var html = '<table cellpadding=2 cellspacing=2 width="100%" align="center">';
	html += '<tr><td>Enter part of a username<br /><small>at least two letters</small><br />';
	html += '<span id="PPNameForm"><input type="text" id="name" size=10/>&nbsp;<input type="button" value="Find User" onClick="return PPGetNames();"></span></td></tr>';
	html += '<tr><td><div style="height:300px; overflow:auto; border:1px solid black; padding:3px">';
	html += listHtml;
	html += '</div></td></tr>';
	html += '<tr><td align="center"><a class="bold" href="javascript:PPClose();">Done</a></td></tr></table>';
	doToolTip(null, html, false,'center',document.getElementById('PeoplePicker'),'#eee', 210);
}

function CreatePP()
{
	PPShow('');

	if (typeof PPInputsToHide != 'undefined')
	{
		for(i=0; i<PPInputsToHide.length; i++)
			document.getElementById(PPInputsToHide[i]).style.visibility = 'hidden';
	}
}

//  End People Picker
//--------------------------------
//--------------------------------
//--------------------------------
//--------------------------------


//-------------------------------------------------------------------------------------------
//
//
//  leftnav stuff
//
//
//-------------------------------------------------------------------------------------------

function LeftNavClearFilter() {
	deleteCookie('navFilter');
}

var userid;
var navFilter;
function LeftNavLoadCookies() {
	navFilter = getCookie('navFilter') | 0;
	userid = getUserId() | 0;
	if (document.getElementById('navFilterSelect'))
		document.navFilterForm.navFilterSelect.value=navFilter;
}

function LeftNavShowAreaCounts(index) {
	if (aAreas.length>0) {
		 for (i=0; i < aAreas.length; i++)
		 {
		 	var id = aAreas[i][0];
		  	var count = aAreas[i][navFilter+1];
			totalcount = aAreas[i][1];
		 	result = '<span class="small" style="color:#555">(';
		 	if (navFilter!=0 && ( count>0))  {
				result += '<span style="color:red">' + count + '</span>/';
		 	}
		 	result += totalcount + ')</span>';
			row = document.getElementById('leftnav_' + id);
			if (row) row.innerHTML = result;
		 }
	}
}

function LeftNavShowRouteStarsAndRatings(selectedId) {
	if (aRoutes.length>0) {
		 for (route=0; route < aRoutes.length; route++)
		 {
		 	var id = aRoutes[route][0];
		  	var rating = aRoutes[route][1];
		  	var stars = aRoutes[route][2];
		  	var userstars = userRouteScores[id];
		  	var type = aRoutes[route][navFilter+3];
		  	var isSelected = id==selectedId;

		  	starhtml = '';

	 	 	if (userstars)
	 	 	    starhtml += starsHtml(userstars, 'user');
	 	 	else
	 	 	    starhtml += starsHtml(stars, 'leftnav');

			starspan = document.getElementById('leftnavstars_' + id);
			if (starspan) starspan.innerHTML = starhtml;

			result = '';
		  	if (type && navFilter!=0)
		  		result += '<span style="color:red;">'; // start route highlighting
	 	 	result += "<small>" + rating + "</small>";
		  	if (type && navFilter!=0)
		  		result += '</span>'; // end the route highlighting

			routespan = document.getElementById('leftnavroute_' + id);
			if (routespan) routespan.innerHTML = result;

		 }
	}
}


function LeftNavShowFilterNote() {
	labels = ['total', 'Rock', 'Boulder', 'Trad', 'Sport', 'Ice', 'Aid', 'Mixed', 'Alpine', 'Toprope'];
	var html = '';
	if (navFilter != 0) {
		html = '<em><span style="color:red" class="bold">' + labels[navFilter] +' routes are RED</span></em><br />';
	};
	if (document.getElementById('leftnavfilternote'))
		document.getElementById('leftnavfilternote').innerHTML = html;
}


function OnLeftNavShowRoutesSelect(value, id) {
	setCookie('navFilter', value);
	LeftNavDynamicContent(id);
}


function LeftNavDynamicContent(selectedObjectId) {
	LeftNavLoadCookies();
	LeftNavShowFilterNote(); // the big read note saying "Boulder routes are in RED"
	LeftNavShowAreaCounts();	// the ##/## counts on areas (red or not red)
	LeftNavShowRouteStarsAndRatings(selectedObjectId); // route stars and the RED/notRED rating
}

//-------------------------------------------------------------------------------------------
//
//
//  star stuff
//
//
//-------------------------------------------------------------------------------------------

var imgBomb  = new Image;
var imgBombW = new Image;
var imgAvg   = new Image;
var imgAvgY  = new Image;
var imgStarW = new Image;
var imgStarY = new Image;
var imgStarB = new Image;
var imgStarHalfB = new Image;


imgBomb.src   = '/img/stars/bomb.gif';
imgBombW.src   = '/img/stars/bomb_w.gif';
imgAvg.src    = '/img/stars/avg.gif';
imgAvgY.src   = '/img/stars/avg_y.gif';
imgStarW .src = '/img/stars/star_w.gif';
imgStarY.src  = '/img/stars/star_y.gif';
imgStarB.src  = '/img/stars/star_b.gif';
imgStarHalfB.src = '/img/stars/star_b_half.gif';

var starset=0; // each call to "clickableStarsHtml" increments this to create a new starset
var starClickableImgOff = ['', imgBombW, imgStarW, imgStarW, imgStarW, imgStarW ];
var starClickableImgOn  = ['', imgBomb, imgStarY, imgStarY, imgStarY, imgStarY ];
var starNonClickableImg = ['', imgBomb, imgStarB, imgStarB, imgStarB, imgStarB  ];
var starNonClickableUser= ['', imgBomb, imgStarY, imgStarY, imgStarY, imgStarY ];
var starText   = ['', 'AVOID', 'OK', 'GOOD', 'GREAT', 'CLASSIC!'];
var starsetScores = [];         // default scores (when the cursor is moved off a starset, it reverts to this)
var starsetObjectIds = [];      // which route does each starset reference
var redrawStarsetObj = [];      // html object to redraw after wait graphic times out
var redrawStarsetHtml = [];     // saved HTML to redraw with after wait graphic times out
var starsetHotclicks = [];


function starClickableGraphicId(starset, index) {
	return 'starClick' + starset+index;
}

function starClickableClass(index, score) {
	// the class for a clickable score - draws the box if selected
	if (index==score)
	   return 'starSelected';
	else
	   return'starUnselected';
}

function starClickableGraphic(index, score) {
	// the graphic for clickable score (graphic changes if 'index' is less than score - that's the yellow/blue thing)
	// img is off if it's higher than score, or if it's the bomb and score is higher than bomb
	if (index>score || (index==1 && score>1))
		return starClickableImgOff[index];
	else
		return starClickableImgOn[index];
}

function getStarText(score) {
	// the text for a score
	theText = starText[score];
	// the hidden inputs are in case this clickable starset is within a form (and not xml hot)
	if (theText)
	   return "<input type='hidden' name='starscore' value='" + score + "'><small><em>" + theText + "</em></small>";
	else
	   return "<input type='hidden' name='starscore' value=''>";
}

function selectStars(starset, score) {

	if (score==-2)
	   score = starsetScores[starset];

	// display the graphics
	for (i=1;i<=5;i++) {
		star = document.getElementById(starClickableGraphicId(starset, i));
		if (star) {
			star.className = starClickableClass(i, score);
			img = starClickableGraphic(i, score);
			star.src = img.src;
		}
	}

	// and the star text
	text = document.getElementById("startext"+starset);
	if (text) {
       text.innerHTML = getStarText(score);
	}
}

function clickStar(starset, score) {

	// user must be logged in
	if (!CheckLogin("We'll keep track of your score for each route, but you have to sign up so we know who you are."))
		return;

	// set the new 'default' score
	starsetScores[starset]=score;

	// update the display
	selectStars(starset,score);

	// save the html of the star display
	starsetObj = document.getElementById("starset"+starset);
	redrawStarsetHtml[starset] = starsetObj.innerHTML;

	if (starsetHotclicks[starset]) {
		// change to wait graphic
		starsetObj.innerHTML = "<img src='/img/wait_bar.gif'>";
		// and set a timeout for this starset to redraw (will redraw from the saved html)
		redrawStarsetObj[starset] = starsetObj;
		window.setTimeout('redrawStarset('+starset+')',1000);
		// call PHP to actually update the DB
		makeXmlHttpRequest("/scripts/XmlHttpRequest.php?action=saveScore&id="+starsetObjectIds[starset]+"&score="+score);
	}
}

function redrawStarset(starset) {
	// when a user clicks a star, it is changed to a wait graphic - this resets it
	// after a timeout
	redrawStarsetObj[starset].innerHTML = redrawStarsetHtml[starset];
    obj = document.getElementById("startrash"+starset);
    // update trash visibility
	obj.style.visibility= starsetScores[starset]>=1 ? 'visible' : 'hidden';
}

// clickableStarsHtml - this is the star display that allows
// a user to click and set a score
//    objectid - the object's id
//    score - default (starting) score
//    hotclicks - 1/0, 1 means a click calls the XML script to update the score, otherwise this is assumed to be in a form

function clickableStarsHtml(objectid, score, hotclicks) {

	starset++;  // each "clickableStarsHtml" call defines a new starset
    starsetScores[starset]=score; // save the default score (for when the mouse is moved away)
    starsetObjectIds[starset]=objectid; // save the objectid for this starset
    starsetHotclicks[starset]=hotclicks; // "hotclicks" means to do the XML call and update the score...

	html = '<span style="white-space:nowrap;" id="starset'+starset+'" onmouseout="javascript:setTimeout(\'selectStars('+starset+',-2)\', 100);" >';

	// display the stars
	for (i=1; i<=5; i++) {
		starId = starClickableGraphicId(starset, i);
	    className = starClickableClass(i, score);
	    starImg   = starClickableGraphic(i, score);
	    html += "<img style='margin:0; padding:0; border:0' width=12 height=11 class="+className+" id='"+starId+"' onclick='javascript:clickStar("+starset+", "+i+");' onmousemove='javascript:setTimeout(\"selectStars("+starset+", "+i+")\",100);' src='" + starImg.src + "'>";
	}

	// display the text
	thetext = getStarText(score);
	html += '&nbsp;<span id="startext'+starset+'">'+thetext+'</span>';

	// and the trash can
	trashvis = score>=1 ? 'visible' : 'hidden';
	if (hotclicks)
	   html += "<span style='visibility:"+trashvis+";' id='startrash"+starset+"'>&nbsp;<a href='javascript:clickStar("+starset+",0)'><img alt='Clear Score' width='10' height='11' border='0' src='/img/trash.gif' width='10' height='11' ></a></span>";

	html += '</span>';

	return html;
}

// this is for non-clickable stars (generally most cases)
// modes are:
//   'avg' - displayed in blue
//   'leftnav' - displayed in blue
//   'user' - displayed in yellow

function starsHtml(score, mode) {

	html = '';

	score = Math.round(score*10)/10;
	if (score<=0) return '';
	if (score<=1) // for bomb, only show one icon
	   i = score;
	else
	   i = 2; // for stars, begin at first star
	while (i<=score) {
	    if (mode == 'user')
	       starImg = starNonClickableUser[i];
	    else
	       starImg = starNonClickableImg[i];
	    html += "<img width=12 height=11 src='"+ starImg.src + "'>";
	    i++;
	}

	// add a half star if required
	if ((score-Math.floor(score))>0)
	    html += "<img width=12 height=11 src='"+imgStarHalfB.src+"'>";

	return html;
}

// this is the text in the route header (average stars display)
// needs to be in javascript since it is called after the
// user changes a score (in addition to when the route is first displayed)
function starSummaryText(score, votecount, voteslink) {
	html = 'Average: ';
	score = Math.round(score*10)/10;
	scoretext = Math.round((score-1)*100)/100; // no sprintf in jscript? homemade
	if (score<1) return '';
	if (score<1.7)
	   html += 'bomb '+scoretext;
	if (score>=1.7 && score<=2.4)
	   html += 'OK '+scoretext;
	if (score>=2.4)
	   html += scoretext + " stars";
	if (voteslink)
		html += "&nbsp;<a href='" + voteslink + "'>(" + votecount + " votes)</a>";
	else
		html += "&nbsp;(" + votecount + " votes)";
	return html;
}

function rateThis(id, value)
{
	if (value==-1000) return; // ignore 'rate this' listbox value
	var str = 'id=' + id + '&action=rateThis&score=' + value;
	makeXmlHttpRequest("/scripts/XmlHttpRequest.php?"+str)
	document.getElementById('rateThisPage').innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;<img src='/img/wait_bar.gif'>&nbsp;&nbsp;&nbsp;&nbsp;";
	window.setTimeout('redrawRateThis(0)', 500);
}

function redrawRateThis(i) {
    document.getElementById('rateThisPage').innerHTML = "<span style='background-color:#e8f8ed; padding:0 28px; border:1px solid black'><em>Thank You! </em></span>";
}

//-------------------------------------------------------------------------------------------
// homepage photo of the moment stuff
//-------------------------------------------------------------------------------------------

// these functions require aRandomPhotos to be set
// see index.php

var aRandomPhotos = [];
var randomPhotoIndex = -2;
function setPhotoOfTheMoment(offset) {
	if (randomPhotoIndex == -2)
		randomPhotoIndex=Math.floor(Math.random()*aRandomPhotos.length);
	if (!offset)
		offset=0;
	randomPhotoIndex = (randomPhotoIndex + offset + aRandomPhotos.length) % aRandomPhotos.length;

	imguri = aRandomPhotos[randomPhotoIndex][0];
	link = aRandomPhotos[randomPhotoIndex][3];
	height = aRandomPhotos[randomPhotoIndex][4];
	getEl('photoOfTheMomentPrestrip').innerHTML = '<div><a href="' + link + '"><img style="border-top:1px solid #000000;" src="http://www.mountainproject.com' + imguri + '" width=220 height='+height+' border=0 /></a></div>';

	title = aRandomPhotos[randomPhotoIndex][1];
	thelocation = aRandomPhotos[randomPhotoIndex][2];
	getEl('photoOfTheMomentBody').innerHTML = '<small>' + title + '<br />' + thelocation + '</small>';
}

//-------------------------------------------------------------------------------------------
// functions to support inline images for posts
// these functions make it 'smart'... it'll load the
// image in the background and then display it sized appropriately
// with a maximum width of 450.  For images bigger than that, it'll
// link to the original image
//-------------------------------------------------------------------------------------------

var inlineImageCount=0; // incremented for each image
var inlineImages = [];  // the array of Image objects

function showInlineImage(imgsrc) {

        inlineImageCount++;
        document.write('<span id="inlineimage_'+inlineImageCount+'" class="img-shadow" style="padding:0px 3px;"><small>LOADING IMAGE...</small></span><br clear="all" />');

        // load the images
	    inlineImages[inlineImageCount] = new Image;
        inlineImages[inlineImageCount].src = imgsrc;

       	// one loaded, show it
        inlineImages[inlineImageCount].onload = new Function("drawInlineImage(" + inlineImageCount+");" );
        if (inlineImages[inlineImageCount].width>0) {
        	// alternate show method in case image is already loaded.. required in IE or it won't
        	// show when a page is reloaded
        	drawInlineImage(inlineImageCount);
        }
}

function drawInlineImage(imageNumber) {
        pix = inlineImages[imageNumber];
        var maxW = getWinWidth()-200;
        var maxH = getWinHeight()-100;
        // but not too small
        if (maxW < 450)
        	maxW = 450;
        if (maxH < 350)
        	maxH = 350;

        var w=pix.width;
        var h=pix.height;
        var notes='<br>changes to image:';
        if (w > maxW)
        {
                f=1-((w - maxW) / w);
                w=w * f;
                h=h * f;
                notes += '<br>resized width to '+w+' ';
        }
        if (h > maxH)
        {
                f=1-((h - maxH) / h);
                w=w * f;
                h=h * f;
                notes += '<br>resized height to '+h+' ';
        }
        bordersize = (w==pix.width && h==pix.height) ? 1 : 3;
        imghtml = '<img border=' +bordersize +' alt="image" src=' + pix.src + ' width=' + w + ' height=' + h + '>';
        if (w!=pix.width || h!=pix.height) {
                imghtml = '<a href="' + pix.src +'">' + imghtml + '</a>';
        }
        imgspan = document.getElementById('inlineimage_'+imageNumber);
        if (imgspan) {
        	imgspan.style.border='';
        	imgspan.style.padding='';
        	imgspan.innerHTML = imghtml;
        }
}

//----------------------------------------------------------------
// comment visibility switcher
//----------------------------------------------------------------


function onShowCommentTypeChange(value, ccount) {
	for (i=1;i<=ccount;i++) {
      convcomment = document.getElementById('cm_conv'+i);
	  thecomment=convcomment;
	  betacomment=null;
      if (!convcomment) {
		betacomment = document.getElementById('cm_beta'+i);
		thecomment=betacomment;
      }
      if (!thecomment) continue;
      if (value=='all') {
      	thecomment.className='comvis';
      }
      else {
      	if (value=='beta')
      		thecomment.className=(betacomment ? 'comvis' : 'comhid');
      	if (value=='conv')
      		thecomment.className=(convcomment ? 'comvis' : 'comhid');
      }
	}
}


//----------------------------------------------------------------
// object browser
//----------------------------------------------------------------

function objectBrowser(startid) {
	var width=440; var height=440;
	// center it
	var w = 1024, h = 768;
	if (document.all || document.layers)
	{
		w=eval("scre"+"en.availWidth"); h=eval("scre"+"en.availHeight");
	}

	var leftPos = (w/2-width/2), topPos = (h/2-height/2);
	// open it
	ww=window.open('/scripts/ObjectBrowserPopup.php?startid='+startid, "objectbrowser", "width="+width+",height="+height+",top="+topPos+",left="+leftPos+",toolbar=no,status=no,menubar=no,directories=no,resizable=yes");
	ww.focus();
}

//----------------------------------------------------------------
// content flagging
//----------------------------------------------------------------

function flagContent() {
	return confirm("Flag this post as inappropriate?\n\nNOTE: This is not for frivolous complaints or retaliation. Abuse of this tool will result in account suspension.");
}