		var map;
		var mgr;
		var geocoder;
		var g = null;
		var updated = false;

		function initialize()
		{
			map = new GMap2(document.getElementById("map_canvas"));
			map.addControl(new GSmallMapControl());
			map.setCenter(new GLatLng(39, -96.5), 3);
			mgr = new MarkerManager(map);
			geocoder = new GClientGeocoder();
			updateUSACheckbox(false);
			needsUpdate(true);
		}

		function updateAddress()
		{
			var form = document.regphotog;
			if (!validateForm(form)) return;

			updateMap(form);
		}

		function validateForm(form, addressonly)
		{
			if (addressonly == null) addressonly = false;
			var e = "";
			var v = null;

			with (form)
			{
				if (!addressonly)
				{
					v = studio.value;

					if (!v || v == "")
					{
						e += "Please provide a photographer/studio name.";
					}

					v = url.value;

					if (!v || v == "" || !verifyURL(v))
					{
						e += (e == "" ? "" : "\n") + "Please provide a valid website/blog URL";
					}

					v = email.value;

					if (!v || v == "" || !verifyEmail(v))
					{
						e += (e == "" ? "" : "\n") + "Please provide a valid email address";
					}

					v = phone.value;

					if (v && v != "" && !verifyPhone(v))
					{
						e += (e == "" ? "" : "\n") + "Please provide a valid phone number or leave blank";
					}
				}

				v = street.value;

				if (false)
				{
					e += (e == "" ? "" : "\n") + "Please provide a valid street address";
				}

				v = city.value;

				if (false)
				{
					e += (e == "" ? "" : "\n") + "Please provide a valid city";
				}

				v = state.value;

				if (false)
				{
					e += (e == "" ? "" : "\n") + "Please provide a valid state";
				}

				v = country.value;

				if (!usa.checked && (!v || v == ""))
				{
					e += (e == "" ? "" : "\n") + "Please provide a country";
				}

				v = zip.value;

				if (usa.checked && (!v || v == "" || !verifyZip(v)))
				{
					e += (e == "" ? "" : "\n") + "Please provide a valid Zip/Postal code";
				}

				if (!addressonly)
				{
					minprize = 150;
					v = winnerprize.value;

					if (!v || v == "" || !verifyPrize(v))
					{
						e += (e == "" ? "" : "\n") + "Please provide a valid U.S. dollar amount for the winner's prize.";
					}
					else if (!verifyPrize(v,false,minprize))
					{
						e += (e == "" ? "" : "\n") + "There's a $" + minprize + " minimum giveaway... don't forget to include the value of your session fee!";
					}

					v = referrerprize.value;

					if (v && v != "" && !verifyPrize(v,true))
					{
						e += (e == "" ? "" : "\n") + "Please provide a valid U.S. dollar amount for the referrer's prize.";
					}

					v = locale.value;

					if (false)
					{
						e += (e == "" ? "" : "\n") + "Please provide a valid effective locale.";
					}
				}

				v = deadline.value;

				if (!v || v == "" || !verifyDate(v))
				{
					e += (e == "" ? "" : "\n") + "Please provide a valid nomination deadline.";
				}
				else if (!verifyDate(v, "03/01/2010"))
				{
					e += (e == "" ? "" : "\n") + "Whoops!  There's a giveaway announcement deadline of 3/1/10! ";
				}

				v = announce.value;

				if (!v || v == "" || !verifyDate(v))
				{
					e += (e == "" ? "" : "\n") + "Please provide a valid winner announcement date.";
				}
			}

			var ret = true;

			if (e != "")
			{
				alert(e);
				ret = false;
			}

			return ret;
		}

		function verifyDate(date, compareDate)
		{
			var regexp = /^(0?[1-9]|1[0-2])\/(0?[1-9]|[1-2][0-9]|3[0-1])\/(20)?(0[8-9]|1[0-9])$/

			if (!regexp.test(date)) return false;

			var max = 0;

			bits = date.split("/");

			yr = parseInt(bits[2]);
			if (yr < 100) yr += 2000;
			isleap = (yr % 4 == 0);
			mo = parseInt(bits[0]);

			switch (mo)
			{
				case 1: max = 31; break;
				case 2: if (isleap) max = 29; else max = 28; break;
				case 3: max = 31; break;
				case 4: max = 30; break;
				case 5: max = 31; break;
				case 6: max = 30; break;
				case 7: max = 31; break;
				case 8: max = 31; break;
				case 9: max = 30; break;
				case 10: max = 31; break;
				case 11: max = 30; break;
				case 12: max = 31; break;
			}

			day = parseInt(bits[1]);
			
			if (compareDate != null)
			{
				ddbits = compareDate.split("/");
				
				ddyr = parseInt(ddbits[2]);
				if (ddyr < 100) ddyr += 2000;
				ddmo = parseInt(ddbits[0]);
				ddday = parseInt(ddbits[1]);
				
				if (yr < ddyr) isBeforeDropDead = true;
				else if (yr > ddyr) isBeforeDropDead = false;
				else if (mo < ddmo) isBeforeDropDead = true;
				else if (mo > ddmo) isBeforeDropDead = false;
				else if (day <= ddday) isBeforeDropDead = true;
				else isBeforeDropDead = false;
			}
			else
			{
				isBeforeDropDead = true;
			}

			return (day <= max && isBeforeDropDead);
		}

		function verifyURL(url)
		{
			if (url.indexOf("://") < 0)
			{
				url = "http://" + url;
				document.regphotog.url.value = url;
			}

			var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
			return regexp.test(url);
		}

		function verifyEmail(str)
		{
			/**
 			* DHTML email validation script. Courtesy of SmartWebby.com (http://www.smartwebby.com/dhtml/)
			**/

			var at="@"
			var dot="."
			var lat=str.indexOf(at)
			var lstr=str.length
			var ldot=str.indexOf(dot)

			if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr)
			{
				return false;
			}

			if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr)
			{
				return false;
			}

			if (str.indexOf(at,(lat+1))!=-1)
			{
				return false;
			}

			if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot)
			{
				return false;
			}

			if (str.indexOf(dot,(lat+2))==-1)
			{
				return false;
			}

			if (str.indexOf(" ")!=-1)
			{
				return false;
			}

			return true;
		}

		function verifyZip(s)
		{
			// Check for correct zip code
			reZip = new RegExp(/(^\d{5}$)|(^\d{5}-\d{4}$)/);

			if (!reZip.test(s))
			{
				// Try Canadian
				if (s.length == 6 && s.search(/^[a-zA-Z]\d[a-zA-Z]\d[a-zA-Z]\d$/) != -1) return true;
				else if (s.length == 7 && s.search(/^[a-zA-Z]\d[a-zA-Z](-|\s)\d[a-zA-Z]\d$/) != -1) return true;
				else return false;
			}

			return true;
		}

		function verifyPrize(prize,allowzero,minprize)
		{
			if (minprize == null) minprize = 1;
			val = parseInt(prize);
			return (val >= minprize) || (val == 0 && allowzero);
		}

		/**
 		* DHTML phone number validation script. Courtesy of SmartWebby.com (http://www.smartwebby.com/dhtml/)
		 **/

		function isInteger(s)
		{
			var i;
			for (i = 0; i < s.length; i++)
			{
	        		// Check that current character is number.
			        var c = s.charAt(i);
	        		if (((c < "0") || (c > "9"))) return false;
			}
			// All characters are numbers.
			return true;
		}

		function stripCharsInBag(s, bag)
		{
			var i;
			var returnString = "";
			// Search through string's characters one by one.
			// If character is not in bag, append to returnString.
			for (i = 0; i < s.length; i++)
			{
	        		// Check that current character isn't whitespace.
			        var c = s.charAt(i);
	        		if (bag.indexOf(c) == -1) returnString += c;
			}

			return returnString;
		}

		function verifyPhone(str)
		{
			// non-digit characters which are allowed in phone numbers
			var phoneNumberDelimiters = "()- ";
			// characters which are allowed in international phone numbers
			// (a leading + is OK)
			var validWorldPhoneChars = phoneNumberDelimiters + "+";
			// Minimum no of digits in an international phone no.
			var minDigitsInIPhoneNumber = 10;

			s = stripCharsInBag(str, validWorldPhoneChars);
			return (isInteger(s) && s.length >= minDigitsInIPhoneNumber);
		}

		function submitForm(form)
		{
			return validateForm(form);
		}

		function updateMap(form)
		{
			var st = form.street.value;
			var city = form.city.value;
			var state = form.state.value;
			var country = form.country.value;
			var zip = form.zip.value;

			var addr = buildAddress(st, city, state, country, zip);

			if (g && g.marker) mgr.removeMarker(g.marker);

			with (form)
			{
				g = new Giver(0, studio.value, addr, phone.value, email.value, url.value, winnerprize.value, referrerprize.value, locale.value, deadline.value, announce.value);
			}

			g.addToMap(mgr, map, true, "mapUpdatedCB()");
		}

		function mapUpdatedCB()
		{
			if (g)
			{
				document.regphotog.lat.value = g.lat;
				document.regphotog.lon.value = g.lon;
				setTimeout("openWindow()", 0); // opening the info window fails if it's on the same thread as whatever is adding the marker
				needsUpdate(false);
			}
		}

		function openWindow()
		{
			if (g) g.openInfoWindow();
		}

		function updateUSACheckbox(wipeValues)
		{
			if (wipeValues == null) wipeValues = true;
			var checked = (document.regphotog.usa.checked);
			var staterow = document.getElementById("staterow");
			var countryrow = document.getElementById("countryrow");
			var ziprow = document.getElementById("ziprow");
			if (checked)
			{
				staterow.style.display = "";
				countryrow.style.display = "";
				if (wipeValues) document.regphotog.country.value = "";
				ziprow.style.display = "";
			}
			else
			{
				staterow.style.display = "none";
				if (wipeValues) document.regphotog.state.value = "";
				countryrow.style.display = "block";
				ziprow.style.display = "none";
				if (wipeValues) document.regphotog.zip.value = "";
			}
		}

		function needsUpdate(needed)
		{
			confcheck = document.regphotog.confirmed;
			confmsg = document.getElementById("confirmmsg");
			submitbtn = document.regphotog.submit;

			if (needed || needed == null)
			{
				confcheck.disabled = true;
				confcheck.checked = false;
				confmsg.innerHTML = "Please preview location before continuing.";
				submitbtn.disabled = true;
			}
			else
			{
				confcheck.disabled = false;
				confmsg.innerHTML = "I confirm that the information above is correct to the extent of my knowledge.";
			}
		}

		function updateConfirm(box)
		{
			document.regphotog.submit.disabled = !(box.checked);
		}

		function PhotogGeo(name, lat, lon)
		{
			this.name = name;
			this.lat = lat;
			this.lon = lon;
		}

		var photogs = new Array();

