/* ////////////////////////////////////////////////////////

   JAVASCRIPT FUNCTIONS
   General functions for client-side JavaScript.

//////////////////////////////////////////////////////// */

/**
 * Test browser's feature compatibility.
 */
function browserTest() {
	// Test for cookies turned off -- on home page only, to keep from infinitely repeating dialog box
	if ((location.pathname == "/" || location.pathname == "/index.php") && !navigator.cookieEnabled) {
		if (confirm("You appear to have cookies turned off in your web browser. This site requires cookies to function properly.\n\nClick OK for more information about why our site requires cookies.")) {
			location.href = "/jscookies.php";
		}
	}
	// Test for unsupported browser -- only if not already tested
	if (!getCookie("browser-tested") && !document.getElementById) {
		if (confirm("You appear to be using an unsupported browser. This site may not function properly with your current web browser software. Would you like to view the system requirements page?")) {
			setCookie("browser-tested",true);
			location.href = "/sysreq.php";
		}
	}
	setCookie("browser-tested",true);
}

/**
 * General-purpose confirmation message to display before proceeding to a new URL.
 * 
 * @param	string	url			URL to proceed to upon confirmation.
 * @param	int		msgcode		Code for predefined message to display in confirmation box.
 */
function confirmAction(url,msgcode) {
	var msg;
	switch (msgcode) {
		case 1:
			msg = "Are you sure you wish to continue?\nUnsaved changes will be lost.";
			break;
		default:
			msg = "Are you sure?\nThis action cannot be undone.";
			break;
	}
	if (confirm(msg)) {
		location.href = url;
	}
	else {
		return false;
	}
}

/**
 * General-purpose confirmation message to display before proceeding to submit a delete request.
 * 
 * @param	string	f	DOM ID of form.
 */
function confirmDelete(f) {
	var cnf = confirm("Are you sure you wish to delete the checked items?\nThis action cannot be undone.");
	if (cnf) {
		if (f.process) { f.process.value = "false"; }
		if (f.mode) { f.mode.value = "delete"; }
		f.submit();
	}
	else {
		return false;
	}
}

/**
 * Determine number of days in a given month.
 * 
 * @param	int		m	Month.
 * @param	int		y	Year.
 * @return				Integer representing number of days in requested month.
 */
function daysInMonth(m,y) {
	if (m == 2) {
		if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) {
			return 29;
		}
		else {
			return 28;
		}
	}
	else if (m == 4 || m == 6 || m == 9 || m == 11) {
		return 30;
	}
	else {
		return 31;
	}
}

/**
 * Delete a cookie.
 * Source: http://webreference.com/js/column8/functions.html
 * 
 * @param	string	name	Name of the cookie.
 * @param	string	path	Path to which the cookie applies.
 * @param	string	domain	Domain to which the cookie applies.
 */
function deleteCookie(name, path, domain) {
  if (getCookie(name)) {
    document.cookie = name + "=" +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}

/**
 * Standard message to apply to any features not implemented on a demo site.
 */
function demoAlert() {
	alert("This feature is not available in the demo version.");
	return false;
}

/**
 * Target a link to a new blank window from a pop-up.
 * 
 * @param	string	ln			DOM ID of link.
 */
function fixTarget(ln) {
	if (window.opener) {
		ln.target = "_blank";
	}
}

/**
 * Reset form values on page load. Applies to Safari only.
 */
function formReset() {
	if (navigator.userAgent.indexOf("Safari") != -1) {
		for (i = 0; i <= document.forms.length; i++) {
			if (document.forms[i]) {
				document.forms[i].reset();
			} 
		}
	}
}

/**
 * Get a cookie.
 * Source: http://webreference.com/js/column8/functions.html
 * 
 * @param	string	name	Name of the cookie.
 * @return					String containing cookie data.
 */
function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else
    begin += 2;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1)
    end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}


/**
 * Initiate a new XMLHttpRequest object (for AJAX)
 * Source: http://www.dynamicajax.com/fr/AJAX_Hello_World-271_290_322.html
 */
function getXMLHttpRequestObject() {
	// Non-IE browsers
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	}
	// IE
	else if (window.ActiveXObject) {
		return new ActiveXObject("Microsoft.XMLHTTP");
	}
	// Unsupported browsers
	else {
		alert("Your browser doesn't support the XmlHttpRequest object.  Better upgrade to Firefox.");
	}
}

/**
 * Hide a div. Good for "Please wait" messages.
 * 
 * @param	string	div_id		DOM ID of link.
 */
function hideDiv(div_id) {
	if (document.getElementById) {
		elem = document.getElementById(div_id);
	}
	else if (document.all) {
		elem = document.all.div_id;
	}
	else if (document.layers) {
		elem = document.div_id;
	}
	if (elem) {
		elem.style.display = "none";
	}
}

/**
 * Clean up a keycode: convert all letters to uppercase and strip non-alphanumeric characters.
 * 
 * @param	string	str		The keycode string as entered by the user.
 * @return					Cleaned-up string.
 */
function keycodeCleanup(str) {
	str = str.toUpperCase();
	str = str.replace(/[^A-Z0-9]/g,'');
	return str;
}

/**
 * Return current date and time in MySQL format.
 * 
 * @return					Date and time formatted as a MySQL datetime string.
 */
function mysqlTimestamp() {
	var timestamp = new Date();
	var y = "" + timestamp.getFullYear();
	var m = "" + (timestamp.getMonth() + 1);
	var d = "" + timestamp.getDate();
	var h = "" + timestamp.getHours();
	var n = "" + timestamp.getMinutes();
	var s = "" + timestamp.getSeconds();
	if (m.length == 1) { m = "0"+m; }
	if (d.length == 1) { d = "0"+d; }
	if (h.length == 1) { h = "0"+h; }
	if (n.length == 1) { n = "0"+n; }
	if (s.length == 1) { s = "0"+s; }
	return y+"-"+m+"-"+d+" "+h+":"+n+":"+s;
}

/**
 * Format a number as a price.
 * 
 * @param	float	num		The number to format.
 * @param	string	sym		Currency symbol.
 * @return					Formatted price string.
 */
function numToPrice(num,sym) {
	if (!sym) { sym = "$"; }
	var out = sym;
	// Round to two decimal places
	num = String((Math.round(num*100))/100);
	// Convert to string
	if (num.indexOf(".") == -1) {
		out += num + ".00";
	}
	else if (num.substr(num.indexOf(".")).length == 2) {
		out += num + "0";
	}
	else {
		out += num;
	}
	return out;
}

// Variables for window opened by popUp() function.
var newWindow;
var newWindowName = "PopUp" + Math.round(Math.random()*10000);
/**
 * Open a new pop-up window with defined parameters.
 * 
 * @param	string	url				URL to open in new window.
 * @param	int		xsize			Horizontal size of new window.
 * @param	int		ysize			Vertical size of new window.
 * @param	string	resize			Set to "yes" or "no" to determine if window will be resizable.
 * @param	string	scrollbars		Set to "yes" or "no" to determine if window will have scrollbars.
 */
function popUp(url,xsize,ysize,resize,scrollbars) {
	if (!resize) {
		resize = "no";
	}
	if (!scrollbars) {
		resize = "yes";
	}
	if (newWindow && !newWindow.closed) {
		newWindow.focus();
		newWindow.close();
	}
	if (!xsize) { xsize = 400; }
	if (!ysize) { ysize = 300; }
	var xpos = 50;
	var ypos = 50;
	// Center pop-up over current window, if possible
	if (window.screenX && window.outerWidth) {
		xpos = window.screenX + ((window.outerWidth - xsize) / 2);
	}
	if (window.screenY && window.outerHeight) {
		ypos = window.screenY + ((window.outerHeight - ysize) / 2);
	}
	newWindow = window.open(url,newWindowName,"width=" + xsize + ",height=" + ysize + ",screenX=" + xpos + ",screenY=" + ypos + ",directories=no,location=no,menubar=no,resizable=" + resize + ",scrollbars=" + resize + ",toolbar=no");
}

/**
 * Set a cookie.
 * Source: http://webreference.com/js/column8/functions.html
 * 
 * @param	string	name	Name of the cookie.
 * @param	string	value	Value for the cookie.
 * @param	string	expires	Date when cookie expires expressed as a UTC string.
 * @param	string	path	Path to which the cookie applies.
 * @param	string	domain	Domain to which the cookie applies.
 * @param	string	secure	Whether or not the cookie is secure.
 */
function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) +
      ((expires) ? "; expires=" + expires : "") +
      ((path) ? "; path=" + path : "") +
      ((domain) ? "; domain=" + domain : "") +
      ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}

/**
 * Set page offset for positioning on reload.
 * 
 * @param	string	f		DOM ID of form.
 */
function setPageOffset(f) {
	// Internet Explorer 6
	if (document.documentElement && document.documentElement.scrollTop) {
		f.value = document.documentElement.scrollTop;
	}
	// Internet Explorer 5
	else if (document.body)	{
		f.value = document.body.scrollTop;
	}
	// Standard
	else {
		f.value = window.pageYOffset;
	}
}

/**
 * Limit the size of the value entered in a textarea form field.
 * 
 * @param	string	tfld	DOM ID of: document.formname.textareaname
 * @param	string	cfld	DOM ID of: document.formname.countboxfieldname
 * @param	int		size	Maximum character length allowed.
 */
function textareaCount(tfld,cfld,size) {
	// Truncate field at size
	if (tfld) {
		if (tfld.value.length > size) {
			tfld.value = tfld.value.substr(0,size);
		}
	}
	// Update counter box
	if (cfld) {
		cfld.value = size - tfld.value.length;
	}
}

/**
 * Turn a div on or off and adjust a toggle image accordingly.
 * 
 * @param	string	div_id		DOM ID of div to toggle.
 * @param	string	img_name	NAME attribute of image to swap.
 * @param	string	img_folder	Path to folder containing swap images.
 * @param	string	img_opened	Filename for "opened" image.
 * @param	string	img_closed	Filename for "closed" image.
 * @param	string	passfield	Form field on page to set to match toggle status (for use on reload).
 * @param	string	display		Pass "none" or "block" to force a status rather than simply toggling.
 */
function toggler(div_id,img_name,img_folder,img_opened,img_closed,passfield,display) {
	var elem = "";
	if (document.getElementById) {
		elem = document.getElementById(div_id);
	}
	else if (document.all) {
		elem = document.all.div_id;
	}
	else if (document.layers) {
		elem = document.div_id;
	}
	if (display && elem) {
		elem.style.display = display;
		if (img_name) {
			if (display == "none") { img_name.src = img_folder + img_closed; }
			else { img_name.src = img_folder + img_opened; }
		}
		if (passfield) {
			passfield.value = display;
		}
	}
	else if (elem.style.display == "block") {
		elem.style.display = "none";
		if (img_name) { img_name.src = img_folder + img_closed; }
		if (passfield) {
			passfield.value = "none";
		}
	}
	else if (elem) {
		elem.style.display = "block";
		if (img_name) { img_name.src = img_folder + img_opened; }
		if (passfield) {
			passfield.value = "block";
		}
	}
}

/**
 * Trim whitespace from beginning and end of a string.
 * 
 * @param	string	s	The string to process.
 * @return				Trimmed string.
 */
function trim(s) {
	// Remove leading spaces and carriage returns
	while ((s.substring(0,1) == ' ') || (s.substring(0,1) == '\n') || (s.substring(0,1) == '\r')) {
		s = s.substring(1,s.length);
	}
	// Remove trailing spaces and carriage returns
	while ((s.substring(s.length-1,s.length) == ' ') || (s.substring(s.length-1,s.length) == '\n') || (s.substring(s.length-1,s.length) == '\r')) {
		s = s.substring(0,s.length-1);
	}
	return s;
}

/**
 * Determine if a date is valid (e.g. February 30, 2005 is not a valid date).
 * 
 * @param	string	m			The month in the date.
 * @param	string	d			The day number in the date.
 * @param	string	y			The year in the date.
 * @return						Boolean value.
 */
function validDate(m,d,y) {
	if (m && d && y) {
		// Year must be a positive integer... no B.C.E. here!
		if (isNaN(y) || y <= 0) {
			return false;
		}
		// Check number of days in month
		else {
			// February
			if (m == 2) {
				if (d > 29) { return false; }
				// Leap year day
				else if (d == 29) {
					// Leap years
					if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) {
						return true;
					}
					// Non-leap years
					else {
						return false;
					}
				}
				else { return true; }
			}
			// April, June, September, November
			else if (m == 4 || m == 6 || m == 9 || m == 11) {
				if (d > 0 && d < 31) { return true; } else { return false; }
			}
			// 31-day months
			else {
				if (d > 0 && d < 32) { return true; } else { return false; }
			}
		}
	}
	// Missing one or more values
	else {
		return false;
	}
}

/**
 * Determine if a string conforms to standard email address format.
 * 
 * @param	string	email		The string to validate.
 * @return						Boolean value.
 */
function validEmail(email) {
	// Email cannot be null or empty
	if (!email || email == "") {
		return false;
	}
	// Email address must be at least 5 characters long
	else if (email.length < 5) {
		return false;
	}
	// Spaces and commas are explicitly disallowed (other disallowed characters are not checked)
	else if (email.indexOf(" ") > -1 || email.indexOf(",") > -1) {
		return false;
	}
	// @ must appear once and be in at least the second position
	else if (email.indexOf("@") != email.lastIndexOf("@") || email.indexOf("@") < 1) {
		return false;
	}
	// . must appear at least 1 character after @ and must be at least 2 characters from end
	else if (email.lastIndexOf(".") <= (email.lastIndexOf("@") + 1) || email.lastIndexOf(".") > email.length - 2) {
		return false;
	}
	else {
		return true;
	}
}

/**
 * AKALOO: Redirect window to Learner Center if not in a pop-up
 * Does not work well; do not use.
 */
function akalooLCRedirect() {
	if (!window.opener && location.href.indexOf('/learner') == -1) {
		location.replace("/learner/");
	}
}
