function buildCartUrl() {
	var link = 'http://' + dev_url + 'results/';
	if (typeof(window.location.hash != 'undefined') && window.location.hash) 
		link += window.location.hash + '&view=cart';
	else link += '#view=cart';
	return link;
}


window.onload = function() {
	debug('hello ie we are onloading');
	Event.observe('leftcontent','click',function(event) {
		user_click_flag = true;
		updateHashPrefs();	
	});	
	Event.observe('form1', 'click', function(event) {
		user_click_flag = true;
		updateHashPrefs();	
	});

	// should the divs be redrawn?
	// if on load there is already a hash then yes
	getHashPart('prefs');  // this will set any prefs that were passed thru url, overriding the defaults
//	load2();
	debug('================ ' + next_divs + '==================');
	
	setInterval(load2, 1000);
	
}

	
	


function hashTracker(this_hash) {
//alert('going');
	new Ajax.Request(
			"http://" + dev_url + "app/scripts/hash_tracker.php?" + stripLeadingHash(this_hash),  
			{
				method: "GET",
				onComplete: function() {
//					alert('gone');
			}});
}

// this watches the open widget spinners and 
new PeriodicalExecuter(function() {
        if (typeof(next_divs)=='undefined') return;
	for(var i=0;i<next_divs.length;i++) {
		var div = next_divs[i];
		var widgets = mult_widget_post_names[div];
		for (var j=0;j<widgets.length;j++) {
			var widget = widgets[j];
			if (typeof(Ajax.activeWidgetRequest[widget]) == 'undefined') Ajax.activeWidgetRequest[widget] = -1;
			if (Ajax.activeWidgetRequest[widget] == 0) {
				// no  more active requests, hide the loading indicator
				toggleOpenWidgetSpinners(widget,0);
				// so we don't pick it up again
				Ajax.activeWidgetRequest[widget] = -1;
				}}}}, 1);

// set the cache every few seconds
new PeriodicalExecuter(function() {
	// set the cache
		if (!typeof(last_cached_get)=='undefined') last_cached_get = load_get;
		if (load_get && (load_get != last_cached_get)) {
			last_cached_get = load_get;
			new Ajax.Request(
				"http://" + dev_url + "app/scripts/homepage/set_cache.php?" + load_get, 
				{ method: "GET"
				});
	}},3);
	
// gets fadey mult selections
function getValidMultsJSON(div,widget_arr) {
		if (disable_getValidMultsJSON) { return; }
		if (!load_get) {
			info('calling getvalidmultsjson from itself ' + div + ' ' + widget_arr);
			getValidMultsJSON(div,widget_arr);
			return;
		}
		var widgets = new Array();
		// only request widgets that are actually in this div and are mult widgets
		for (var i=0;i<widget_arr.length;i++) {
			var widget = widget_arr[i];
			// is this really a mult widget?
			if (in_array(widget,mult_widget_post_names[div])) {
				//yes, add it to the widgets array
				widgets[widgets.length] = widget;
				toggleOpenWidgetSpinners(widget,1);  // turn on the spinner
				// activate the counter
				if (Ajax.activeWidgetRequest[widget] < 0) Ajax.activeWidgetRequest[widget] = 0;
				Ajax.activeWidgetRequest[widget]++;
			}
			else debug( widget + ' is not a mult widget in ' + mult_widget_post_names[div]);
		}
		
		if (!widgets.length) {
			debug('widgets had no length');
			return;
		}	
		var widget_str = widgets.join(',');

		info('calling getvalidmultsJSON for ' + widget_str); 
	
		// fill in the default div
		new Ajax.Request(
			"http://" + dev_url + "app/scripts/homepage/div_json.php?" + "div=" + div + '&' + load_get + '&widgets=' + widget_str,  
			{
				method: "GET",
				onComplete: function() {
				},
				 onSuccess: function(transport, json) {
					 	
						// incoming from div_json
						if (json.valid_mults) {
							valid_mults 		= json.valid_mults;
							var invalid_mults 	= json.invalid_mults;
							var div     		= json.div;
	
							// clear them for the next thread
							json.valid_mults 	= null;	
							json.invalid_mults 	= null;	
							json.div 		 	= null;
							
							if (valid_mults.length) {
								for (var i=0;i<valid_mults.length;i++) {
									var this_id = valid_mults[i];
									if ($(this_id)) {
										$(this_id).style.color      = 'black';
									}
								}							
							// change to fadey invlid mults
							if (invalid_mults.length) {
								// this value is invalid, fade it.
								for (var j=0;j<invalid_mults.length;j++) {
									var this_id = invalid_mults[j];
									if ($(this_id)) {
										// http://www.w3schools.com/html/html_colorsfull.asp
										$(this_id).style.color 			 = '#B0B0B0';
									}	
								}	
							}
							for(var i=0;i<widgets.length;i++) {
								var widget = widgets[i];
								Ajax.activeWidgetRequest[widget]--;
							}
						}
					}
			 }
		}
	);
	
}

// user clicks 'add range' this function draws it
	function addRange(post_name_no_num,value1,value2,has_named_ranges) {
		// range widgets are always named with the suffix 1
		var widget_container = post_name_no_num + '1_widget';
		// unless they are single column range widgets in which case there is no numeric suffix
		if (!$(widget_container)) widget_container = post_name_no_num + '_widget';
		var range_fields = rangeHTML(post_name_no_num,value1,value2,has_named_ranges); 
		new Insertion.Bottom(widget_container, range_fields);
	}
	

	function createMenu(next_divs,div_titles,const_tables) {
		var menu = '\<table class = "menu" width = "100%">';
		if (!const_tables) const_tables = new Array();
		for(var i=0;i<next_divs.length;i++) {
			var div       	= next_divs[i];
			var div_title 	= div_titles[i];
			
		menu += '\<tr>' + 
				'\<td id = "menu_'+div+'_checkbox" class = "menu_'+div+'" '+ 
				'width = "20" valign = "middle">';
		
		if(in_array(div,const_tables)) {
			// draw the checkmark
			menu += '\<span class = "checkflag_menu popup" ' +  
					 'title = "Parameters are constrained">\</span>';
		} else {
			menu += '\<p>&nbsp;\</p>';
		}		
		menu += '\</td>\<td id = "menu_'+div+'" class = "menu_'+div+'" align = "left">' + 
				'\<a href = "" id = "link_'+div+'" class = "menu" ' +  
						'onmouseover = "menuMouseOver(\''+div+'\')" ' + 
						'onmouseout  = "menuMouseOut(\''+div+'\')" ' + 
						'onclick="default_div = \''+div+'\'; ' + 
							 'menuStyle(); ' + 
							 'hideAll(\''+div+'\'); ' + 
							 'Element.show(\''+div+'\'); ' + 
							 'return false;">'+div_title+'\</a>\</td>\</tr>';
	} 
	
	menu += '\</table>';
	menu += '\<div title = "menu_hints" id = "menu_indicator" style = "text-align:center">' + loading(); + '\</div>';
	$('leftcontent').innerHTML = menu;
	menuStyle();
	Effect.Fade('menu_indicator', {duration:1});
}

function submitSearchForm() {

	if (window.location.hash) {
		$('form1').action = 'results/' + window.location.hash;  
		$('form1').submit();
	}
	else alert("Please make a selection");
	
}

// state = 1 shows the msg state = 0 hides it
function divAlertDismissHandler(div,state) {
	if (state) {
		Element.show('div_alert_text_' + div);  
		Element.hide('dismissed_div_opener_' + div); 
		$('div_alert_' + div).style.width = '20%'; 
		$('div_alert_' + div).style.fontSize = '100%'; 
		$('div_alert_' + div).style.whiteSpace = 'normal';
		Element.show('div_alert_hide_' + div);
	} else {
		Element.hide('div_alert_text_' + div); 
		Element.show('dismissed_div_opener_' + div); 
		Element.hide('div_alert_hide_' + div);
		$('div_alert_' + div).style.width = '8%'; 
		$('div_alert_' + div).style.fontSize = '90%';
		$('div_alert_' + div).style.whiteSpace = 'nowrap';
	}
}
var planets_selected  = new Array();
// opens appropriate target list
function planetClickHandler(post_name,no,label) {
	var element_id = 'input_' + post_name + no; 								
	if (!$(element_id)) return;
	if($F(element_id)) {
		planets_selected[planets_selected.length] = label;  // keep track of the selected planets
		if ( $('targets_' + label) && $('targets_' + label).style.display == 'none') {	
			// this selection is checked, and the corresponding target list is still hidden.  unhide.. 
			if ($('targets_' + label)) Effect.BlindDown('targets_' + label, {duration:.5}); 
			if ($('targets_' + label + '_close')) Element.show('targets_' + label + '_close');
			if ($('targets_' + label + '_open')) Element.hide('targets_' + label + '_open');
		}	
	}
	else {
		/* here you are referring to a post name that might have been reset! */
		// they have de-selected this planet, 
		// if the target_name widget is closed then close the corresponding target group
		if ($('targetname_hide_label') && $('targetname_hide_label').style.display == 'none') {
			// the close button is not showing so the widget must be closed, reverse the above
			if ($('targets_' + label)) Element.hide('targets_' + label, {duration:.5}); 
			if ($('targets_' + label + '_close')) Element.hide('targets_' + label + '_close');
			if ($('targets_' + label + '_open')) Element.show('targets_' + label + '_open');
		}
	}
}
function errorlog(message) {
	t = new Date();
	error(message + ' ' + t.getMinutes() + ':' + t.getSeconds());
}
// an array of param names and the number of range pairs that have
// been opened by the user clicking on 'add range'
function rangeHTML(post_name_no_num,value1,value2,has_named_ranges) {
	post_length = 75;
	var size        = 15;
	var post_name_min = post_name_no_num + '1';
	var post_name_max = post_name_no_num + '2';
	if (!range_start_num[post_name_min]) {
		range_start_num[post_name_min] = '0';
	}
	else {
		// turn the string '0' into a number so we can increment it..
		if (range_start_num[post_name_min] == '0') range_start_num[post_name_min] = parseInt(range_start_num[post_name_min]);
		range_start_num[post_name_min] = range_start_num[post_name_min] + 1;
	}
	if (!range_start_num[post_name_max]) {
			range_start_num[post_name_max] = '0';
	}
	else {
		if (range_start_num[post_name_max] == '0') range_start_num[post_name_max] = parseInt(range_start_num[post_name_max]);
		range_start_num[post_name_max] = range_start_num[post_name_max] + 1;
	}
	var min_num = range_start_num[post_name_min];
	var max_num = range_start_num[post_name_max];
	var id_min = post_name_min + min_num;
	var id_max = post_name_max + max_num;
	// keep a log of range fields we added, for use by clearAll
	added_ranges[added_ranges.length] = id_min;
	added_ranges[added_ranges.length] = id_max;
	var range_html  = '<div id = "range_fields_' +  id_min + '"><span class = "range_fields" style =  "white-space:nowrap;">min:&nbsp;\<input type = "text" id="input_' 
						+ id_min + '" class = "range" maxlength = "' 
						+ post_length + 
						'" size = "' + size + 
						'" 	name = "' + post_name_min + '"' + 
						'value = "' + value1 + '"' +  
						'onclick  = "userSelectionFlag();" 	' + 
						'onblur = "monitorTextFields(\'' + post_name_no_num + '\',\'1' + min_num + '\');" 	' + 
						'onchange = "updateHash(); indicatorHandler(\''+ post_name_no_num + '\',\'1' + min_num + '\',$F(this),\'RANGE\'); "' +
						'onkeydown="if (event.keyCode == 13) {updateHash(); return false; }"' + 
						'</span>';
		range_html	+= '<span  class = "range_fields" style = "white-space:nowrap;">max:&nbsp;<input type = "text" id="input_' + id_max + 
						'" class = "range"	maxlength = "' + post_length + '"	' + 
						'size = "' + size + '"' + 
						'name = "' + post_name_max + '"' + 
						'value = "' + value2 + '"' + 
						'onclick = "userSelectionFlag();"	' + 
						'onblur = "monitorTextFields(\'' + post_name_no_num + '\',\'2' + max_num + '\');"	' + 
						'onchange = "updateHash(); indicatorHandler(\'' + post_name_no_num + '\',\'2' + max_num + '\',$F(this),\'RANGE\'); "' + 
						'onkeydown="if (event.keyCode == 13) {updateHash(); return false; }"' + 
						'</span>';
						range_html += '<a href = "" title = "remove this range" onclick = "removeRange(\'' + id_min + '\',\'' + id_max + '\',\'' + min_num + '\',\'' + post_name_no_num + '\'); ';
						range_html += '  return false;">[<span  style = "color:red" >x</span>]</a>';
//			if(has_named_ranges) {  // ths is cut and this should show for all ranges
			var named_range_id = 'look_up_range_'+post_name_no_num+'_'+ min_num;
			var named_range_link = '\<a href = "" title = "click for more information" onclick = "namedRangeHandler(\'' + post_name_no_num + '\',\'' + min_num + '\'); return false;">[...]\</a>';
			if ($(named_range_id)) {
				// this range was already drawn, add the link into it
					$(named_range_id).innerHTML = named_range_link;
			} else {
				// add the named range link to this widget
				range_html += '<span id = "' + named_range_id + '">' + named_range_link + '</span>';
				// add some space to the add_range, but only if the widget isn't open
			}
			range_html += '</div>';
		return range_html;
}
	var range_start_num_clicked;
	function namedRangeHandler(post_name_no_num,min_num) {
		new Element.scrollTo('banner');
//		alert('this ' + post_name_no_num + ' ' + post_name_min);
		range_start_num_clicked = min_num;
		getNamedRanges(post_name_no_num);
	}
function removeRange(id_min,id_max,min_num,post_name_no_num) {
		// remove any errors on this field
		highlightWidgetError(post_name_no_num + '1_widget',0);
		var post_name_min = post_name_no_num+'1';
		var reload = false;
		if ($F('input_' + id_min) ||  $F('input_' + id_max) ) {
			reload = true;
		}
		if (min_num != '0') {							
			Element.remove('range_fields_' +  id_min);
		}
		else {
			Field.clear('input_' + id_max ); 
			Field.clear('input_' + id_min); 
		}	
		// single column range fields don't have the trailing number, so we have to try 2 ways to get this working
		if ($(post_name_min+ '_widget')) {
			var range_elements = $(post_name_min+ '_widget').getElementsByClassName('range_fields');
		}
		else {
			var range_elements = $(post_name_no_num+ '_widget').getElementsByClassName('range_fields');
		}
		if (range_elements.length < 3) {
	}
		if (reload) updateHash(); 
}




/* we are disabling this for now, this is the live ajax search feature 
		 of the string search fields*/ 
function createAC(post_name) {
}
// hide all but one div	 
function hideAll(no_hide){
		Element.show(no_hide); 
		for (var i = 0; i<all_divs.length; i++){
			if (all_divs[i] != no_hide) {
				Element.hide(all_divs[i]); 
			}
		}
}
// handles whether widgets are open or closed 
function widgetHandler(this_div) {
		// all the post_names in this div
		var names = post_names[this_div];
		for (var i=0;i<names.length;i++) {
			// sometimes we pull out a widget that has been turned off
			// check that this widget dom element exists before we do 
			// anything with it..
			// if this widget is in the open_widgets array
			if (in_array(names[i],open_widgets)) {
				//open it
				toggleWidget(names[i],this_div,1);
			}
			else {
				// close it
				toggleWidget(names[i],this_div,0);
			}	
		}		
}
// draws a div and triggers ajax call to get valid mults
function getDiv(div) {

		// fill in the defaul div
		new Ajax.Updater(
			div,
			"http://" + dev_url + "app/scripts/homepage/div.php?div=" + div + '&' + load_get, {	
				method: "get",
				evalScripts:true,
				onComplete: function() {
					if (redraw) {  
						divs_rendered[divs_rendered.length] = div;
//						info('tracking divs rendered::  ' + divs_rendered);
//						info('actual divs:: ' + next_divs);
						if (areArraysEqual(divs_rendered,next_divs)) {  // unset redraw flag after all divs are rendered
							redraw = false; 			
							divs_rendered = [];
//							error('unsetting redraw flag and emptying divs rendered'); 
					}}
						
							if ($('spinner_'+div)) Element.hide('spinner_'+div);
							widgetHandler(div);
							$(div).style.textAlign = "left";

							if (!disable_getValidMultsJSON) {
								var widget_arr = open_widgets;
								info('calling getvalidmultsjson from getDiv ' + div + ' ' + widget_arr);
								getValidMultsJSON(div,widget_arr); }	
					
					// oh behave! 
					Event.observe( 'div_alert_hide_'+div, 'click', function(event) { 
							div_alerts_dismissed[div_alerts_dismissed.length] = div;  
							divAlertDismissHandler(div,0);  });
					Event.observe('dismissed_div_opener_'+div,'click',function (event) { 
							divAlertDismissHandler(div,1); });
					new Draggable('div_alert_'+div); 
					
					}});
}
function getNamedRanges(post_name_no_num) {
		$('named_ranges_text').innerHTML = loading();
		Effect.Appear('named_ranges_container',{duration:.2});
		Effect.Appear('named_ranges_text',{duration:.2});
		get = userSelections();
		warn(get);
		/** turning this caching off for now **/		
		/**
		if (named_range_collection[post_name_no_num]) {
			$('named_ranges_text').innerHTML = named_range_collection[post_name_no_num];
		}	
		**/
// 		else {		
			t = new Date();
			// fill in the defaul div
			new Ajax.Updater(
				'named_ranges_text',
				"http://" + dev_url + "app/scripts/homepage/named_ranges.php?"+ get,  
				{
					 method: "post",
					 postBody:"field=" + post_name_no_num + '&' + get + '&range_num_clicked=' + range_start_num_clicked,
					onComplete: function() {
						named_range_collection[post_name_no_num] = $('named_ranges_text').innerHTML;
						t = new Date();
					}	
				}
			);			
		// }
}
function namedRangeInnerSelected(field,value1,value2) {
		if (field == 'both') {
			$('named_range_min').value = value1;
			$('named_range_max').value = value2;
			new Effect.Highlight('named_range_min', {duration:1});
			new Effect.Highlight('named_range_max', {duration:1});
		} else if (field == 'min') {
			$('named_range_min').value = value1;
			new Effect.Highlight('named_range_min', {duration:1});
		} else if (field == 'max') {
			$('named_range_max').value = value2;
			new Effect.Highlight('named_range_max', {duration:1});
		}
	}
function namedRangeSelected(post_name_no_num) {
	   // this only because range_start_num takes post_name_no_num as an attribute
	   var post_name_min = post_name_no_num + '1';
	   if (!range_start_num_clicked) range_start_num_clicked = '0';
	   var range_id1 = 'input_' + post_name_no_num + '1' + range_start_num_clicked;
	   var range_id2 = 'input_' + post_name_no_num + '2' + range_start_num_clicked;
	   // set the value of the range field to the user selected value
	   $(range_id1).value = $('named_range_min').value; 
	   $(range_id2).value = $('named_range_max').value; 
	   // alert the indicator displays
	  indicatorHandler(post_name_no_num,'1' + range_start_num_clicked,$(range_id1).value,'RANGE');
	  indicatorHandler(post_name_no_num,'2' + range_start_num_clicked,$(range_id2).value,'RANGE');
	   // hide the named ranges popup, reset it to it's default display
	   Effect.Fade('named_ranges_container',{duration:.2});
	   $('named_ranges_text').innerHTML = '\<div style = "text-align:center">Looking up named ranges\<br>' + loading() + '\</div>'; 	   
	   // make sure the units selector is set back to it's first selection (the default)
	   if ($('units_' + post_name_no_num)) {
		   // there is a units selector..
		   $('units_' + post_name_no_num).value =  $('units_' + post_name_no_num).options[0].value;
	   }
	   new Effect.Highlight(range_id1, {duration:2});
	   new Effect.Highlight(range_id2, {duration:2});
	   // reload the results
	   updateHash();
}	
function getDisabledWidgetsJSON(div) {
}
function toggleOpenWidgetSpinners(widget,state) {
	if (disable_getValidMultsJSON) state = 0;
		if (!state) {
			// only turn it off if there are no requests
			// set the final next divs
			if ($('spinner_' + widget)) {
				Effect.Fade('spinner_' + widget, {duration:1.3});
			}
		} else { // state = 1;
			// spinners should show if widget is open
			// widget is open, show spinner if there is one
			if ($('spinner_' + widget)) {
				Effect.Appear('spinner_' + widget, {duration:div_loading_duration});
//					new Effect.Highlight('spinner_' + post_name, {duration:.5});
			}
		}
}	
function getRangeEndpoints(post_name) {
		var spinner = loading();
		get = userSelections();
		$('dummy').innerHTML = null;
		$('alert_text').innerHTML = '<div style = "text-align:center;">Looking up range info, please wait.<br>' + spinner + '</div>';
		Element.show('alert_container');
		Element.show('alert_text');
		//updateHash();
		new Ajax.Updater(
				"dummy", 
				"http://" + dev_url + "app/scripts/homepage/range_endpoints.php", 
				{
				 method: "post",
				 postBody:"field=" + post_name + '&' + load_get ,
				 onComplete: function() {
		
					 warn('completed range endpoints');
						 if ($('dummy').innerHTML) {
								$('alert_text').innerHTML = $('dummy').innerHTML; 
						 }
						 else
						 {
							 // nothing came back and no error, hide the 
							 //bookmark returned nothing, error message 
							 $('alert_text').innerHTML = "Sorry, \<br> we are experiencing a technical problem<br>and cannot retrieve endpoints\<br>please try again later.";
						 }
					}
				}
			);
	}
// launches getValidMultsJSON or getDiv if needed, skips the default div
function getNextDivs(request) {
		new Ajax.Request(
			"http://" + dev_url + "app/scripts/homepage/next_divs_JSON.php", 
			{	method: "post",
				postBody:load_get,
			 	 onComplete: function(transport, json) {
					if (request < Ajax.lastRequestNo) { return; }
					if (!json.next_divs) return;
						
					var old_next_divs 		= next_divs;	
					next_divs 				= json.next_divs;
					var new_div_titles 		= json.div_titles;
					var new_const_tables 		= json.const_tables;
					
					// draw the menu
					createMenu(next_divs,new_div_titles,new_const_tables);
				
					if (!in_array(default_div,next_divs) || redraw) {
						info('drawing div ' + default_div + 'redraw is ' + redraw);
						getDiv(default_div); 
						Element.show(default_div); } 
							
					// look at each new div and see if its div needs to be drawn or is drawn already
					for (var i=0;i<next_divs.length;i++) {
						var this_div  = next_divs[i];
						if (this_div != default_div) { // we already did the default div
							if (!in_array(this_div,old_next_divs)  || redraw){
								// this is a new div was not there before
								getDiv(this_div); 
							} 
						}
						else { // same old div, refetch its mult info
								if (!disable_getValidMultsJSON) {
									widget_arr = open_widgets;
									info('calling getvalidmultsjson from getnextdivs ' + this_div + ' ' + widget_arr);
									getValidMultsJSON(this_div,widget_arr);
				 					}}}
								
					// are there any divs that were drawn before but are 
					// no longer valid?  replace them with a  spinner
					for (var i=0;i<old_next_divs.length;i++) {
						if (!in_array(old_next_divs[i],next_divs)) {
							$(old_next_divs[i]).innerHTML = loading();
						}}
						
						json.next_divs = null;
					}});
}			
function userSelections() {
			// user selections
			var all = Form.serialize($('form1'));
			return trimSerializedFormString(all);
}





// removes form elements with no values from the all string
// this function also replaces spaces with + 
// if value not part of a param that is found in var no_space_replace
function trimSerializedFormString(all) {
		var all_arr = all.split('&');
		var new_all_arr 						= [];
		var selections 							= {'params':[], 'serialized':[]};
		var string_selects 					= {'params':[], 'serialized':[]};
		var units 									= {'params':[], 'serialized':[]};
		// this is a little hack that probably belongs in function updateHash()
		// we take the referring page when the page loads, then the first time
		// we sweep the form with this function we unset it.  That way we can 
		// tell whether this is the first instance of updateHash() or whether the user 
		// has been clicking around.. 
		if (referrer) {
			var first_call_to_load = true;
			referrer = null;
		}
		// loop through every field
		for (var i=0;i<all_arr.length;i++ ) {
			var input = all_arr[i];
			var input_split = input.split("=");  
			if (input_split[1]) {  	
				// this form field has a value
				// determine if this field is part of the units or string_selects array
				if (input_split[0].search('string_selects') > -1) {
						// this field is a string_select field'
/**
						var trim1 = input_split[0].search("%5B") + 3;  // we want to the end of the "%5D" so add 3
						var trim2 = input_split[0].search("%5D");
						string_selects['params'][i] = input_split[0].substring(trim1,trim2);
**/
						var string = input.replace("%5B","/");
						string = string.replace("%5D","/");
						string = string.replace('%20%20','+');  // replacing spaces with +
						string = string.replace('%20','+');
						string_selects['serialized'][i] = string;

						var param_arr = string.split("/");
						//string_selects['params'][i] = input_split[0].substring(trim1,trim2);
						string_selects['params'][i] = param_arr[1];

						
						//	debug(param.substring(trim2));
				}
				else if (input_split[0].search('units') > -1) {
					// this field is a units field
						var string = input.replace("%5B","/");
						string = string.replace("%5D","/"); // replacing brackets with slash
						string = string.replace('%20%20','+');  // replacing spaces with +
						string = string.replace('%20','+');
						units['serialized'][i] = string;
						var param_arr = string.split("/");
						//string_selects['params'][i] = input_split[0].substring(trim1,trim2);
						units['params'][i] = param_arr[1];

						
					/**
						units['serialized'][i] = input_split.join("=");
						var trim1 = input_split[0].search("%5B") + 3;  // we want to the end of the "%5D" so add 3
						var trim2 = input_split[0].search("%5D");
						units['params'][i] = input_split[0].substring(trim1,trim2);
					**/	
				}	
				else {
					// now for user selections
						selections['serialized'][i] = input_split.join("=");
						var trim1 = input_split[0].search("%5B") + 3;  // we want to the end of the "%5D" so add 3
//						var trim2 = input_split[0].search("%5D");
						selections['params'][i] = input_split[0]; //.substring(trim1,trim2);
						if (!in_array(input_split[0],no_space_replace))  {
							// want to replace spaces here with + sign
							selections['serialized'][i] = selections['serialized'][i].replace('%20%20','+');
							selections['serialized'][i] = selections['serialized'][i].replace('%20','+');
						}	
						new_all_arr[new_all_arr.length] = selections['serialized'][i];
						debug(selections['serialized'][i]);
				}
			} // end if input_split value
		}
		// now check the units and string_selects arrays and if they have corresponding selections they will be kept		
		for(var i=0;i<units['params'].length;i++) {
			var param = units['params'][i];
			// a field with units might have a numeric suffix in the selections array which 
			// is not reflected in the units array..
			if (param && (in_array(param,selections['params'])
									|| in_array(param+'1',selections['params'])
									|| in_array(param+'2',selections['params']))
				) {
					// this is the units for a field with a value, keep it
					new_all_arr[new_all_arr.length] = units['serialized'][i];
					debug(units['serialized'][i]);
			}
		}
		for(var i=0;i<string_selects['params'].length;i++) {
			var param = string_selects['params'][i];
				
			if (param && in_array(param,selections['params'])) {
					// this is the units for a field with a value, keep it
					new_all_arr[new_all_arr.length] = string_selects['serialized'][i];
	//				debug(string_selects['serialized'][i]);
			}
		}
		var new_all = new_all_arr.join('&');
// 		error('new all: ' + new_all);
		// if this is not the first call to load this page (meaning they are coming in 
		// from another page) and there are no selections
		// that means the user deselected all their selections
		// then send along the order to reset the form
		if (selections['params'].length<1 && !first_call_to_load) 
			{ 
				new_all += 'update=reset';
			}
		return new_all;
}


// hash is like planet=saturn&target=pan&target=pandora 
// notice it has multiple values for certain params, we want to turn that style 
// into having them be comma deliminted in the url 
// like planet=saturn&target=pan,pandora
// this funtion combines duplicates in the url string to make them a comma delimited string
function combineParams(hash) {
	var hash_arr = hash.split('&');	// original hash as an array
	var new_hash_arr = [];			// holds new hash values as an arr
	var params = [];						// holds names of constrained params
	
	var temp_hash_arr = [];			// intermediate array step thingy 
	for(var i=0;i<hash_arr.length;i++) {
	//	document.write(hash_arr[i] + "<br>");
		var term 		= hash_arr[i]; // q = v
		var pair 		= term.split('='); 
		var param 	= pair[0];	  // q
		var value 		= pair[1];  // v
		if (!in_array(param,params)) {
			temp_hash_arr[param] = value;
			params[params.length] = param;
		}
		else {
			temp_hash_arr[param] += ','+value;
		}
	}
	// temp hash array holds params in the array keys 
	// now we turn it into a numerically indexed array holding the param=value pairs
	for(var i=0;i<params.length;i++) {
		param = params[i];
		value = temp_hash_arr[param];
		new_hash_arr[new_hash_arr.length] = param + '=' + value;
	}
	return new_hash_arr.join('&');
}	

// sets the hash
function updateHash() {
	user_click_flag = true;
	Form.Element.disable('submit_button'); 
	var get = userSelections(); // reads the form returns serialized string

//	window.location.hash = escape(get);
	var prefs = getHashPart('prefs')
	var new_hash = combineParams(get);
	if (prefs) new_hash += '&'+ prefs;
	window.location.hash = new_hash;
	Form.Element.enable('submit_button'); 
	new Effect.Highlight('submit_button', {duration:2});
}

/* this is the answer */
// take app state prefs and put them in the url
function updateHashPrefs() {
	var selections = getHashPart('selections');
	var prefs = 'tab='+default_div+'&open='+open_widgets;
	if (prefs != last_prefs) {
		var new_hash = ''
		if (selections) new_hash += selections + '&';
		if (prefs) new_hash += prefs;
		window.location.hash = new_hash;
	}	
}

// returns either 'selections' or 'prefs' from the hash
// if returning 'prefs' also sets the prefs
function getHashPart(part) {
	var hash = stripLeadingHash(window.location.hash);
	if (!hash) {
		return;
	}
	if (hash.search('&') > -1) { 
		var pairs = hash.split('&');
	}
	else var pairs = [hash];
	var result_arr = [];  // the new set of pairs that will not include the result_table specific session vars 
	for (var i=0;i<pairs.length;i++) {
		var pair 	= pairs[i].split('=');
		var param = pair[0];
		var value 	= pair[1];
		if (!param) continue;
		if (part=='selections' && !in_array(param,hash_params)) {
			result_arr[result_arr.length] = param + '=' + value;
		} else if (part=='prefs' && in_array(param,hash_params)) {
			result_arr[result_arr.length] = param + '=' + value;
			if (param == 'open') open_widgets = value.split(',');
			if (param == 'tab')   default_div = value;
			// other params with matching url names use  window[param] = value;
		}	
	}
	if (result_arr) return result_arr.join('&');
}


var user_click_flag = true;  // this means take the state from the app state and transfer it to the url, on page load and when user is clicking 
var load_get = '';
var last_selections = 'dummy';
var last_prefs;
// this is the new load func set to a timer by onload
// this is the first ajax call for any query
function load2() {

	var current_selections = '';
	var current_prefs = '';

	// look at the hash
	current_selections 	= getHashPart('selections');
	current_prefs		= getHashPart('prefs');

// debug('click flag: ' + user_click_flag + ' current_prefs ' + current_prefs + ' last_prefs ' + last_prefs);
//	debug(user_click_flag);
	
	if (!user_click_flag && current_prefs && last_prefs && current_prefs != last_prefs) {
		error('reacting to new prefs in the url since: ');
		error('click flag: ' + user_click_flag + ' current_prefs ' + current_prefs + ' last_prefs ' + last_prefs);
		
		// react to new prefs
		hideAll(default_div);
		for(var i=0;i<next_divs.length;i++) {
			var this_div = next_divs[i];
			widgetHandler(this_div); /* this might be too slow find out of can detect first */
		}
	}
	last_prefs 		= current_prefs;
	
	if (current_selections==last_selections) { 
		user_click_flag = false; 
		return; }  	// if selections haven't changed no need to call the server
		
	info(' going to load ');
	last_selections 	= current_selections;
	
	if (!user_click_flag) {
		 // url changed without user clicking, we will redraw the divs, show loading indicators
		 error('URL CHANGED NO CLICKS redrawing divs');
		 redraw = true;
		 for(var i=0;i<next_divs.length;i++) {
			 var this_div = next_divs[i];
			 $(this_div).innerHTML = loading(); }}
	 
	user_click_flag = false;

	warn('redraw = ' + redraw); 

	if (window.location.hash) hashTracker(window.location.hash);
	new Effect.Highlight('result_count', {duration:2});
	$('result_heading').innerHTML = "Updating";
	// start spinner in result count gui
	$('result_count').innerHTML    = loading();
	
	Ajax.lastRequestNo++;
	load_get = window.location.hash + '&request=' + Ajax.lastRequestNo;
	if (div_alerts_dismissed) {
		var dismissed = div_alerts_dismissed.join();
		load_get += '&div_alerts_dismissed=' + dismissed;
	}	

	load_get += "&caller=homepage";
		
	load_get = stripLeadingHash(load_get);
	load_get = convertArraysInUrl(load_get);
			
		// get the result count, initialize all session vars
		new Ajax.Updater(
			"result_count", 
			"http://" + dev_url + "app/scripts/controller.php?" + load_get,
			{
			 method: "GET",
			 onSuccess: function (transport, json) {
				if (json.request < Ajax.lastRequestNo) { return; }

/**				
				 if (json.open_widgets) {
					  	open_widgets = json.open_widgets;
						json.open_widgets = null;
				 }
				 if (json.default_div) {
					  	default_div = json.default_div;
						json.default_div = null;
				 }
**/

				$('result_heading').innerHTML = "Result Count:";
				if ($('menu_indicator')) { Effect.Appear('menu_indicator', {duration:1}); }

				getNextDivs(json.request);
				
				if (json.error) {
					new Element.scrollTo('banner');
					$('alert_text').innerHTML = json.error;
					Element.show('alert_container');
					Element.show('alert_text');

					for (var i=0;i<json.error_widgets.length; i++) {
						highlightWidgetError(json.error_widgets[i],1);
					}}}});
				
}	  // end load2()

	function highlightWidgetError(widget,state) {
		if (state && $(widget) ) {
			$(widget).style.border = "3px solid red";
			$(widget).style.backgroundColor = '#FFFFCC';
		}
		else if ($(widget)){
			$(widget).style.border = "none";
			$(widget).style.backgroundColor = '#FFFFFF';
		}	
	}
	function monitorTextFields(post_name,no){
		var id = 'input_' + post_name + no;
		
		if (!$(id).value) {
			removeIndicator(post_name,no);
			updateHash();
		}
	} 

	function removeIndicator(post_name,no) {
		// empty the original field
		var field_id     = 'input_'     + post_name + no;
		var indicator_id = 'indicator_' + post_name + no;
		if ($F(field_id)) {
			// this user input is checked..	
			if ($(field_id).type == 'checkbox') {
				// uncheck the checkbox
				$(field_id).checked = false;
			}
			else {
				// clear the text fields
				Field.clear(field_id);
				Field.clear($(field_id));
			}
		} 
		// hide indicator
		if ($(indicator_id)) {
			Element.remove(indicator_id);

		}	
	}

	// types are STRING STRING_SELECT
	function addIndicator(post_name,no,label,type) {
		var field_id 			= 'input_' + post_name + no;
		var indicator_id 		= 'indicator_' + post_name + no;
		var indicator_container = 'indicator_container_' + post_name;
		// get html of new indicator
		var indicator_str = getIndicatorString(post_name,no,label,type);
		// add new indicator
		// watch the field types, sometimes we are replacing and sometimes adding
		if (type=='GROUP') {
				new Insertion.Bottom(indicator_container, indicator_str);
			}
		else if ((type == 'RANGE') || (type == 'TIME')) {
			if($(indicator_id)) {
				// indicator exists, replace it and show it
				$(indicator_id).innerHTML = indicatorReplaceInner(post_name,no,label,type);
				Element.show(indicator_id);
//				$(indicator_id).style.display = '';
			}		
			else {
				// indicator does not exist draw it, show it.
				new Insertion.Bottom(indicator_container, indicator_str);
				Element.show(indicator_id);
			}
		} else {
			// these are types STRING and STRING_SELECT, they get 1 indicator only, keep replacing
			// this is a string field and there is only 1 allowed indicator
				$(indicator_container).innerHTML = '';
				$(indicator_container).innerHTML = indicator_str;
		}	
}
function handleTextFieldKeyPress(event,post_name,value) {
	var key=event.keyCode || event.which;
	if (key==13){
		indicatorHandler(post_name,value,'STRING');
		updateHash();
	}
}
var formValues = new Array();
var lastFormValues = new Array();
function indicatorHandler(post_name,no,label,type) {
		// hide all widget error notices
		if (type=='RANGE') {
			highlightWidgetError(post_name + '1_widget',0); 
		}
		else {
			highlightWidgetError(post_name  + '_widget',0); 
		}
		//		$(post_name + '_' + no).style.fontWeight = "bold";
		// need this here for checkflags
		// the way checkflags work is that they check this div, if it is 
		// empty then the flag is removed, if not then it stays the same
		// we are using the depracated functionality of the indicators to make
		// these flags work properly.. a hack !!
		var indicator_container = 'indicator_container_' + post_name;
		var field_id = 'input_' + post_name + no;
		if($F(field_id)) {
			addIndicator(post_name,no,label,type);
			// if type is group, make the label bold
			if (type=='GROUP') {
				$(post_name+'_'+no).style.fontWeight='bold';
			}
			// put up checkflag
			Element.show('flag_selected_' + post_name);
		}
		else {
			removeIndicator(post_name,no); 
			// make unbold
			if (type=='GROUP') {
				$(post_name+'_'+no).style.fontWeight='normal';
		}
			// should we remove the checkflag?  check the indicator container..
//			alert('checking to remove');
			if (!$(indicator_container).innerHTML.strip()) {
				//no more indicators, remove flag
				Element.hide('flag_selected_' + post_name);
			}
		}
}
function getIndicatorString(post_name,no,label,type) {
		var inner = indicatorReplaceInner(post_name,no,label,type);
		var string =  '<span id = "indicator_' + post_name + no + '" class = "indicators">' + 
				inner  + 
				'</span>'	;
		return string;		
}
function indicatorReplaceInner(post_name,no,label,type) {
		var pre    = ''; 
		var string = '';
		var no_display = 0;
		if (type == 'RANGE') {
			if (no.substr(0,1) == '1') {
				pre = 'min: ';	
			}
			else {
				pre = 'max: ';
			}
		}
		else if (type == 'STRING_SELECT') {
			// this is the string select drop down, in which case it's value 
			// is really the 'pre' and it's adjasent text field is the value.
			pre = label + ': ';
			if ($F('input_' + post_name)) {
				label = $F('input_' + post_name);
			}
			else {
			// there is no entry in the adjacent text field, do not dislay an indicator
			no_display = 1;
			}
		}
		else if (type == 'STRING') {
			// get the pre from the select field
			pre = $F('string_selects_' + post_name) + ': '; 
		}
		if (!no_display) {
			string = '<span class = "indicator_pre">' + pre + '</span>'			
						+ label + 
						'&nbsp;<a class = "indicatorClose" href = "" onclick = "removeIndicator(\''  +  
								post_name + "','" + no + '\');  updateHash(); return false;">x</a>';
			return string;		
		}
	}
var txt="";
 // from the shopping cart demo
function userSelectionFlag() {
}
// calls getValidMultsJSON 
// state is what to DO, like 1 = show and 0 = hide.. the state you *want*
function toggleWidget(post_name,div,state) {
    var widget     	= post_name + "_widget";
    var show_label = post_name + "_show_label";
	var hide_label 	= post_name + "_hide_label";
	var widget_extras   	  = post_name + "_widget_extras";
	var widget_footnote	  = post_name + "_widget_footnote";
	// ajax call here 
	if (in_array(post_name,mult_widget_post_names[div]) && state) {
		// call the server to get valid mults for this newly opened widget
		// only fetch this widget, make an array to hold it:
		var widget_arr = [post_name];
		info('calling getvalidmultsjson from togglewidget ' + div + ' ' + widget_arr);
		getValidMultsJSON(div,widget_arr);
	}
   	if (state && Ajax.activeWidgetRequest[div]) {
		Effect.Appear('spinner_' + post_name, {duration:div_loading_duration});
	}
	if (!state) {
		Effect.Fade('spinner_' + post_name, {duration:div_loading_duration});
	}
	if (!$(show_label)) {
		error('no show_label to toggle' + show_label);
		return;
	}	
	if (!$(hide_label))  {
		error('no hide_label to toggle' + hide_label);
		return;
	}
	if (!$(widget)) { 
		error('no widget to toggle' + widget);
		return;
	}	
	if (state) {
		// show the widget
		Effect.BlindDown(widget, {duration:.2});
		Effect.BlindDown(widget_extras, {duration:.2});
		Effect.BlindDown(widget_footnote, {duration:.2});
		Element.hide(show_label);
		Element.show(hide_label);
	}
	else {
		Effect.BlindUp(widget, {duration:.2});
		Effect.BlindUp(widget_extras, {duration:.2});
		Effect.BlindUp(widget_footnote, {duration:.2});
		Element.show(show_label);
		Element.hide(hide_label);
	}
	// handling of the open_widgets array
	if (state) {
		// showing the widget		
		// add to open_widgets array
		// first make sure it's not already in the array
		if (!in_array(post_name,open_widgets)){
			// it's not there so add it..
			open_widgets[open_widgets.length] = post_name;
		}
	}
		else {
			// renmove from open_widgets array
			for (var i=0;i<open_widgets.length;i++) {		 	
				if (open_widgets[i] == post_name) {
					open_widgets.splice(i,1);
				}		
			}
		}
}
function showDiv(id) { 
	if (document.getElementById) {
      document.getElementById(id).style.display = 'block';
      document.getElementById(id).focus();
	} else {
  		  document.all[ id ].style.display = 'block'; 
  		  document.all[ id ].focus(); 
	}
}
function hideDiv(id) { 
	if (document.getElementById) {
      document.getElementById(id).style.display = 'none';
	} else {
  		  document.all[ id ].style.display = 'none';  
	}
}
function toggleBox(szDivID, iState) // 1 visible, 0 hidden
{
	if(document.getElementById)	  //gecko(NN6) + IE 5+
    {
        var obj = document.getElementById(szDivID);
        obj.style.display = iState ? "block" : "none";
    }
    else if (document.all)	// IE 4
    {
        document.all[szDivID].style.display = iState ? "block" : "none";
    }
}

function defaultMenu(thisDiv) {
   var menuID;
   var linkID;
   menuID = "menu_" + thisDiv;
   linkID = "link_" + thisDiv;
   checkboxID = menuID + "_checkbox";
   document.getElementById(thisDiv).style.visibility = "visible";
   document.getElementById(thisDiv).style.display = "inline";
   document.getElementById(menuID).style.backgroundColor = "#f0f0fe";
   document.getElementById(checkboxID).style.backgroundColor = "#f0f0fe";
   document.getElementById(linkID).style.color = "black";
}
function menuMouseOver(div) {
    var menuID  = "menu_" + div;
    var checkboxID  = menuID + "_checkbox";
    var linkID  = "link_"  + div;
	$(linkID).style.color = "black";
}

function menuMouseOut(div) {
	if (div != default_div) {
		var linkID  = "link_"  + div;
		var menuID  = "menu_" + div;
		var checkboxID  = menuID + "_checkbox";
	}
}
// todo:
// abstract out the color and bgcolor lines to their own function
// then apply that function in here, and on mouseOver
function menuStyle() // 1 visible, 0 hidden
{
   for (var i=0; i < all_divs.length; i++) {
       this_div    = all_divs[i];
       var menuID  = "menu_" + this_div;
       var linkID  = "link_"  + this_div;
       var checkboxID  = menuID + "_checkbox";
	if ($(menuID)) {   
		if (default_div == this_div) {
		   $(menuID).style.backgroundColor = "white";
		   $(checkboxID).style.backgroundColor = "white";
		   $(linkID).style.fontWeight = "bold";
		   }
		   else {
		   $(menuID).style.backgroundColor = "";
		   $(checkboxID).style.backgroundColor = "";
		   $(linkID).style.fontWeight = "500";
		   }
		}   
   } // end for
}
function deselectCheck(div) {
    document.form1.default_div.value = div;
    document.form1.deselect_check.value = 1;
}
