// open a generic popup window using the graphic passthru page, which allows margin=0 settings

	function popup_graphic(source,width,height) {
		popup_window_graphic = window.open("../assembled/screenshot.html?"+source,"popup_window_graphic","width="+String(width+36)+",height="+String(height+36)+",location=no,menubar=no,directories=no,toolbar=no,scrollbars=yes,resizable=yes,status=yes");
		popup_window_graphic.focus()
	}


// open the feature tour in a popup window (this lets us set the size globally)

	function open_tour(page) {
		popup(page,644,488);
	}


// open the subscriber agreement in a popup window (this lets us set the size globally)

	function open_agreement(page) {
		popup(page,360,380);
	}


// submits a single form on a page

	function submit_form(next){
	
		if (document.URL.indexOf("completed")!=-1) {
			alert ("Thanks for signing up! You'll be hearing from us shortly.");
		} else {
			document.forms["signup"].action="sign_up.php?next="+next;	
			document.forms["signup"].submit();
		}
	}
	

// checks value of agreement submission

	function agreement_submit(){
	
		if (document.signup.agreement_date[0].checked) {
				submit_form("payment");
		} else if (document.signup.agreement_date[1].checked) {
				alert("We're sorry to hear that you don't accept our Subscriber Agreement. Please feel free to send your concerns to sales@betaboard.com.");
				parent.location = "http://www.betaboard.com";
		} else {
				alert ("You choose to accept the Subscriber Agreement to continue.");
		}
	}
		 	

// grab all name/value pairs from the URL and create JavaScript variables from them

	function get_vars() {
	
		if (location.href.indexOf('?') != -1) {
		
			query_string = location.href.substring(location.href.indexOf('?') + 1, location.href.length);
			query_pairs = query_string.split("&");
			
			for (n=0; n < query_pairs.length; n++) {
				pair = query_pairs[n].split("=");
				key = pair[0];
				value = pair[1];
				eval(key + " = '" + value + "'");
			}
			
			if (query_string.indexOf("args=") != -1) {
				args_pieces = args.split(",");
				for (n=0; n < args_pieces.length; n++) {
					j = n + 1;
					eval("arg" + j + " = '" + args_pieces[n] + "'");
				}
			}
		
		} else {
			query_string = ""; query_pairs = ""; template = ""; args = "";
		}
			
	}
	

// return a value up to the delimiter, or the original value if the delimiter isn't there
// - this is used most often when parsing an argstring to set button states

	function crop(value, delimiter) {
		result = (value.indexOf(delimiter) != -1) ? value.substring(0, value.indexOf(delimiter)) : value ;
		return result;
	}
	

// open a popup window, specifying source, width, and height, and optionally a name; if no name, choose a random one

	function popup(source, width, height, window_name) {
		if (! window_name) { 
			now = new Date();
			window_name = now.getTime();
		} else {
			window_name = window_name.replace(/ /g, "_");
		}
		popup_window = window.open(source, window_name, "width=" + String(width) + ",height=" + String(height) + ",location=no,menubar=no,directories=no,toolbar=no,scrollbars=yes,resizable=yes,status=yes");
		popup_window.focus();
	}


// show an email link on a page in a way that spam harvesters can't see

	function show_email(user, domain, tld, label) {
		if (!label) { label = user + "@" + domain + "." + tld; }
		document.write("<a href='mailto:" + user + "@" + domain + "." + tld + "'>" + label + "<\/a>");
	}


// write a random element from the specified array

	function write_random(array_name) {
		which = (Math.round(Math.random() * (arrayName.length - 1)));
		document.write(array_name[which]);
	}


// the simplest possible rollover function

	function swap(name, state) {
		eval('document.images.' + name + '.src = ' + name + '_' + String(state) + '.src');
	}
	

// rollovers with sticky highlights
// - used in navigation frames where the buttons persist but other pages are changing

	var previous = null;
	var current = null;

	function sticky_swap(name, state, hold) {
		if (hold == 1) {
			// set previously lit button to normal
			previous = current;
			if (previous != null) {
				eval('document.images.' + previous + '.src = ' + previous + '_0.src');
			}
		}
		if ((name != null) && (name != current)) {
			// set new button state
			eval('document.images.' + name + '.src = ' + name + '_' + String(state) + '.src');
			if (hold == 1) { current = name; }
		}
	}
	

// rollovers with separate but linked button and label graphics
// - highlights both the button and label if you mouse over either one 
// - requires graphics to be named like "button_0.gif" and "button_label_0.gif"

	function label_swap(name, state) {
		eval('document.images.' + name + '.src = ' + name + '_' + String(state) + '.src');
		
		// change the label if one exists
		if (eval('document.images.' + name + '_label')) {
			eval('document.images.' + name + '_label.src = ' + name + '_label_' + String(state) + '.src');
		}
		
		// change the button if this is a label
		if (name.indexOf("_label") != -1) {
			name = name.substr(0, (name.length - 6));
			if (eval('document.images.' + name)) {
				eval('document.images.' + name + '.src = ' + name + '_' + String(state) + '.src');
			}
		}
	}
	

// write a block of code that preloads a list of graphics
// - this version makes on and off states and is most often used for button rollovers

// names - a comma-delimited list of button names (e.g. "home,about,contact")
// path - the path to the graphics; defaults to "../graphics" if not set (e.g. "../graphics/menus/home")
// extension - the file extension of the graphics files; defaults to "gif" if not set (e.g. "jpg")

	function preload_buttons(names, path, extension) {
		names = names.split(",");
		path = (path) ? path : "../graphics/buttons" ;
		extension = (extension) ? extension : "gif" ;
		for (n=0; n < names.length; n++) {
			this_name = names[n];
			this_path = path + "/" + this_name;
			eval(this_name + "_0 = new Image()");
			eval(this_name + "_0.src = '" + this_path + "_0." + extension + "'");
			eval(this_name + "_1 = new Image()");
			eval(this_name + "_1.src = '" + this_path + "_1." + extension + "'");
		}
	}
	

// write a block of code that preloads a list of graphics
// - this version just makes an on state and is most often used for tips associated with button rollovers

// names - a comma-delimited list of button names (e.g. "home,about,contact")
// path - the path to the graphics; defaults to "../graphics" if not set (e.g. "../graphics/menus/home")
// extension - the file extension of the graphics files; defaults to "gif" if not set (e.g. "jpg")

	function preload_tips(names, path, extension) {
		names = names.split(",");
		path = (path) ? path : "../graphics" ;
		extension = (extension) ? extension : "gif" ;
		for (n=0; n < names.length; n++) {
			this_name = names[n];
			this_path = path + "/" + this_name;
			eval(this_name + " = new Image()");
			eval(this_name + ".src = '" + this_path + "." + extension + "'");
		}
	}
	

// write a block of code that preloads a list of graphics
// - this version uses the same source file for each instance and is most often used for markers associated with button rollovers

// names - a comma-delimited list of instance names (e.g. "home_marker,about_marker,contact_marker")
// marker_name - the base name of the marker graphic
// path - the path to the graphics; defaults to "../graphics" if not set (e.g. "../graphics/menus/home")
// extension - the file extension of the graphics files; defaults to "gif" if not set (e.g. "jpg")

	function preload_markers(names, marker_name, path, extension) {
		names = names.split(",");
		path = (path) ? path : "../graphics" ;
		extension = (extension) ? extension : "gif" ;
		for (n=0; n < names.length; n++) {
			this_name = names[n];
			this_path = path + "/" + marker_name;
			eval(this_name + "_0 = new Image()");
			eval(this_name + "_0.src = '" + this_path + "_0." + extension + "'");
			eval(this_name + "_1 = new Image()");
			eval(this_name + "_1.src = '" + this_path + "_1." + extension + "'");
		}
	}
	

// leave this here to catch calls to the original preload script

	function make_preloads(names, path) {
		preload_buttons(names, path);
	}
	

// figure out whether a variable has been set or not without generating an undefined error if it hasn't

	function isset(variable) {
		eval("result = (typeof(" + variable + ") != 'undefined')");
		return result;
	}
	

// returns the index of an array element, something that ought to be built into JavaScript but isn't!
// returns -1 if not present

	function get_position(string, array) {
		for (n=0; n < array.length; n++) {
			if (array[n] == string) {
				return n;
				break;
			}
		}
		return -1;
	}


// sets a menu to a given text or value

	function set_menu(form_name, field_name, text_or_value, key) {
		eval("these_options = document." + form_name + "." + field_name + ".options");
		for (n=0; n < these_options.length; n++) {
			eval("this_text_or_value = these_options[n]." + text_or_value);
			if (this_text_or_value == key) {
				eval("document." + form_name + "." + field_name + ".selectedIndex = " + n);
				break;
			}
		}
		return "";
	}


// set date menus to a new SQL-standard date
// leave date blank to select today's date
// set to -1 to clear the menu

	function select_date(form_and_menu, new_date) {
		if (new_date != "-1") {
			if (new_date == "") {
				date = new Date();
				
				day = date.getDate();
				month = date.getMonth() + 1;
				year = date.getFullYear();
				
			} else {
				date = new_date;
				
				year = date.substring(0, date.indexOf("-"));
				month = date.substring(date.indexOf("-") + 1, date.lastIndexOf("-"));
				day = date.substring(date.lastIndexOf("-") + 1);
				
			}
					
			eval("document." + form_and_menu + "_month.selectedIndex = month");
			eval("document." + form_and_menu + "_day.selectedIndex = day");
			eval("document." + form_and_menu + "_year.selectedIndex = year - document." + form_and_menu + "_year.options[1].value + 1");
		} else {
			eval("document." + form_and_menu + "_month.selectedIndex = 0");
			eval("document." + form_and_menu + "_day.selectedIndex = 0");
			eval("document." + form_and_menu + "_year.selectedIndex = 0");
		}
	}


// set time menus to a new SQL-standard time
// leave time blank to select the current time

	function select_time(form_and_menu, new_time) {
		if (new_time != "-1") {
			if (new_time == "") {
				time = new Date();
				
				hours = time.getHours();
				minutes = time.getMinutes();
				seconds = time.getSeconds();
				
			} else {
				time = new_time;
				
				hours = time.substring(0, time.indexOf(":"));
				minutes = time.substring(time.indexOf(":") + 1, time.lastIndexOf(":"));
				seconds = time.substring(time.lastIndexOf(":") + 1);
				
			}
					
			if (hours >= 12) {
				ampm_index = 2;
				if (hours > 12) {
					hours = hours - 12;
				}
			} else {
				ampm_index = 1;
			}

			eval("document." + form_and_menu + "_hours.selectedIndex = hours");
			eval("document." + form_and_menu + "_minutes.selectedIndex = minutes + 1");
			eval("document." + form_and_menu + "_seconds.selectedIndex = seconds + 1");
			eval("document." + form_and_menu + "_ampm.selectedIndex = " + ampm_index);
		}
	}


// jumble up some text for safer transfer in places where cookies or PHP encryption can't go

	// 08-27-04 - we're no longer removing and restoring spaces; that should be the job of the code before and after calling this function, since it is not always desirable

	function pseudo_crypt(input, direction, key) { 
		output = "";
		palette = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+&=:/"; // any other characters will be untouched
		key = "everygoodboydeservesfudge"; // can only contain members of palette
		key_position = 0;
		for (n=0; n < input.length; n++) {
			input_char = palette.indexOf(input.charAt(n));
			if (input_char != -1) {
				key_char = key.charAt(key_position);
				offset = palette.indexOf(key_char);
				if (direction == 1) {
					offset = ((input_char + offset) > (palette.length - 1)) ? offset - palette.length : offset ;
					output += palette.charAt(input_char + offset);
				} else {
					offset = ((input_char - offset) < 0) ? offset - palette.length : offset ;
					output += palette.charAt(input_char - offset);
				}
				key_position++;
				key_position = (key_position > key.length) ? 0 : key_position ;
			} else {
				output += input.charAt(n);
			}
		}
		return output;
	}
	
	
// this is handy for preventing the Return key from submitting forms (set form action to "JavaScript:nothing()")
	
	function nothing() {}
		

