/* ------------------------------------------------------------ 
   Copyright (c) 2007 ManyFutures, Inc. All rights reserved.
   ------------------------------------------------------------ 
   FILE: globalgiving.js
   DESCRIPTION: Site wide javascript functions for globalgiving.
   We try to place all (most) javascript into one file that will
   be downloaded once and cached for all pages.
   ------------------------------------------------------------ */

/* ********************* MAIN ONLOAD ** MAIN ONLOAD ***************** */

/*
 * This is the main onload function that will call others
 */

function pageOnLoad() {
	// Look for queued up Listener functions to call, now that page is loaded
	if (window.onloadListeners) {
		for ( var i = 0; i < window.onloadListeners.length; i++) {
			var func = window.onloadListeners[i];
			func.call();
		}
	}
}

function onDocumentReady() {
	// alert('The cobrand is :'+getCobrandFromURL());
	grabRefCode();
	checkLogin(); // this lives in ggajax.js
}

try {
	$(document).ready( function() {
		onDocumentReady();
	});
} catch (err) {
	// oh well
}

/** ******************* Browse Page - Expand/Collapse Items ***************** */
function toggleItem(strElementID) {
	if (document.getElementById("panel" + strElementID).style.display == "none") {
		expandItem(strElementID);
	} else {
		collapseItem(strElementID);
	}
}

function expandItem(strElementID) {
	document.getElementById("panel" + strElementID).style.display = "block";
	document.getElementById("image" + strElementID).src = "/img/icons/collapse.gif";
}
function collapseItem(strElementID) {
	document.getElementById("panel" + strElementID).style.display = "none";
	document.getElementById("image" + strElementID).src = "/img/icons/expand.gif";
}

/* ********************* GENERAL ** GENERAL ***************** */

/*
 * Note: as of 4/18/06 - additional functionality added to the onload to: Parse
 * the query string of the URL looking for 'rf=xxxx' If found, a ggRefCode
 * Cookie is created (or overwritten) with the contents being xxxx. The cookie
 * will expire in 30 days. This is to facilitate identifying donations as from a
 * certain source. The referring URL (from a google adword, or referral from
 * another site) Must contain the query string "?rf=xxxx", to be recognized. The
 * giving cart will add this refcode to each giving cart item in the promotion
 * code.
 * 
 * Note: as of 4/25/06 - this used to be in a forcewww() onload script don't
 * need this anymore, can be handled by apache. so took out url ref code
 * checking and put in own function.
 */

function grabRefCode() {

	// Check for a referral code in the query string...
	// parse the query string on this page, and see if it has an rf=*
	// if so, put the * in cookie called ggRefCode
	var query = location.search.substring(1);
	var pairs = query.split("&"); // split pairs by ampersand 
	var noRefCode = true;
	for ( var i = 0; i < pairs.length; i++) {
		var pos = pairs[i].indexOf("=");
		if (pos == -1)
			continue;
		var argname = pairs[i].substring(0, pos).toLowerCase();
		if (argname.toLowerCase() == "rf") {
			var value = pairs[i].substring(pos + 1);
			assignRefAndConversionCode(value, false); 
			noRefCode = false;
			//setCookie("ggRefCode", value, 365, "/"); 
			//setCookie("ggConversionCode", value, 30, "/");
			//alert(getCookie('ggConversionCode')); 
		} 
	}
	if(noRefCode){
		assignRefAndConversionCode(null, false);
	}
}

/** * For Value Outcomes * */
function showMore(projectId) {
	document.getElementById("lessValueOutcomes" + projectId).style.display = "none";
	document.getElementById("moreValueOutcomesButton" + projectId).style.display = "block";

	$("#moreValueOutcomes" + projectId).slideDown(200);
	//$("#lessValueOutcomes" + projectId).parent().hide();
	//$("#lessValueOutcomes" + projectId).parent().siblings().hide();
}

function showLess(projectId) {
	document.getElementById("lessValueOutcomes" + projectId).style.display = "block";
	document.getElementById("moreValueOutcomes" + projectId).style.display = "none";
	document.getElementById("moreValueOutcomesButton" + projectId).style.display = "none";

	//$("#lessValueOutcomes" + projectId).parent().show();
	//$("#lessValueOutcomes" + projectId).parent().siblings().show();
}


/**
 * this function will print (called from receipt.wm) the receipt but hide the
 * survey fields first, then re-show them.
 */
function printReceipt() {
	var surv = document.getElementById('rcpt_survey');
	if (surv != null) {
		surv.style.cssText = "display:none"; // hide the survey
		window.print();
		surv.style.cssText = "disiplay:block"; // un-hide the survey
	} else {
		window.print();
	}
}

/*
 * Function called on every page to check if the user is logged in or not. If
 * they are logged, we display their display name, handed to me by the cookie.
 */

// Popup a help window
function showhelp(url) {
	var width = 400;
	var height = 500;
	var name = 'HelpWindow';
	popup2(url, name, width, height);
}

/**
 * this determines a cobrand id from the location path NOTE: if cobrand id is
 * cidi, this returns gg Because this is used to determine cookie names for
 * login tokens And gg and CIDI want to share a common login All other cobrands
 * have individual login. TODO: Need to implement special code for cobrands that
 * have their own URL (ie. not globalgiving/cb/<cbid>
 */

function getCobrandFromURL() {
	var result = 'gg';
	var path = location.pathname;
	if (path == null || path.length < 3) {
		if (location.hostname.indexOf("globalgiving") > -1)
			return result;
		else if (location.hostname.indexOf("globalgrandparenting") > -1)
			return result; // same as gg
		// else its a different URL/cobrand, figure it out!!!
	} else {
		if (path.indexOf("/dy/v2/admin/") > -1) {
			var re = "dy\\/v2\\/admin\\/[^\\/]+\\/";
			var matches = path.match(re);
			if (matches != null && matches.length == 1)
				result = matches[0].substring(12, matches[0].length - 1);
			else
				result = 'gg';
		}
		else if (path.indexOf("/dy/") > -1) {
			// find the html portion
			// var re = /(\/.*)+\/(.+)\.html/;
			var re = /[^\/]+\.html/;
			var matches = path.match(re);
			if (matches != null && matches.length == 1)
				result = matches[0].substring(0, matches[0].length - 5);
			else
				result = 'gg';
		} else if (path.indexOf("/cb/") > -1) {
			// find the cb in path
			var re = /\/cb\/(\w+)\// ;
			var matches = path.match(re);
			result = matches[1];
		}
		if (result == 'cidi')
			result = 'gg'; // cidi and gg are the same!!
	    if(result.indexOf("challenge")!=-1) // added to make sure user cookie is found if on a leaderboard
			result='gg';
		return result;
	}
}

/* ********************* COOKIES CHECK FOR LOGIN BOX ****************** */

/*
 * DISCLAIMER: THESE JAVASCRIPT FUNCTIONS ARE SUPPLIED 'AS IS', WITH NO WARRANTY
 * EXPRESSED OR IMPLIED. YOU USE THEM AT YOUR OWN RISK. NEITHER PAUL STEPHENS
 * NOR PC PLUS MAGAZINE ACCEPTS ANY LIABILITY FOR ANY LOSS OR DAMAGE RESULTING
 * FROM THEIR USE, HOWEVER CAUSED.
 * 
 * Paul Stephens' NetScape-based cookie-handling library
 * 
 * http://web.ukonline.co.uk/paul.stephens/index.htm
 * 
 * TO USE THIS LIBRARY, INSERT ITS CONTENTS IN A <script></script> BLOCK IN THE
 * <HEAD> SECTION OF YOUR WEB PAGE SOURCE, BEFORE ANY OTHER JAVASCRIPT ROUTINES.
 * 
 * Feel free to use this code, but please leave this comment block in.
 * 
 */

function setCookie(name, value, lifespan, access_path) {

	var cookietext = name + "=" + escape(value)
	if (lifespan != null) {
		var today = new Date()
		var expiredate = new Date()
		expiredate.setTime(today.getTime() + 1000 * 60 * 60 * 24 * lifespan)
		cookietext += "; expires=" + expiredate.toGMTString()
	}
	if (access_path != null) {
		cookietext += "; PATH=" + access_path
	}
	document.cookie = cookietext
	return null
}

function setDatedCookie(name, value, expire, access_path) {
	var cookietext = name + "=" + escape(value)
			+ ((expire == null) ? "" : ("; expires=" + expire.toGMTString()))
	if (access_path != null) {
		cookietext += "; PATH=" + access_path
	}
	document.cookie = cookietext
	return null
}

/**
 * Get the value of a cookie. If the cookie does not exist, return 'null'.
 * 
 * Use this function instead of 'getCookie()' as this function is more
 * appropriately/accurately named.
 */
function getCookieValue(Name) {
	var search = Name + "="
	var CookieString = document.cookie
	var result = null
	if (CookieString.length > 0) {
		offset = CookieString.indexOf(search)
		if (offset != -1) {
			offset += search.length
			end = CookieString.indexOf(";", offset)
			if (end == -1)
				end = CookieString.length;
			// result = CookieString.substring(offset,end);
			// alert('[getCookieValue]encoded="'+result+'",unencoded="'+decodeURIComponent(result)+'"');
			result = decodeURIComponent(CookieString.substring(offset, end))

		}
	}
	return result;
}

/**
 * Check if a cookie exists at all. Value may still be blank (i.e. an empty
 * string). Function returns a boolean - true if the cookie exists; otherwise,
 * false.
 */
function userHasCookie(CookieName) {
	var cookieValue = getCookieValue(CookieName)
	if (cookieValue == null)
		return false
	return true
}

/**
 * This function should really be called getCookieValue(), because it returns a
 * cookie's value, not a cookie object itself.
 */
function getCookie(Name) {
	return getCookieValue(Name)
}

/**
 * Get a cookie value ONLY for specified path
 */
function getCookieValue(Name, Path) {
	var search = Name + "="
	var CookieString = document.cookie
	var result = null
	if (CookieString.length > 0) {
		offset = CookieString.indexOf(search)
		if (offset != -1) {
			offset += search.length
			end = CookieString.indexOf(";", offset)
			if (end == -1)
				end = CookieString.length;
			// result = unescape(CookieString.substring(offset, end))
			// result = CookieString.substring(offset,end);
			// alert('[getCookieValue]encoded="'+result+'",unencoded="'+decodeURIComponent(result)+'"');
			result = decodeURIComponent(CookieString.substring(offset, end))

		}
	}
	return result;
}
/**
 * Remove a cookie.
 */
function deleteCookie(Name, Path) {
	setCookie(Name, "Deleted", -1, Path)
}

/* ********************* VALUE OUTCOMES ***************** */

function focusTextBox(form) {
	form.amount.focus();
}

function clearTextBox(form) {
	if (form && form.amount) {
		form.amount.value = '';
	}
}

function validateAmt(myform, elementId) {
	if (!validateNumber(myform.amount, false, 'Donation amount', true, 0, 10,
			10000)) {
		myform.amount.select();

		if (document.getElementById(elementId)) {
			if (myform.amount > 10000) {
				document.getElementById(elementId).innerHTML = "Gift cards must be less than $10,000.";
			} else {
				document.getElementById(elementId).innerHTML = "Gift cards must be at least $10.";
			}
		}
		setTimeout( function() {
			myform.amount.focus()
		}, 10);
		return false;
	} else
		return true;
}

function validateOtherAmt(f) {
	if (f.vo_id.value == -1) // validate amount?
	{
		var x = f.amount.value
		x = x.replace(",", "");
		var anum = /(^\d+$)|(^\d+\.\d+$)/
		if (anum.test(x)) {
			// alert("pass test numeric");
		} else {
			// alert("fail test numeric");
			alert("Donation amount must be a whole number greater than US $10.");
			f.amount.value = '';
			f.amount.focus();
			return false;
		}
		if (x >= 10) {
			// alert("pass test >= 10");
		} else {
			// alert("fail test >= 10");
			alert("Donation amount must be a whole number greater than US $10.");
			setTimeout( function() {
				f.amount.focus()
			}, 10);
			f.amount.focus();
			return false;
		}
	}
	return true;
}

/* ********************* EMAIL ** EMAIL ***************** */

/*
 * Functions used to mask email addresses throughout website. Variations on
 * subject line, body or email address style
 */

function mkaddrexternal(addr) {
	document.write('<a href=\"mailto:' + addr + '\">' + addr + '</a>');
}

function mkaddr5(addr, subj, body, label) {
	document.write('<a class="menutab" href=\"mailto:' + addr + '?subject='
			+ subj + '&body=' + body + '\">' + label + '</a>');
}

function mkaddr4(addr, subj, body, label) {
	site = "globalgiving.com";
	document.write('<a href=\"mailto:' + addr + '@' + site + '?subject=' + subj
			+ '&body=' + body + '\">' + label + '</a>');
}

function mkaddr3(addr, label, font) {
	site = "globalgiving.com";
	document.write('<a class=\"' + font + '\" href=\"mailto:' + addr + '@'
			+ site + '\">' + label + '</a>');
}

function mkaddr2(addr, label) {
	site = "globalgiving.com";
	document.write('<a href=\"mailto:' + addr + '@' + site + '\">' + label
			+ '</a>');
}

function mkaddr1(addr, subj) {
	site = "globalgiving.com";
	label = addr + '@' + site;
	document.write('<a href=\"mailto:' + addr + '@' + site + '?subject=' + subj
			+ '\">' + label + '</a>');
}

function mkaddr(addr) {
	site = "globalgiving.com";
	mkaddr2(addr, addr + '@' + site);
}

function protectaddr_projpage(addr, domain, label) {
	document.write('<a href=\"mailto:' + addr + '@' + domain + '\">' + label
			+ '</a>');
}

function protectaddr(addr, domain, label) {
	document.write('<a href=\"mailto:' + addr + '@' + domain + '\">' + label
			+ '</a>');
}

function protectaddr2(addr, domain) {
	document.write('<a href=\"mailto:' + addr + '@' + domain + '\">' + addr
			+ '@' + domain + '</a>');
}

function emailafriend(body, url, lbl) {
	document.write('<a href="mailto:?body=' + escape(body)
			+ 'Check it out at http://www.globalgiving.com/' + url + '">' + lbl
			+ '</a>');
}

function tellafriend(body, lbl) {
	document
			.write('<a href="mailto:?body='
					+ escape(body)
					+ 'Check it out and consider making a donation at http://www.globalgiving.com/'
					+ '\">' + lbl + '</a>');
}

function emailprofile(subject, body, url, lbl) {
	document.write('<a href="mailto:?subject=' + subject + '&body=' + body
			+ escape(url) + ' ">' + lbl + '</a>');
}

function emailsubject(addr, subject, lbl) {
	site = "globalgiving.com"
	document.write('<a href=\"mailto:' + addr + '@' + site + '?subject='
			+ subject + '">' + lbl + '</a>');
}

function emailjob(addr, subject) {
	site = "globalgiving.com"
		document.write('<a href=\"mailto:' + addr + '@' + site + '?subject='
				+ subject + '">' + addr + '@' + site + '</a>');
}

/* ********************* POP UPS ** POP UPS ***************** */

/*
 * Functions that call up a pop-up window. Settings vary for new window. all
 * force focus back to the popup
 */

// simple browser window without features
function popup(url, name, width, height) {
	settings = "toolbar=no,location=no,directories=no,"
			+ "status=no,menubar=no,scrollbars=yes," + "resizable=yes,width="
			+ width + ",height=" + height;
	var myname = name.replace(/ /g, '_'); // no spaces in window name!

	MyNewWindow = window.open(url, myname, settings);
	MyNewWindow.focus();
}

// simple browser window with only a scrollbar
function popup2(url, name, width, height) {
	var settings = "scrollbars,width=" + width + ",height=" + height;
	var myname = name.replace(/ /g, '_'); // no spaces in window name!
	MyNewWindow = window.open(url, myname, settings);
	MyNewWindow.focus();
}

// same as above but with different settings
function popup3(url, name, ht, wd) {
	settings = "toolbar=no,location=no,directories=no,"
			+ "status=no,menubar=no,scrollbars=yes," + "resizable=no,width="
			+ wd + ",height=" + ht;
	var myname = name.replace(/ /g, '_'); // no spaces in window name!
	pop = window.open(url, myname, settings);
	pop.focus();
}

// fully customizable version
function popup4(url, name, settings) {
	var myname = name.replace(/ /g, '_'); // no spaces in window name!
	pop = window.open(url, myname, settings);
	pop.focus();
}

// simple browser window without features and page position
function popup5(url, name, width, height, top, left) {
	settings = "toolbar=no,location=no,directories=no,"
			+ "status=no,menubar=no,scrollbars=1," + "resizable=yes,width="
			+ width + ",height=" + height + ",top=" + top + ",left=" + left;

	var myname = name.replace(/ /g, '_'); // no spaces in window name!
	MyNewWindow = window.open(url, myname, settings);
	MyNewWindow.focus();
}

// simple browser window with only a scrollbar and page position
function popup6(url, name, width, height, top, left) {
	settings = "toolbar=no,location=no,directories=no,"
			+ "status=no,menubar=no,scrollbars=yes," + "resizable=no,width="
			+ width + ",height=" + height + ",top=" + top + ",left=" + left;
	var myname = name.replace(/ /g, '_'); // no spaces in window name!

	MyNewWindow = window.open(url, myname, settings);
	MyNewWindow.focus();
}

/* ********************* DONATIONS ** DONATIONS ***************** */

/*
 * The following are several functions used in the donation pages. They range
 * from taking data out of the URL to display on page to creating hyperlinks to
 * giftany functions and comments for verisign.
 */

// This function lets us grab data out of the URL
function getUrlParm(url, parmname) {
	qndx = url.indexOf("?");
	if (qndx < 0)
		return null;
	parmndx = url.indexOf(parmname, qndx + 1);
	if (parmndx < 0)
		return null;
	eqndx = url.indexOf("=", parmndx);
	if (eqndx < 0)
		return null;
	termndx = url.indexOf("&", eqndx);
	if (termndx < 0) {
		termndx = url.indexOf("#", eqndx);
		if (termndx < 0) {
			return unescape(url.substring(eqndx + 1));
		}
	}
	return unescape(url.substring(eqndx + 1, termndx));
}

// Test to make sure entered donation amount is valid
function is_a_num(number) {
	var tester = number * 1;
	// Check to make sure field is not blank
	if ((number == null) || (number.length == 0)) {
		alert("Please enter a donation amount");
		return false;
	}
	// Check to make sure number is not negative or 0
	if (number < 1) {
		alert("Please enter a positive donation amount");
		return false;
	}
	// Check to make sure number is indeed a number
	if (isNaN(tester) == true) {
		alert("Please enter a valid donation amount");
		return false;
	}
	return true;
}

// Create comment field for verisign and submit verisign form
function descvalue() {
	var url = window.location.href
	// Gathering variables needed for comment field
	var projid = getUrlParm(url, "pid");
	var projtitle = getUrlParm(url, "ptitle");
	var donation = document.amt.AMOUNT.value;
	// Converting data from checkboxes into variables
	if (document.amt.ANON.checked) {
		var anonymous = "a";
	} else {
		var anonymous = "p";
	}
	if (document.amt.NEWSL.checked) {
		var newsletter = "r";
	} else {
		var newsletter = "u";
	}
	// Creating the verisign comment and description field
	document.amt.DESCRIPTION.value = (unescape(projtitle + " (" + projid + ")"));
	document.amt.COMMENT1.value = ("d:-1:" + projid + ":" + anonymous + ":"
			+ newsletter + ":" + donation);
	// Submiting form if donation amount is a valid number
	if (is_a_num(donation) == true) {
		document.amt.submit();
	}
}
function trim(pString) {
	return pString.replace(/^\s+/g, '').replace(/\s+$/g, '');
}
function removeAllSpaces(pString) {
	return pString.replace(/\s+/g, '');
}
function removeAllCommas(pString) {
	return pString.replace(/,+/g, '');
}

/*
 * This function takes several parameters and a DOM element to validate its
 * value is a number. It will validate decimal numbers with specified precision,
 * or] whole numbers with an optional trailing ".00" to handle currency. The
 * parameters: pComponent - reference to the HTML Dom element to be validated
 * showAlert - pass in true or false to tell function whether it should set
 * focus on pComponent and display a javascript alert if no pass. pLabel - the
 * string to prepend to the error message (usually the descriptive field label).
 * pWhole - boolean (true or false) if the number to be validated is integer
 * only pPrecision - applies only if pWhole is false, the number if decimal
 * places (maximum) allowed. pMin - the minimum value allowed for this field
 * pMax - the maximum value allowed for this field
 */
function validateNumber(pComponent, showAlert, pLabel, pWhole, pPrecision,
		pMin, pMax) {
	pComponent.value = removeAllSpaces(pComponent.value);

	var amount = removeAllCommas(pComponent.value);
	var msg;
	var reFloat;
	var valFloat = parseFloat(amount);
	if (isNaN(valFloat)) // first validate entered value is a number
	{
		if (showAlert) {
			alert(pLabel + " is required to be a number between " + pMin
					+ " and " + pMax + ".");
			pComponent.select();
			setTimeout( function() {
				pComponent.focus()
			}, 10);
		}
		return false;
	}
	if (pWhole) // whole number (integer)
	{
		msg = pLabel + " must be an Integer between " + pMin + " and " + pMax
				+ ".";
		// this regexp allows optional ".00" after the number
		reFloat = /^-?[\d,]*\.?0{0,2}$/;
	} else // decimal number with pPrecision decimal places
	{
		msg = pLabel + " must be a decimal number with " + pPrecision
				+ " decimal places between " + pMin + " and " + pMax + ".";
		reFloat = new RegExp("^-?[\\d,]*\\.?\\d{0," + pPrecision + "}$");
	}
	if (!(reFloat.test(amount))) {
		if (showAlert) {
			alert(msg);
			pComponent.select();
			setTimeout( function() {
				pComponent.focus()
			}, 10);
		}
		return false;
	}
	if (valFloat < pMin || valFloat > pMax) // validate between min and max
	{
		if (showAlert) {
			alert(msg);
			pComponent.select();
			setTimeout( function() {
				pComponent.focus()
			}, 10);
		}
		return false;
	}
	return true;
}

// copyright 1999 Idocs, Inc. http://www.idocs.com
// Distribute this script freely but keep this notice in place
function numbersOnly(myfield, e, dec) {
	var key;
	var keychar;

	if (window.event)
		key = window.event.keyCode;
	else if (e)
		key = e.which;
	else
		return true;
	keychar = String.fromCharCode(key);

	// control keys
	if ((key == null) || (key == 0) || (key == 8) || (key == 9) || (key == 13)
			|| (key == 27))
		return true;

	// numbers
	else if ((("0123456789").indexOf(keychar) > -1))
		return true;

	// decimal point jump
	else if (dec && (keychar == ".")) {
		myfield.form.elements[dec].focus();
		return false;
	} else
		return false;
}

// copyright 1999 Idocs, Inc. http://www.idocs.com
// Distribute this script freely but keep this notice in place
function currencyOnly(myfield, e, dec) {
	var key;
	var keychar;

	if (window.event) {
		key = window.event.keyCode;
	} else if (e) {
		key = e.which;
	} else {
		return true;
	}

	keychar = String.fromCharCode(key);

	// control keys
	if ((key == null) || (key == 0) || (key == 8) || (key == 9) || (key == 13)
			|| (key == 27)) {
		return true;
	}
	// numbers
	else if ((("0123456789").indexOf(keychar) > -1)) {
		return true;
	} else {
		// allow one decimal point
		if ("." == keychar || "," == keychar) {
			return true;
		} else {
			return false;
		}
	}
}

// CREATE A MAILTO URL OR MAILTO ANCHOR TAG
function createMailto(sourceForm, targetField, urlType) {
	var to = sourceForm.to.value;
	var cc = sourceForm.cc.value;
	var bcc = sourceForm.bcc.value;
	var subject = sourceForm.subject.value;
	var body = sourceForm.body.value;
	var linkText = sourceForm.linkText.value;

	if (linkText == "") {
		linkText = "Link Text";
	}

	var urltext = "";

	// IF THE VALUE IS SET, INCLUDE IT IN THE URL
	if (to != "") {
		urltext += to;
	} else {
		alert("Sorry, you must fill out the 'To' field");
		sourceForm.to.focus();
		return (1);
	}
	if (cc != "") {
		urltext = addDelimiter(urltext);
		urltext += "CC=" + cc;
	}
	if (bcc != "") {
		urltext = addDelimiter(urltext);
		urltext += "BCC=" + bcc;
	}
	if (subject != "") {
		urltext = addDelimiter(urltext);
		urltext += "Subject=" + escape(subject);
	}
	if (body != "") {
		urltext = addDelimiter(urltext);
		urltext += "Body=" + escape(body);
	}
	if (urlType == "url") {
		urltext = "mailto:" + urltext;
	} else {
		urltext = "<A HREF=\"mailto:" + urltext + "\">" + linkText + "</A>";
	}

	// PUT THE NEW URL IN THE FORM FIELD
	targetField.value = urltext;

	// GIVE THE FIELD FOCUS AND HIGHLIGHT THE TEXT --
	// TO FACILITATE EASY COPYING AND PASTING OF THE NEW URL
	targetField.focus();
	targetField.select();
	return (1);
}

// ADD THE "?" OR "&" NAME/VALUE SEPARATOR CHARACTER
function addDelimiter(inputString) {
	var inString = inputString;

	// IF '?' NOT FOUND, THEN THIS IS THE FIRST NAME/VALUE PAIR
	if (inString.indexOf("?") == -1) {
		inString += "?";
	}
	// ELSE IT'S A SUBSEQUENT NAME/VALUE PAIR, SO ADD THE '&' CHARACTER
	else {
		inString += "&";
	}
	return inString;
}

// TEST THE MAILTO URL -- ASSIGN THE URL TO THE DOCUMENT LOCATION
// TO POP UP THE MESSAGE WINDOW
function testMailto(loc) {
	var doc = loc;

	// IF MAILTO URL IS EMBEDDED IN AN ANCHOR TAG
	if (doc.indexOf("HREF=") != -1) {
		// EXTRACT THE MAILTO URL FROM THE ANCHOR TAG
		var doc = doc.substring(doc.indexOf("HREF=") + 6, doc.indexOf(">") - 1);
	}

	// ASSIGN THE MAILTO URL TO THE DOCUMENT (THIS WILL POP UP A MAIL WINDOW)
	window.location = doc;
}

function viewMailto(mailtoText) {
	alert("URL:\n\n" + mailtoText);
}


/*
 * ********************* VALIDATION FOR RECEIPT FEEDBACK SURVEY
 * *****************
 */

/**
 * Sets the Maxlength for the Text Area, use by calling this in the textarea's
 * onkeyup and onkeydown.
 */
function textCounter(field, maxlimit, displayid) {
	if (field.value.length > maxlimit) {
		field.value = field.value.substring(0, maxlimit);
	}
	if (displayid != null && document.getElementById(displayid) != null) {
		var count = maxlimit - field.value.length;
		document.getElementById(displayid).innerHTML = count + '&nbsp;characters remaining';
	}
}

function checkboxReceiptValidate() {
	// set var checkbox_choice to false
	var checkbox_choice1 = false;
	var checkbox_choice2 = false;
	var checkbox_choice3 = false;
	var checkbox_choice4 = false;
	var checkbox_choice5 = false;
	var checkbox_choice6 = false;
	var comments_choice7 = false;
	// Check if any of the values are true
	if (document.formRecptSurvey.a1.checked) {
		checkbox_choice1 = true;
	}
	if (document.formRecptSurvey.a2.checked) {
		checkbox_choice2 = true;
	}
	if (document.formRecptSurvey.a3.checked) {
		checkbox_choice3 = true;
	}
	if (document.formRecptSurvey.a4.checked) {
		checkbox_choice4 = true;
	}
	if (document.formRecptSurvey.a5.checked) {
		checkbox_choice5 = true;
	}
	if (document.formRecptSurvey.a6.checked) {
		checkbox_choice6 = true;
	}
	if (document.formRecptSurvey.a7.value.length > 0) {
		comments_choice7 = true;
	}

	if (!checkbox_choice1 && !checkbox_choice2 && !checkbox_choice3
			&& !checkbox_choice4 && !checkbox_choice5 && !checkbox_choice6
			&& !comments_choice7) {
		alert("Please select at least one answer and/or\nprovide comments to submit your response.")
		return (false);
	}
	return (true);
}


/** ******************************** */
/*
 * Client-side access to querystring name=value pairs
 * http://adamv.com/dev/javascript/querystring Version 1.2.3 22 Jun 2005 Adam
 * Vandenberg
 */
function Querystring(qs) { // optionally pass a querystring to parse
	this.params = new Object()
	this.get = Querystring_get

	if (qs == null)
		qs = location.search.substring(1, location.search.length)

	if (qs.length == 0)
		return

		// Turn <plus> back to <space>
		// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
		qs = qs.replace(/\+/g, ' ')
	var args = qs.split('&') // parse out name/value pairs separated via &

	// split out each name=value pair
	for ( var i = 0; i < args.length; i++) {
		var value;
		var pair = args[i].split('=')
		var name = unescape(pair[0])

		if (pair.length == 2)
			value = unescape(pair[1])
		else
			value = name

		this.params[name] = value
	}
}

function Querystring_get(key, default_) {
	// This silly looking line changes UNDEFINED to NULL
	if (default_ == null)
		default_ = null;

	var value = this.params[key]
	if (value == null)
		value = default_;

	return value
}

// remove spaces
function removeSpaces(string) {
	return string.replace(/\s*/g, '');
}

/**
 * escape characters for json replace single characters with escaped characters:
 * replace \ with \\. \n with \\n, \r with \\r, and " with \\" So that the
 * server side can decode the string into JSONString
 */
function jsonEscape(string) {
	return string.replace(/\\/g, "\\\\").replace(/\n/g, "\\n").replace(/\r/g,
			"\\r").replace(/"/g, '\\"');
}
/* method for determining which refcode/conversion cookie to set 
   this follows basic logic as requested by Michael 
   refcode cookie: valid 365 days, conversion code cookie: session cookie
   if (refode && no refcode cookie) set both conversion and refcode to refcode 
   if (recode && refcode cookie) only set conversioncode cookie to  new refcode
   if (no refcode) if(ref code cookie) set conversion code cookie to referrer ELSE set refcode and conversion code cookie to referrer 
   if (no refcode &&  no referrer && no cookie) do nothing
   the boolean of forceConverionCode allows to explicitely set a conversion code from a landing page
*/    
function assignRefAndConversionCode(refCode, forceConversionCode){ 
	var GG_REF_CODE ="ggRefCode";
	var GG_CONVERSION_CODE = "ggConversionCode";
	var hasRefCode = refCode!=null;   
	var hasRefCodeCookie = getCookieValue(GG_REF_CODE)!=null; 
	var hasConversionCodeCookie = forceConversionCode ? false : getCookieValue(GG_CONVERSION_CODE)!=null; 

	var refCodeValueToWrite = hasRefCodeCookie ? getCookieValue(GG_REF_CODE) : refCode;
	var conversionCodeValueToWrite = hasRefCode ? refCode : refCodeValueToWrite;

	var referrer = document.referrer; 
	var notGG =  referrer.indexOf("globalgiving")==-1;
	notGG = notGG ? true : referrer.indexOf("globalgiving") > 13;
	if(!hasRefCode){ 
		if(!referrer=="" && notGG) {
			//alert("referred from: " + document.referrer); 
			refCodeValueToWrite = hasRefCodeCookie ? getCookieValue(GG_REF_CODE) : referrer;
			conversionCodeValueToWrite = referrer;   	   
		} 
	} 
	if(notGG && !hasRefCodeCookie && refCodeValueToWrite != null){
		setUnescapedCookie(GG_REF_CODE, refCodeValueToWrite, 365, "/");  
		//alert("set ref code cookie, \ncode=" + getCookieValue(GG_CONVERSION_CODE)+ " refocode="+getCookieValue(GG_REF_CODE));
	}
	if(notGG && !hasConversionCodeCookie && conversionCodeValueToWrite != null)  { 
		setUnescapedCookie(GG_CONVERSION_CODE, conversionCodeValueToWrite, null, "/");
		//alert("set conversion code cookie, \ncode=" + getCookieValue(GG_CONVERSION_CODE)+ " refocode="+getCookieValue(GG_REF_CODE)); 
	}
	// this is a conditional to make sure we convert 
	// the current refcode cookie to a 1 year cookie
	var now = new Date();
	var cutOffDate = new Date(2009,4,15);
	var forceRefCodeCookie = now < cutOffDate;
	if(notGG && hasRefCodeCookie && forceRefCodeCookie){
		setUnescapedCookie(GG_REF_CODE, getCookieValue(GG_REF_CODE), 365, "/"); 	
	}
}
function setUnescapedCookie(name, value, lifespan, access_path) {

	var cookietext = name + "=" + value
	if (lifespan != null) {
		var today = new Date()
		var expiredate = new Date()
		expiredate.setTime(today.getTime() + 1000 * 60 * 60 * 24 * lifespan)
		cookietext += "; expires=" + expiredate.toGMTString()
	}
	if (access_path != null) {
		cookietext += "; PATH=" + access_path
	}
	document.cookie = cookietext
	return null
}
