/* =====================================================================
	JavaScript Library - Portland Community College
	Written by Curtis Harvey <charvey@pcc.edu>, Gabriel McGovern <gabriel.mcgovern@pcc.edu>
	Compress with jmin, or shrinksafe <http://alex.dojotoolkit.org/shrinksafe/>
	Change Log: 
		2006-04-01 gabriel mcgovern: Only popup email form for @pcc.edu addresses
		2006-05-05 gabriel mcGovern: Extra link info [PDF], [DOC], [INTRANET] now added by javascript - Thanks Curtis!
		2006-06-12 gabriel mcgovern: Fixed several inconsistencies with compressed version. 
		2006-07-13 gabriel mcgovern: Added {} to ValidateForm so that it will still work when compressed - allow for longer then 4 character TLD's (.museum)
 									 Expanded validation to use the label's title (if available)
		2006-08-08 gabriel mcgovern: Added updateCopyright() function - replaces 2000 with 2000-current year
									 Extra link info [XLS] now added. Let's keep the file types to a minimum people!
		2006-12-19 gabriel mcgovern: Added inspection to validateForm function - Checks for bad characters in form field 
									 names or ids. Could be expanded to check for other errors. 
		2007-01-08 gabriel mcgovern: Added reset warning to validateForm function.
		2007-03-29 gabriel mcgovern: Added "Show what gnav section we are currently under"
									 						 
 * ===================================================================== */

/* === TEST JAVASCRIPT SUPPORT === */
var DOM = !!(document.getElementById && document.getElementsByTagName); /* Basic W3C DOM Support */
var advDOM = !!(DOM && document.createElement); /* More Advanced W3C DOM Support */


/* === DEBUGING HELPERS === */
var debug = (getURLVars()['debug'] != null);
function dalert(msg) {
	if (debug) alert(msg);
}




/* === EVENT HANDLING (via http://www.scottandrew.com/weblog/articles/cbs-events) === */
function addEvent(elm, evType, fn, useCapture) {
	if (elm.addEventListener) {
		elm.addEventListener(evType, fn, useCapture);
		return true;
	} else if (elm.attachEvent) {
		var r = elm.attachEvent("on"+evType, fn);
		return r;
	} else {
		return false;
	}
}
function removeEvent(elm, evType, fn, useCapture) {
	if (elm.removeEventListener) {
		elm.removeEventListener(evType, fn, useCapture);
		return true;
	} else if (elm.detachEvent) {
		var r = elm.detachEvent("on"+evType, fn);
		return r;
	} else {
		return false;
	}
}

/* === BAD PRESENTATIONAL SCRIPTING, FIXES AND HACKS === */
function badPresentationalScripting() {
	var page = document.getElementById('page');
	var content = document.getElementById('content');
	var main = document.getElementById('main');
	var snav = document.getElementById('snav');
	if (content) {
		/* using JS to set styles to avoid breaking dw/contribute design view - lame I know */
		content.style.position = 'relative';
		if (snav) snav.style.top = '65px';
		/* add corner to #content when using popup version of template */
		if (page && page.className.hasClass('popup')) addCorner(content, 'contentcorner');
	}
	/* add rounded corner to #main */
	if (page && !page.className.hasClass('home') && !page.className.hasClass('sub-home') && main) {
		main.style.position = 'relative';
		addCorner(main, 'maincorner');
	}
	/* add folded corner to form.advanced */
	var i, frm, forms = document.getElementsByTagName('form');
	for (i=0; frm=forms[i]; i++) {
		if (frm && frm.className.hasClass('advanced')){
			frm.style.position = 'relative';
			addCorner(frm, 'foldcorner');
			//alert(frm.parentNode.id);
		}
	}
	/* make sure #snav is not longer than #main */
	fixColumns();
}
function addCorner(elem, cornerId) {
	var o = (typeof elem == 'string') ? document.getElementById(elem) : elem;
	if (!elem) return false;
	var corner = document.createElement('div');
	if (cornerId) corner.id = cornerId;
	corner.className = 'corner'
	elem.appendChild(corner);
	return true;
}
function fixColumns() {
	try { // wrapping in empty try/catch block for silent failure
		var main = document.getElementById('main'), snav = document.getElementById('snav');
		if (!main || !snav) return;
		// store default padding in global variable, needed for runtime changes (show/hide)
		if (window.defaultMainPaddingBottom == null) {
			if (main.currentStyle)
				window.defaultMainPaddingBottom = main.currentStyle.paddingBottom;
			else if (document.defaultView && document.defaultView.getComputedStyle)
				window.defaultMainPaddingBottom = document.defaultView.getComputedStyle(main,'').getPropertyValue('padding-bottom');
		}
		// restore default padding before calculating column heights
		main.style.paddingBottom = window.defaultMainPaddingBottom;
		// add bottom padding to #main to make it at least as tall as snav if shorter
		if (main.offsetHeight < snav.offsetHeight)
			main.style.paddingBottom = parseInt(window.defaultMainPaddingBottom)+snav.offsetHeight-main.offsetHeight+'px';
	} catch(e) { }
}

/* === CLASSNAME FUNCTIONS === */
String.prototype.hasClass = function(cls) {
	return new RegExp('(^| )'+cls+'( |$)').test(this);
};
String.prototype.addClass = function(cls) {
	if (this == '') return cls;
	if (this.hasClass(cls)) return this;
	return this+" "+cls;
};
String.prototype.removeClass = function(cls) {
	return this.replace(new RegExp('(^| )'+cls+'( |$)'), '');
};
function getElementsByClassName(node, cls, tag) {
	if (!DOM) return [];
	var i, elem, elems = node.getElementsByTagName( (tag != null ? tag : '*') ), results = [];
	for (i=0; elem = elems[i]; i++) if (elem.className.hasClass(cls)) results.push(elem);
	return results;
}


/* === URL/PATH/HISTORY INFORMATION/MANIPULATION === */
function getDirs(path) { // returns an array of directory hierarchy
	var folders = path.split('/');
	if (folders[0] == "") folders.shift(); // remove empty first element
	if (re.index.test(folders[folders.length-1])) folders[folders.length-1] = '';
	return folders;
}
function getReferringPage() {
	if (document.referrer) return document.referrer;
	else if (window.opener) return window.opener.location;
	else return '';
}
function getURLVars() {
	var url = document.URL; //used document.URL instead of location because URL is returned as a string, location as an object
	if (!url || url.indexOf('?') < 0) return {};
	var pairs, i, v, vars = {};
	pairs = url.replace(/&(amp;)?/, '&amp;').substring(url.lastIndexOf('?')+1).split('&amp;'); //account for & and &amp; delimeters
	for (i=0; i<pairs.length; i++) {
		v = pairs[i].split('=');
		vars[v[0]] = unescape(v[1]);
	}
	return vars;
}
function populateFormFromGets() {
	if (!DOM) return;
	var id, vars = getURLVars();
	for (id in vars)
		if(document.getElementById(id) && document.getElementById(id).value != null)
			document.getElementById(id).value = unescape(vars[id]);
}

/* === COOKIE MANAGEMENT (via http://www.quirksmode.org/js/cookies.html) === */
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	} else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++)
	{
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}
function eraseCookie(name)
{
	createCookie(name,"",-1);
}

/* === LINKS SETUP === */
function linkSetup() {
	if (!DOM) return;
	var lnks = document.getElementsByTagName('a');
	var i, a, email, subj;
	var reIsPDF = /\.pdf$/i;
	var reIsDOC = /\.doc$/i;	
	var reIsXLS = /\.xls$/i;	
	var reIsIntranet = /intranet\.pcc\.edu/i;
	var reIsPCC = /\.pcc\.edu/i;
	var hrefUrl = unescape(String(location.href));
	var hrefLink = "";
	
	for (i=0; a=lnks[i]; i++) {
		hrefLink = unescape(String(a.href))
		// add extra info for links to non-html documents.
		if (a.hasChildNodes() && (a.getElementsByTagName('img').length == 0) ){ // do not add to links around blanks or images 
			if (reIsPDF.test(a.href)) {
				a.innerHTML += ' <em class="link-type" title="Portable Document Format - www.pcc.edu/help/">[pdf]</em>';
			}
			else if (reIsDOC.test(a.href)) {
				a.innerHTML += ' <em class="link-type" title="Microsoft Word Document - www.pcc.edu/help/">[doc]</em>';
			}
			else if (reIsXLS.test(a.href)) {
				a.innerHTML += ' <em class="link-type" title="Microsoft Excel Document - www.pcc.edu/help/">[xls]</em>';
			}
			else if (reIsIntranet.test(a.href)) {
				if(!reIsIntranet.test(window.location.hostname)){   // do not show intranet links on the intranet.
					a.innerHTML += ' <em class="link-type" title="Only Available on PCC Campus - www.pcc.edu/help/">[intranet]</em>';
				}
			}
			/*	
			if (!reIsPCC.test(a.href)) {
				a.innerHTML += ' <em class="link-type" title="Outside link - www.pcc.edu/help/">[www]</em>';
			}
			*/
		}
		// show what gnav section we are currently under
		//if (a.parentNode.parentNode.id == "gnav" && hrefUrl.indexOf(hrefLink) == 0 ){
		//	a.className = a.className.addClass('current');
		//}
		// add class name of 'current' to links to self (account for index files)
		if (a.href != "" && hrefLink.replace(re.index, '') == hrefUrl.replace(re.index, '')) {
			a.className = a.className.addClass('current');
		}
		// redirect mailto to email form
		if (a.getAttribute('onclick') == null) { // only add an onclick handler if one does NOT already exist
			// email (mailto) links
			if (re.pccemail.test(a.href)) {
				a.onclick = function() {
					var path = "http://www.pcc.edu/resources/web/forms/email/?to="+escape(this.href.replace(/mailto:/,''));
					if (this.title) path += "&amp;subject="+escape(this.title);
					return popup(path, 'form');
				}
				a.onmouseover = function() { window.status = "Send email to "+this.href.replace(/mailto:/, ''); return true; }
				a.onmouseout = function() { window.status = window.defaultStatus; return true; }
			}
			// popup links
			else if (/popup/.test(a.className)) {
				a.onclick = function() {
					var s = /popup-(\w+)/.exec(this.className);
					s = s ? s[1] : 'default';
					return popup(this.href, s);
				}
			}
		}
	}
}
function popup(url, s) {
	if (!url) return true;
	if (window.opener) window.location = url; // if already in a popup just change location
	else window.open(url,'popup'+(new Date().getSeconds()), (s && popups[s]) ? popups[s] : popups.normal);
	return false;
}

/* === ADD FULL COPYRIGHT=== */
function updateCopyright() {
	if (!advDOM) return;
	var copyright = document.getElementById('copyright');
	var currentYear = (new Date()).getFullYear();
	copyright.innerHTML = copyright.innerHTML.replace("2000","2000-"+currentYear);
}
	
/* === ACTIVATE SECTION TABS === 
var reGnav = {			// regex for global nav
		about	:	new RegExp("^/about/(^calendars/)"),
		temp	:	new RegExp("^/temp/(^gabes)")
};
function activateGnav() {
	if (!advDOM) return;
	var currpath = window.location.pathname;
	
	if( reGnav.temp.test(currpath) ){
		tabLink= document.getElementById('gnav-temp').firstChild;
		tabLink.className = tabLink.className.addClass('current');
		
	}

}*/
	
/* === ADD BREADCRUMB TRAIL / DIRECTORY TREE TO PAGE === */
function addDirNav() {
	if (!advDOM) return;
	var stitle = document.getElementById('stitle');
	if (!stitle // no #stitle
		|| document.getElementById('dirnav') // dirnav was created manually
		|| document.getElementById('page').className.hasClass('popup') // no dirnav in popup template
		) return;
	var folders = getDirs(window.location.pathname);
	// only insert when atleast two levels deep (2 folders or one folder + non-index page)
	if (folders.length < 2 || (folders.length == 2 && folders[folders.length-1] == '')) return;
	// remove last element since it represents current page
	if (folders.pop() == '') folders[folders.length-1] = '';
	// insert PCC first
	folders.unshift('PCC');
	// build
	var p, i, j, f, a, href, c = '';
	p = document.createElement('p');
	p.setAttribute('id', 'dirnav');
	for (i=0; i<folders.length; i++) {
		f = unescape(folders[i]);
		if (f == '') continue;
		if (i>0) c += '/'+f;
		f = (fns[c]) ? fns[c] : f.replace(/-/, ' ');
		a = document.createElement('a');
		href = '';
		j = folders.length-i;
		if (j==1) href += "./";
		else while(--j) href += "../";
		a.setAttribute('href', href);
		a.appendChild(document.createTextNode(f));
		p.appendChild(a);
		p.appendChild(document.createTextNode(' \u002f '));
	}
	// insert
	stitle.insertBefore(p, stitle.firstChild);
}

/* === FORM VALIDATION === */
function addFormValidation() {
	if (!DOM) return;
	var i, form, forms = document.getElementsByTagName('form');

	for (i=0; frm=forms[i]; i++) {
		if (frm.onsubmit == null) frm.onsubmit = function() { return validateForm(this); }
		if (frm.onreset == null) frm.onreset = function() { return resetWarning(this); }
	}
}

function resetWarning(frm, s) {  // warn on reset
	return confirm("Are you sure you want to clear the form?\nYou will have to start over..."); 
}
	
var valid = validateForm; // backwards compatiable until I can update all pages
function validateForm(frm, s) {
	if (!DOM || !frm) return;
	var silent = (s || s == 'silent') ? true : frm.className.hasClass('fail-silent') ? true : false;
	var i, j, ok, field, errors = [], devErrors = [];
	for (i in frm.elements) {
		field = frm.elements[i];
		if (field && field.type){										// Inspect form for dev errors
			if (field.name && !re.cfvar.test(field.name)){ 				// Test for invalid name
				devErrors.push( "Invalid field name: \""+field.name+"\"");
			}
			if (field.id && !re.cfvar.test(field.id)){ 					// Test for invalid id
				devErrors.push( "Invalid field id: \""+field.id+"\"");
			}
		}
		if (field && field.className && field.className.hasClass('required')) {
			switch (field.type) {
				case 'text':
				case 'textarea':
				case 'password':
					if (!(/\w+/).test(field.value)) errors.push(field);
					else if (field.className.hasClass('pccemail')) { if (!re.pccemail.test(field.value)) {errors.push(field);} }
					else if (field.className.hasClass('email')) {
						if (field.value.toLowerCase() == 'none') { field.value = 'webadmin@pcc.edu'; }
						else if (!re.email.test(field.value)) { errors.push(field);}
					}
					break;
				case 'select-one':
				case 'select-multiple':
					if (field.selectedIndex < 0 || field.options[field.selectedIndex].value == "null") errors.push(field);
					break;
				case 'radio':
					for (j=0, ok=false; j<frm[field.name].length; j++) {
						if (frm[field.name][j].checked) {
							ok = true;
							break;
						}
					}
					if (!ok) {
						for (j=0, ok=false; j<errors.length; j++) {
							if (errors[j].name == field.name) {
								ok = true;
								break;
							}
						}
						if (!ok) errors.push(field);
					}
					break;
				case 'checkbox':
					if (!field.checked) errors.push(field);
					break;
			}
		}
	}
	if (devErrors.length > 0) {
		var mess = "Warning - this form contains errors...\n\n";
		for (i in devErrors) {mess += "     "+devErrors[i]+"\n";}
		mess += "\nPlease contact webteam@pcc.edu\n";
		alert(mess);
		return false;
	}
	else if (errors.length > 0) {
		if (!silent) {
			var mess = "The form appears to be incomplete, please include...\n\n";
			for (i in errors) {
				// If element has a title
				if( errors[i].title ){ j = errors[i].title; }
				// Or, if the label has a title
				else if( (errors[i].parentNode.nodeName == "LABEL") && (errors[i].parentNode.title) ){ j = errors[i].parentNode.title; }
				// Otherwise, use the element name
				else{ j =  errors[i].name; }
				mess += "    * "+j+'\n';
			}
			alert(mess);
		}
		errors[0].focus();
		return false;
	}
	return true;
}
function getLabel(field) {
	var i, labels = document.getElementsByTagName("label");
	for (i=0; i<labels.length; i++) {
		if (labels[i].htmlFor == field.id) return labels[i];
	}
	return null;
}