
	// I'm not convinced that we should be doing this here, but whatever.
	function CheckExpression(field, expr)
	{
		return(expr.exec(field));
	}

	// Takes a regular expression or regular string.
	function CountOccurences(val, expr)
	{
		var parts = val.split(expr);
		return(parts.length-1);
	}

	// Let's get rid of whitespace.
	function Trim(ourtext)
	{
		var our_pattern = /(^\s*|\s*$)/g;
		ourtext = ourtext.replace(our_pattern, '');
		return(ourtext);
	}

	// Utility function to get the value of a <select> element
	function GetSelectValue(form_name, select_name)
	{
		var index = document.forms[form_name].elements[select_name].selectedIndex;
		return(document.forms[form_name].elements[select_name].options[index].value);
	}
	
	// Utility function to get the value of a radio button
	function GetRadioValue(form_name, radio_name)
	{
		var radio = document.forms[form_name].elements[radio_name];
		
		for(var i=0; i<radio.length; i++)
		{
			if(radio[i].checked == true)
			{
				return(radio[i].value);
			}
		}
		
		return(null);
	}

	// Pretty numbers up.
	function FormatNumber(ournum)
	{
		var parts = ournum.toString().split(".");
		ournum = parts[0];
		var pattern = /(\d+)(\d{3})/;

		while(pattern.test(ournum))
		{
			ournum = ournum.replace(pattern, '$1,$2');
		}

		if(parts.length == 2)
		{
			if(parts[1].length > 2)
			{
				parts[1] = parts[1].substring(0, 2);
			}

			ournum += "." + parts[1];
		}

		return(ournum);
	}

	function GetPercentage(part, total)
	{
		if(part == 0)
		{
			return(0);
		}

		return(FormatNumber((part/total)*100));
	}

	function HandleClick(element_name)
	{
		var this_element = document.getElementById(element_name);

		if(this_element.type == "checkbox")
		{
			this_element.checked = !(this_element.checked);
		} else if(this_element.type == "radio")
		{
			this_element.checked = true;
		}
	}

	function ClearTextArea(textarea, chars_remaining, maxnum)
	{
		if(confirm("Are you sure you want to clear this textarea?"))
		{
			textarea.value = "";
			if(chars_remaining == 1)
			{
				CharactersRemaining(textarea, maxnum);
			}
		}
	}

	// this relies on the fact that there's a hidden form variable with the contents of whatever was previously there.
	// the hidden form value should be named in the manner textareaname+ '_hidden'
	function ResetForm(textarea, chars_remaining, maxnum)
	{
		if(confirm("Are you sure you want to reset the field for this textarea?"))
		{
			// Maybe not.
			//textarea.value =
		}
	}

	/* HTML FUNCTIONS */

	// Assumes there's a span/div id identical to that of the textarea, with the exception that its name has "_chars_remaining"
	// appended to it. So, the textarea might be called 'body' and the span/div id would be called 'body_chars_remaining'
	// Usage: <textarea ... onkeyup="CharactersRemaining(this);" onkeydown="CharactersRemaining(this);" onchange="CharactersRemaining(this);">
	function CharactersRemaining(textarea, maxnum)
	{
		var chars_remaining = maxnum - textarea.value.length;

		if(chars_remaining < 0)
		{
			textarea.value = textarea.value.substring(0, maxnum);
			chars_remaining = 0;
		}

		document.getElementById(textarea.name + '_chars_remaining').firstChild.data = FormatNumber(chars_remaining);
	}

	// Like above, but we have to have _chars_remaining_minus_html
	function CharactersRemainingMinusHTML(textarea, maxnum, maxnumminushtml)
	{
		CharactersRemaining(textarea, maxnumminushtml);

		var chars_remaining = maxnum - textarea.value.replace(/<\/?(a|i|b|u).*?>/ig, '').length;

		if(chars_remaining  < 0)
		{
			chars_remaining = 0;
		}

		document.getElementById(textarea.name + '_chars_remaining_minus_html').firstChild.data = FormatNumber(chars_remaining);
	}

	// HTML related functions.
	var short_tag_names = {"b": "Bold", "i": "Italic", "u": "Underline"};

	// Clean up Short tags that just have whitespace between them.
	function TrimShortTags(ourtext)
	{
		var short_tag_checks = new Array("b", "i", "u");
		var this_tag, this_expr;

		for(var i=0; i<short_tag_checks.length; i++)
		{
			this_tag = short_tag_checks[i];

			this_expr = "/<" + this_tag + ">\\s*<\\/" + this_tag + ">/i";
			ourtext = Trim(ourtext.replace(eval(this_expr), ''));
		}

		return(ourtext);
	}

	function CheckShortTags(textarea)
	{
		var short_tag_checks = new Array("b", "i", "u");
		var this_tag, open_tags, closed_tags;
		var test_string = textarea.value.toLowerCase();
		var begin_search = 0, new_begin_search = 0;

		for(var i=0; i<short_tag_checks.length; i++)
		{
			this_tag = short_tag_checks[i];

			open_tags = CountOccurences(test_string, '<' + this_tag + '>');
			closed_tags = CountOccurences(test_string, '</' + this_tag + '>');

			if(open_tags != closed_tags)
			{
				alert("You have one or more " + short_tag_names[this_tag] + " tag mismatches.");
				return(false);
			}

			begin_search = 0;
			new_begin_search = 0;
			while(test_string.indexOf('<' + this_tag + '>', begin_search) != -1)
			{
				new_begin_search = test_string.indexOf('<' + this_tag + '>', begin_search);

				if(test_string.indexOf('</' + this_tag + '>', new_begin_search+3) == -1)
				{
					alert("You have a " + short_tag_names[this_tag] + " tag open, but it isn't closed.");
					return(false);
				}

				begin_search = (new_begin_search+1);
			}
		}

		return(true);
	}

	function CheckHREFTags(textarea)
	{
		var test_string = textarea.value.toLowerCase();
		// The spaces are a fix for IE. God knows what's going on there.
		var num_open = CountOccurences(" " + test_string + " ", /<a href=[^>]+>/i);
		var num_closed = CountOccurences(" " + test_string + " ", /<\/a>/i);

		if(num_open != num_closed)
		{
			alert("You have one or more mismatched HREF tags.");
			return(false);
		}

		var start_search = 0, new_start_search = 0;
		var opener_expression = /<a href=([^>]+)>/i;
		var our_result;
		var our_match;
		while((our_result = opener_expression.exec(test_string.substring(start_search, test_string.length))) != null)
		{
			our_match = our_result[0];
			new_start_search = test_string.indexOf(our_match, start_search)+our_match.length;

			if(test_string.indexOf('</a>', new_start_search) == -1)
			{
				alert("You have one or more open, but unclosed, HREF tags.");
				return(false);
			}

			start_search = new_start_search;
		}

		return(true);
	}

	// Usage: in buttons. tag should be "b, i or u".
	function ShortTag(textarea, tag)
	{
		var our_prompt = prompt("Please enter the text you would like to appear between the " + short_tag_names[tag].toLowerCase() + " tags.");
		our_prompt = Trim(our_prompt);

		if(our_prompt.length == 0)
		{
			textarea.focus();
			return;
		}

		textarea.value = textarea.value + "<" + tag + ">" + our_prompt + "</" + tag + ">";
		textarea.focus();
	}

	function AHREFTag(textarea)
	{
		var our_url = prompt("Please enter the URL of the site you'd like to link to!");
		our_url = Trim(our_url);

		if(our_url.length == 0)
		{
			alert("You must enter the URL of the site you'd like to link to! If you've changed your mind, click \"cancel\".");
			AHREFTag(textarea);
			return;
		}

		var our_label = prompt("Please enter a label you'd like to appear for the website (text will appear as a link, rather than the link itself).");
		our_label = Trim(our_label);

		if(our_label.length == 0)
		{
			our_label = our_url;
		}

		var our_begin_pattern = /^((ht|f)tps?:\/\/|aim:goim|skype|\/)/;
		if(!(our_begin_pattern.exec(our_url)))
		{
			our_url = "http://" + our_url;
		}

		var our_ng_stuff = /^http:\/\/(www\.)?newgrounds\.com(\/?.*)$/i;
		our_url = our_url.replace(our_ng_stuff, "$2");
		if(our_url == "")
		{
			our_url = "/";
		}

		textarea.value = textarea.value + "<a href=\"" + our_url + "\">" + our_label + "</a>";
		textarea.focus();
	}

	function MailToTag(textarea)
	{
		var our_email = prompt("Please enter the e-mail address that you'd like to link to.");
		our_email = Trim(our_email);

		if(our_email.length == 0)
		{
			alert("You must enter the e-mail address that you'd like to link to. If you've changed your mind, press cancel!");
			MailToTag(textarea);
			return;
		}

		if(CountOccurences(our_email, '@') != 1)
		{
			alert("You must enter an @ sign into the address!");
			textarea.focus();
			return;
		}

		var our_good_chars = /[^a-z0-9\-_\.]/ig;
		var our_parts = our_email.split('@');

		if((our_good_chars.exec(our_parts[0])) || (our_good_chars.exec(our_parts[1])))
		{
			alert("Invalid e-mail address!");
			textarea.focus();
			return;
		}

		var our_label = prompt("Please enter a label for the e-mail address, or leave blank to display the e-mail address rather than a label for the address.");
		our_label = Trim(our_label);

		if(our_label.length == 0)
		{
			our_label = our_email;
		}

		textarea.value = textarea.value + "<a href=\"mailto:" + our_email + "\">" + our_label + "</a>";
		textarea.focus();
	}
