//JavaScript Document

/*====================================================================
//NOTE: Requires jQuery 1.4.2 or greater and jQueryUI 1.8.1 or greater
======================================================================*/

var $j = jQuery.noConflict();
var psRTELoaded = false;

//psDateWidget was here...
//This script loads external .js files if the dependent objects exist on a page
var __maxlength_count = 0;
var __maxlength_tracker = {};	// key = id, value = function to call when it has focus
var __maxlength_curFocus = null;
function handleTextAreaMaxLength(el, maxlen) {
	if (maxlen > 0) {
		// If the textarea does not have an id, give it one. We need the id to
		// track when the textarea gets focus.
		var textAreaId = el.attr("id");
		if (!textAreaId) {
			textAreaId = "__maxlength_textarea"+__maxlength_count;
			el.attr("id", textAreaId);
		}
		
		// Add in the display part
		var id = "__maxlength_count"+__maxlength_count;
		
		// See which message to use. If the field is < 1000 characters, don't even need to worry
		// about possibly exceeding the 4000B limit, so we'll just say n characters left instead of
		// about n left.
		var charsLeftKey = "psx.js.scripts.psbehaviors.n_characters_left";
		if (maxlen > 1000) charsLeftKey = "psx.js.scripts.psbehaviors.about_n_characters_left";
		
		el.after ("<p class='textareaCounter'>"+pss_text(charsLeftKey, ["<span id='"+id+"'>"+maxlen+"</span>"])+"</p>");
		__maxlength_tracker[textAreaId] = function () {
			var e2 = el.get(0);
			maxlength(e2, maxlen, id);
		};
		__maxlength_tracker[textAreaId]();		// Call it once to set the initial # characters
		
		// Finally, add on focus/blur events to keep track of which of these guys has focus
		el.focus (function () {
			__maxlength_curFocus = $j(this).attr("id");
		});
		el.blur (function () {
			if (__maxlength_curFocus == $j(this).attr("id")) {
				__maxlength_curFocus = null;
			}
		});
		__maxlength_count++;
	}
}

function jsLazyLoader(){
	// Deal with maxlength annotations. We'd like to just use the maxlength attribute,
	// but unfortunately struts2 doesn't let you pass that.
	if ( $j('textarea[class^="maxlength"]').length) {
		$j('textarea[class^="maxlength"]').each (function() {
			var el = $j(this);
			var classList = el.attr('class').split(/\s+/);
			var maxlen = 0;
			$j.each( classList, function(index, item){
			    maxlen = item.substr(9);
			});
			handleTextAreaMaxLength(el, maxlen);
		});
	}

	if ( $j('textarea[maxlength]').length) {
		$j('textarea[maxlength]').each (function() {
			var el = $j(this);
			handleTextAreaMaxLength(el, el.attr("maxlength"));
		});
	}

	// If there were any max length counter areas set up, set up a periodic length checker.
	if (__maxlength_count) {
		setInterval(function() {
			// Get the current focus id. This allows us to only do checking on the textarea
			// that currently has focus.
			if (__maxlength_curFocus && __maxlength_tracker[__maxlength_curFocus]) {
				__maxlength_tracker[__maxlength_curFocus]();
			}
		}, 250);
	}

	//Loads calendar injection code file using jQuery getScript()
	if( $j( 'input.psDateWidget' ).length ){
		$j.getScript("/scripts/psDateWidget.js", function(){});
	}
	if( $j( 'input.psDateWidget.psDateHighlight' ).length ){
		$j.getScript("/scripts/psDateWidgetHighlight.js", function(){});
	}
	if( $j('textarea.psRTE').length && !psRTELoaded) {
		$j.getScript("/scripts/markitup/jquery.markitup.js", function() {
			$j.getScript("/scripts/markitup/sets/html/set.js", function() {
				$j.getScript("/scripts/singleField_translation.js", function() {
				
				initPsRTE();		// instead of loading psRTE.js
				
				//Load style sheets for the html widget
				$j("head").append("<link>");
				skinsCSS = $j("head").children(":last");
				skinsCSS.attr({
				      rel:  "stylesheet",
				      type: "text/css",
				      href: "/scripts/markitup/skins/simple/style.css"
				    });
				$j("head").append("<link>");
				setCSS = $j("head").children(":last");
				setCSS.attr({
				      rel:  "stylesheet",
				      type: "text/css",
				      href: "/scripts/markitup/sets/html/style.css"
				    });
				
				psRTELoaded = true;
				});
			});
		});
	}
	
	//Loads psRadioDiv code file using jQuery getScript()
	if( $j( 'select[radioDivPre], input[type="checkbox"].radioDivPre, input[type="radio"].radioDivPre' ).length ){
		$j.getScript("/scripts/psRadioDiv.js", function(){});
	}

	//Loads the "inlineDiff" presentation
	if( $j( 'ul.inlineDiff' ).length ){
		$j.getScript("/scripts/diff.js", function(){});
		
		// There might be more than one on the page ... want to treat each one separately.
		$j( 'ul.inlineDiff' ).each (function() {
			var el = $j(this);
			var parts = el.find("li");
			
			// Right now, only know how to deal with it when there are two <li> elements
			if (parts.length == 2) {
				// Hide the original list
				el.hide();

				// See if any title is desired
				var insTitleHTML, delTitleHTML;
				var delTitle = $j(parts[0]).attr("title");
				if (delTitle) delTitleHTML = pss_text("psx.js.scripts.psbehaviors.deleted_xx", [delTitle]); else delTitleHTML = pss_text("psx.js.scripts.psbehaviors.deleted");
				var insTitle = $j(parts[1]).attr("title");
				if (insTitle) insTitleHTML = pss_text("psx.js.scripts.psbehaviors.added_xx", [insTitle]); else insTitleHTML = pss_text("psx.js.scripts.psbehaviors.added");
				
				wDiffHtmlDeleteStart = '<del title="'+delTitleHTML+'">';
				wDiffHtmlDeleteEnd   = '</del>';
				wDiffHtmlInsertStart = '<ins title="'+insTitleHTML+'">';
				wDiffHtmlInsertEnd   = '</ins>';

				// Create new element
				var oldText = $j(parts[0]).html();
				var newText = $j(parts[1]).html();
				var newElHTML = "<p>"+WDiffString(oldText,newText)+"</p>";
				el.after($j(newElHTML));
			}
		});

	}
	
	/*if( $j( '.tableToGrid' ).length ){
		$j.getScript("/scripts/jqgrid-i18n/grid.locale-en.js", function(){});
		$j.getScript("/scripts/jquery.jqGrid.min.js", function(){});
	}*/
}

function initPsRTE() {
	var ccEditor = $j('.psRTE');
	
	ccEditor.each (function (index, el) {
		// Check for search hints class
		var settings = {
			    nameSpace:       "html", // Useful to prevent multi-instances CSS conflict
			    onShiftEnter:    {keepDefault:false, replaceWith:'<br />\n'},
			    onCtrlEnter:     {keepDefault:false, openWith:'\n<p>', closeWith:'</p>\n'},
			    onTab:           {keepDefault:false, openWith:'    '},
			    previewInWindow: 'width=800, height=600, resizable=yes, scrollbars=yes',
			    markupSet:  [
			        {name:'Heading 1', key:'1', openWith:'<h1(!( class="[![Class]!]")!)>', closeWith:'</h1>', placeHolder:'Your title here...' },
			        {name:'Heading 2', key:'2', openWith:'<h2(!( class="[![Class]!]")!)>', closeWith:'</h2>', placeHolder:'Your title here...' },
			        {name:'Heading 3', key:'3', openWith:'<h3(!( class="[![Class]!]")!)>', closeWith:'</h3>', placeHolder:'Your title here...' },
			        {name:'Heading 4', key:'4', openWith:'<h4(!( class="[![Class]!]")!)>', closeWith:'</h4>', placeHolder:'Your title here...' },
			        {name:'Heading 5', key:'5', openWith:'<h5(!( class="[![Class]!]")!)>', closeWith:'</h5>', placeHolder:'Your title here...' },
			        {name:'Heading 6', key:'6', openWith:'<h6(!( class="[![Class]!]")!)>', closeWith:'</h6>', placeHolder:'Your title here...' },
			        {name:'Paragraph', openWith:'<p(!( class="[![Class]!]")!)>', closeWith:'</p>'  },
			        {separator:'---------------' },
			        {name:'Bold', key:'B', openWith:'<strong>', closeWith:'</strong>' },
			        {name:'Italic', key:'I', openWith:'<em>', closeWith:'</em>'  },
			        {name:'Stroke through', key:'S', openWith:'<del>', closeWith:'</del>' },
			        {name:'Underline', key:'U', openWith:'<span style="text-decoration: underline">', closeWith:'</span>' },
			        {separator:'---------------' },
			        {name:'Ul', openWith:'<ul class="text">\n', closeWith:'</ul>\n' },
			        {name:'Ol', openWith:'<ol class="text">\n', closeWith:'</ol>\n' },
			        {name:'Li', openWith:'<li>', closeWith:'</li>' },
			        {separator:'---------------' },
			        {name:'Picture', key:'P', replaceWith:'<img src="[![Source:!:http://]!]" alt="[![Alternative text]!]" />' },
			        {name:'Link', key:'L', openWith:'<a href="[![Link:!:http://]!]"(!( title="[![Title]!]")!)>', closeWith:'</a>', placeHolder:'Your text to link...' },
			        {separator:'---------------' },
			        {name:'Box', replaceWith:'\n<div class=\"box-round\">\n    <h2>Your title here...<\/h2>\n    <p>Your content here...<\/p> \n<\/div>\n' },
			        {name:'Table', replaceWith:'\n<!-- This is a standards driven table. there are no styles, borders, widths and there is a header row--> \n   <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"grid\" id=\"tableUniqueID\"> \n   <CAPTION>This text appears above the table<\/CAPTION>\n   <thead> \n     <tr> \n       <th>H1 content<\/th> \n       <th>H2 content<\/th> \n       <th>H3 content<\/th> \n     <\/tr> \n   <\/thead> \n   <tfoot> \n     <tr> \n       <td colspan=\"3\">This will display at the bottom of the table. Ideal for legends.<\/td> \n         <\/tr> \n   <\/tfoot> \n   <tbody> \n     <tr> \n       <td>R1C1 content<\/td> \n       <td>R1C2 content<\/td> \n       <td>R1C3 content<\/td> \n     <\/tr> \n     <tr> \n       <td>R2C1 content<\/td> \n       <td>R2C2 content<\/td> \n       <td>R2C3 content<\/td> \n     <\/tr> \n    <\/tbody> \n   <\/table> \n' }
			    ]
			};
		
		var jel = $j(el);
		if (jel.hasClass("psRTESearch")) {
			 settings = $j.extend(true, {}, settings);
			 var markupSet = settings.markupSet;

			 markupSet.push({name:'Translation Hints', call: function() { 
				 var toLangField = $j(el).attr('tolang');
				 
				 var fromLanguage = $j($j(el).attr('fromlang')).val(); 
				 var toLanguage = $j(toLangField).val(); 
				 
				 handleSelectedText(fromLanguage, toLanguage);
			 }});
		}
		jel.markItUp(settings);
	});
}

//A way to initiate some common UI widgets from dialogs
function initBehaviors(){
	jsLazyLoader();
	
    /* Reloading "alsoResize" plugin to correct popup bounding issue (jQuery bug 4603/5559).
     * This code snippet was taken from jquery-ui-1.8.1.custom.min.js and modified to use the jQuery alias
     * in this script. It reloads the "alsoResize" plugin, because in that file the "alsoResize" plugin
     * is loaded prior to the "container" plugin, which causes "alsoResize" to fail to respect the bounds
     * of the container. 
     * 
     * Remove this block of code when jQuery is fixed.
     */
	$j.ui.plugin.add("resizable","alsoResize",{start:function(){
	var b=$j(this).data("resizable").options,a=function(c){$j(c).each(function(){
	$j(this).data("resizable-alsoresize",{width:parseInt($j(this).width(),10),
	height:parseInt($j(this).height(),10),left:parseInt($j(this).css("left"),10),top:parseInt($j(this).css("top"),10)})})};
	if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}
	else $j.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(){
	var b=$j(this).data("resizable"),a=b.options,c=b.originalSize,e=b.originalPosition,g={height:b.size.height-c.height||0,width:b.size.width-c.width||0,top:b.position.top-e.top||0,left:b.position.left-e.left||0},
	f=function(h,i){$j(h).each(function(){var j=$j(this),l=$j(this).data("resizable-alsoresize"),p={};
	$j.each((i&&i.length?i:["width","height","top","left"])||["width","height","top","left"],function(n,o){
	if((n=(l[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(/relative/.test(j.css("position"))&& $j.browser.opera){
	b._revertToRelativePosition=true;j.css({position:"absolute",top:"auto",left:"auto"})}j.css(p)})};
	typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?$j.each(a.alsoResize,function(h,i){f(h,i)}):f(a.alsoResize)},stop:function(){
	var b=$j(this).data("resizable");if(b._revertToRelativePosition&&$j.browser.opera){b._revertToRelativePosition=false;
	el.css({position:"relative"})}$j(this).removeData("resizable-alsoresize-start")}});
	// END: Fix for jQuery bug 4603/5559
	
	$j('div.tabs').tabs();
	$j('h2.accordion').accordion();
	$j('#psDialog button.cancel').live('click',function(){$j('#psDialog').dialog('close');});
	//ajax form submit button
	$j('#psDialog button[type=submit]').click(function(){submitFormWithAjax($('#psDialog').find('form'));});
	//Zebra stripes
	$j('fieldset > div:odd:visible').addClass('alt');
	$j('fieldset > div:even:visible').removeClass('alt');
	//YUI style kill later
	$j('.bd tr:even').addClass('alt');
	
	// For any dialog with class "linkClose", unless the specific links have "noClose" on them,
	// close the dialog when the user clicks them.
	$j('.linkClose a:not(.noClose)').click(function(){$j('#psDialog').dialog('close');});
	
	$j('.dialog, .dialogC, .dialogM, .dialogR, .dialogF, .dialogDiv, .dialogDivC, .dialogDivM, .replaceNext').css('visibility','visible'); //Dialog links are hidden till ready this reveals them
	var dialogObjects = '.dialog, .dialogC, .dialogM, .dialogR, .dialogF, .dialogDiv, .dialogDivC, .dialogDivM';
	$j(dialogObjects).each(function() {
		var url = $j(this).attr('href');
		$j(this).attr('href', ''); //to avoid clicking on link if page did not load completely
		if (url == '') {
			url = $j(this).attr('dialogContent');
		}
		if (url) {
			$j(this).attr('dialogContent', url); //will be restored to href in function psDialog()
		}
	});
}


//Parent portal active nav highlighting function
function setActive() {
	var setActive = $j('#activeNav').val();
	$j(setActive).addClass('selected');
}

//expands or collapses an h2 with class="toggle collapsed" or class="toggle expanded" and has a span with a checkbox
function psEnableCheck(){
	$j('h2 input:checkbox:enabled').each( function() {
	var checked = $j(this).attr('checked');
	var heading = $j(this).parentsUntil('.box-round').last();
	var content = $j(this).parentsUntil('.box-round').next('.settings');
		 if(checked){
			content.show();
			heading.removeClass('collapsed').addClass('toggle expanded');//adds classes if they aren't present
		 }else{
			 content.hide();
			 heading.removeClass('expanded').addClass('toggle collapsed');
		}
	});
}

//turns h2 with class="toggle collapsed" or class="toggle expanded" toggle-able widget	
function psToggle(){
	//this is a toggle replacement for the flipvis code
	var togCol = $j(this).hasClass("expanded");
//	changes the class on the header/control
	if (togCol) {
		$j(this).removeClass('expanded').addClass('collapsed');
	} else{
		$j(this).removeClass('collapsed').addClass('expanded');
	}
	$j(this).next().toggle();//hides/shows the next sibling object (div, fieldset, etc)
}
//Toggles all the toggles on a page, constrained to an id'd parent object
function psToggleAll(direction, target){
	var targEl = target + ' .toggle';
	if (direction == 'expand') {
		$j(targEl).each(function(){
			$j(this).removeClass('collapsed').addClass('expanded');
			$j(targEl).next().show();
		});
	} else if (direction == 'collapse'){
		$j(targEl).each(function(){
			$j(this).removeClass('expanded').addClass('collapsed');
			$j(targEl).next().hide();
		});
	}
	
}

/**
 * Drop-in safer replacement for standard jQuery ajax method. The standard method is not
 * very graceful when it comes to session timeouts, etc. We'll deal with those situations here.
 * @param opts hash of options
 * @throws "ajax_error" if some error occurred other than session timeout/logoff from another user logging in
 */
function psAjax (opts) {
	// If there's no error handler (likely there isn't), add it here. Let's *hope* the developer
	// doesn't just catch the error condition and ignore it. :-O
	if (!opts.error) {
		opts.error = function (jqXHR, textStatus, errorThrown) {
			psAjaxError();
		};
	}
	
	// Replace the success handler (if there is one) with a safer one.
	var successHandler = opts.success;
	opts.success = function(data, textStatus, jqXHR) {
		// Check that the response looks legal for an Ajax call. If it's not, 
		// this method will never return.
		psCheckAjaxResponse(jqXHR.status, data);
		
		// Looked ok, pass it on.
		if (successHandler) successHandler(data, textStatus, jqXHR);
	};
	
	// Finally, make the real jQuery ajax call
	$j.ajax (opts);
}

/**
 * Drop-in safe replacement for standard jQuery load method. The standard method is convenient, but it's not
 * very graceful when it comes to session timeouts, etc. We'll deal with those situations here.
 * @param content the URL to load
 * @param success success handler
 * @throws "ajax_error" if some error occurred other than session timeout/logoff from another user logging in
 */
$j.fn.psLoad = function (content, success) {
	var el = this;
	psAjax({ url: content, type: "GET", cache: false,
		success: function(responseText, textStatus, xhr) {
			// If we get here, the response looks good. Replace the element.
			el.html(responseText);
			
			// Finally, call the success callback
			if (success) success();
		}
	});
}

function replaceNext(event){
	var content = $j(this).attr("href");
	var curID = $j(this).attr('id');
	var nextID = $j(this).next().attr('id');
	$j(this).next().psLoad(content, function(){initBehaviors();
		if ( curID == "schoolContext" || "termContext"){
			$j('#'+ nextID).find('select').focus();
		}
	});
	event.preventDefault();
} 


function loadingDialog(message){
	$j('body').append('<div id="loading"></div>');
	if (!message) message = pss_text("psx.js.scripts.psbehaviors.loading");
	$j('#loading').dialog({title: message, width: 228, height:35, resizable:false, position: 'center', modal: true, closeText: '',beforeclose: function (event, ui) { return false; },dialogClass: "dialogLoading", autoOpen: true,open: function(event, ui) {$j(this).closest('.ui-dialog').find('.ui-dialog-titlebar-close').hide();}});
}

function closeLoading() {
	var loading = $j('#loading');
	if (loading) loading.dialog().remove();
}

/**
 * Check the ajax response back from the server to see if it looks like a response is supposed
 * to look. If it does not, then log off the user (if what came back looks like a login page)
 * or just display an error alert (otherwise).
 * @param status
 * @param responseText
 */
function psCheckAjaxResponse(status, responseText) {
	if (!responseText) return;
	
	if (status && (status < 200 || status > 299)) {
		psAjaxError();
	}
	
	responseText = responseText.toLowerCase();
	var isDocument = false;
	for (var i = 0; i < responseText.length; i++) {
		// Ignore whitespace
		if (" \t\n\r".indexOf(responseText.charAt(i)) >= 0) continue;
		
		// If it's got an <html> or <!DOCTYPE> at the beginning, it's bad.
		if (responseText.indexOf("<html", i) == i || responseText.indexOf("<!doctype", i) == i) {
			isDocument = true;
			break;
		}

		// If it starts with a comment, skip it
		if (responseText.indexOf("<!--", i) == i) {
			var endPos = responseText.indexOf("-->", i+1);
			if (endPos >= 0) {
				i = endPos + 2;		// Skip to end of comment, but leave one for the loop incr
				continue;
			} else {
				// Comment to the end? OK, whatever...
				break;
			}
		}
	
		// Otherwise, if it survives, it's not a whole document.
		break;
	}
	
	if (isDocument) {
		// OK, it's a whole document. See if it looks like a login page.
		var loginRegex = /type\s*=\s*["']password["'].*name\s*=\s*["'](password|pw)["']/i;
		if (responseText.match(loginRegex)) {
			psLogoutError();
		} else {
			// Not a login page, just throw up an error and quit loading
			psAjaxError();
		}
	}
}

if(!_messages) var _messages = {};
/**
 * Get texts from the server based on a prefix.
 * @param prefix the prefix to use
 * @param onlyIfNotPresent (optional) if passed, check to see if message is present yet; only fetch the
 *   texts from the server if this key is not present
 */
if (typeof pss_get_texts != 'function') pss_get_texts = function (prefix, onlyIfNotPresent) {
  if (onlyIfNotPresent && _messages[onlyIfNotPresent]) return;
  
  jQuery.ajax ({async: false, 
    url:'/getMessages.action', 
    data:{prefix: prefix, locale: get_locale()},
    dataType:'json',
    success: function (msgs) {
      jQuery.each(msgs, function (key, value) {
        _messages[key] = value;
      });
    }
  });
}
	
function psLogoutError() {
	pss_get_texts("psx.js.scripts.psbehaviors.", "psx.js.scripts.psbehaviors.you_have_been_logged_out");
	alert(pss_text("psx.js.scripts.psbehaviors.you_have_been_logged_out"));
	
	var portal = window.location.href.split("/")[3];
	var url;
	if (portal != 'guardian') url = "/"+portal+"/~loff";
	else url = "/"+portal+"/home.html?ac=logoff";
	
	window.location = url;
	throw "ajax_logout";
}

function psAjaxError() {
	pss_get_texts("psx.js.scripts.psbehaviors.", "psx.js.scripts.psbehaviors.an_error_was_detected_contacting_server");
	alert(pss_text("psx.js.scripts.psbehaviors.an_error_was_detected_contacting_server"));

	// In case it's open (doesn't hurt if not)
	closeLoading();
	
	throw "ajax_error";
}

//Dialog widget	
function psDialog(a) {
	//loading panel
	loadingDialog();
	// The tag in the page <a href="content.html" title="Dialog Title" class="dialog" or "dialogC" or "dialogM">Open Dialog</a>
	// The content page is wrapped with a <div  style="width:XXXpx">content</div> this sets the width of the dialog
	$j('#psDialog').dialog('remove');
	$j('#psDialog').empty();
	var dWidth = "auto";
	var dHeight = "auto";
	var dIdent = $j(this).attr("id");
	var content = $j(this).attr("href");
	if (content == '' ) {
		var url = $j(this).attr('dialogContent'); //this is set in initBehaviors()
		if (url) {
			content = url;
		}
	}
	var dTitle = $j(this).attr("title");
	var dClass = $j(this).attr("class");
	var dModal = false;
	var	dResize = false;
	var x = 0;
	var y = 0;
	
	var dClasses = dClass.split(/\s+/g);
	var foundOne = false;
	$j.each(dClasses, function(index, dClassPart) {
		switch(dClassPart)
	{
	case 'dialogC':
		x = 'center';
		y = 'center';
			foundOne = true;
			return false;
	case 'dialogM':
		x = 'center';
		y = 'center';
		//modal dialog
		dModal = true;
			foundOne = true;
			return false;
	case 'dialogR':
		x = 'center';
		y = 'center';
		//resizable dialog
		dResize = true;
		dHeight = 500;
		dModal = true;
			foundOne = true;
			return false;
	case 'dialogDivC':
		x = 'center';
		y = 'center';
			foundOne = true;
			return false;
	case 'dialogDivM':
		x = 'center';
		y = 'center';
		//modal dialog
		dModal = true;
			foundOne = true;
			return false;
		default:
		break;
		}
		return true;
	});

	if (!foundOne) {
		x = $j(this).position().left;
		y = $j(this).position().top - $j(document).scrollTop();
	}
	
	if (dClass == 'dialogDiv' | dClass == 'dialogDivM' | dClass == 'dialogDivC') {
		var divContent = $j(content).html();
		$j('#psDialog').append(divContent);
		dWidth = $j(content).css('width');
		$j('#psDialog').dialog({
	 	    title : dTitle,
			closeText: 'X',
			width: dWidth,
			minWidth: 200,
			minHeight : 40,
			resizable : dResize,
			position: [x,y],
			draggable: true,
			modal: dModal,
			autoOpen: false,
			zIndex: 1005
		});
		$j('#loading').dialog().remove();
		$j('#psDialog').dialog('open');
		$j("#psDialog :input:visible:enabled:first").focus();
	} else {
		$j('#psDialog').psLoad(content, function() {
			$j('#errorMsg').hide();
			$j('#InboundRequests').click(function(event) 
			{
	    		$j.ajax({
	       			url: "/admin/studentmobility/notificationsInstitutionAJAX.action",
	          		type: "GET",
		          	dataType: "json",
		          	success: function (data) 
	    	      	{
	        	  		if(data.success == "true")
	          			{
	          				$j('#errorMsg').hide();
	          				window.open($j('#InboundRequests').attr('href'),'popup');
		          		}
		          		else
	    	      		{
	        	  			$j('#errorMsg').show();
	          			}
	          		},
					error: function(data)
					{
						psAjaxError();
			   		}
	     		});
		    	event.preventDefault();
			});
			dWidth = $j('#psDialog div:first-child').css('width');
			if (!dHeight){
				dHeight = $j('#psDialog').css('height');
			}
			$j('#psDialog').dialog({
		 	    title : dTitle,
				closeText: 'X',
				width: dWidth,
				minWidth: 200,
				minHeight : 40,
				height: dHeight,
				resizable : dResize,
				position: [x,y],
				draggable: true,
				modal: dModal,
				autoOpen: false,
				zIndex: 1005
			});
			initBehaviors();
			$j('#loading').dialog().remove();
			$j('#psDialog').dialog('open');
			$j("#psDialog :input:visible:enabled:first").focus();
		});
		
	}
	return false;
	/*End psDIalog*/
}

//4D Table formatting injection script: custom field pages lack some basic styling, this fixes them: Remove when we fix 4D
function fourDTableFix(){
	$j('.fourDTable').prepend('<tr class="hide"><td></td><td></td></tr>');
	$j('.fourDTable tr:odd').addClass('alt');
	$j('.fourDTable td:first-child').wrapInner('<strong />');
}

//view-events/data collection floating feedback widget
function psSystemFeedback(){
	if(typeof feedbackEnabled != 'undefined' && feedbackEnabled){
		if ($j('#feedbackSend').size() == 0)
		{
			   if(!recordingActivated){
				   $j('body:not(body.pslogin)').append('<div id="feedbackSend" class="group">' +
							'<div class="button" id="recordingStart">' + pss_text("psx.js.scripts.psbehaviors.recording_start") + '</div>' +
							'<div class="button" id="pageFeedback">' + pss_text("psx.js.scripts.psbehaviors.send_report") + '</div>' + 
							'<div class="button hide" id="recordingStop">' + pss_text("psx.js.scripts.psbehaviors.recording_stop") + '</div>' +
							'<div class="button hide" id="commentaryAddition">' + pss_text("psx.js.scripts.psbehaviors.add_issue_comment") + '</div>' +
							'<div class="button hide" id="recordingCancel">' + pss_text("psx.js.scripts.psbehaviors.recording_cancel") + '</div>' +
						 '</div>');
			   }else{
				   $j('body:not(body.pslogin)').append('<div id="feedbackSend" class="group">' +
							'<div class="button hide" id="recordingStart">' + pss_text("psx.js.scripts.psbehaviors.recording_start") + '</div>' +
							'<div class="button hide" id="pageFeedback">' + pss_text("psx.js.scripts.psbehaviors.send_report") + '</div>' + 
							'<div class="button" id="recordingStop">' + pss_text("psx.js.scripts.psbehaviors.recording_stop") + '</div>' +
							'<div class="button" id="commentaryAddition">' + pss_text("psx.js.scripts.psbehaviors.add_issue_comment") + '</div>' +
							'<div class="button" id="recordingCancel">' + pss_text("psx.js.scripts.psbehaviors.recording_cancel") + '</div>' +
				   '</div>');
			   }
			   
			   $j('#reportIssueLink').addClass('hide');
			   
			   $j('#pageFeedback').click(function(ev){
				   feedbackwindow();
				   $j('#feedbackSend').remove();
				   $j('#reportIssueLink').removeClass('hide');
				   $j(this).blur();
				   return false;
			   });
			   
			   $j('#recordingStart').click(function(ev){
				   //Hide feedbackSend and recordingStart buttons
				   $j('#pageFeedback, #recordingStart').addClass('hide');
				   //Show recordingStop and commentaryAddition buttons
				   $j('#recordingStop, #commentaryAddition, #recordingCancel').removeClass('hide');
				   $j(this).blur();
				   var referringDoc = window.document;
				   var url = referringDoc.URL;	       
				   var htmlTag = referringDoc.getElementsByTagName("html")[0];
				   var screenshot = htmlTag.innerHTML;
				   var queryString = window.location.search;
				   var responseText = submitScreenShot(screenshot, url, queryString);
				   return false;
			   });
			   
			   $j('#recordingStop').click(function(ev){
				   recordingWindow();
				   $j(this).blur();
				   return false;
			   });
			   
			   $j('#commentaryAddition').click(function(ev){
				   commentsWindow();
				   $j(this).blur();
				   return false;
			   });
			   
			   $j('#recordingCancel').click(function(ev){
				   cancelRecording();
				   //Remove hover buttons
				   $j('#feedbackSend').remove();
				   $j('#reportIssueLink').removeClass('hide');
				   $j(this).blur();
				   recordingActivated=false;
				   return false;
			   });
		   }
	}
}


//Send screen shot. Should only be called when page is loaded (on DOM is ready) and recording is active
function sendRecordingScreenShot(){
	var referringDoc = window.document;
	var url = referringDoc.URL;
	var htmlTag = referringDoc.getElementsByTagName("html")[0];
	var screenshot = htmlTag.innerHTML;
	var queryString = window.location.search;
	var responseText = submitScreenShot(screenshot, url, queryString);			
}

function submitScreenShot(screenshot, url, queryString)
{
	var base = "/recordingAJAX.action";
	var postData = "screenshot=" + escape(screenshot);
	postData = postData + "&url=" + encodeURIComponent(url);
	postData = postData + "&params=" + escape(queryString);
	
	var request = new XMLHttpRequest();
	request.open("POST", base, false);
	//Send the proper header information along with the request
	request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	request.setRequestHeader("Content-length", postData.length);
	request.setRequestHeader("Connection", "close");
	request.send(postData);
	return request.responseText;
}

function cancelRecording(){
	var base = "/cancelRecordingAJAX.action";
	
	var request = new XMLHttpRequest();
	var postData = "";
	request.open("POST", base, false);
	request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	request.setRequestHeader("Content-length", postData.length);
	request.setRequestHeader("Connection", "close");
	request.send(postData);
	return request.responseText;
}

//Functions that makes the windows calls, same as commonscript.ftl, coz the changes done there were no reflected.
function recordingWindow () {
	window.showModalDialog('/stopRecording.action','stop_recording','dialogWidth:640px; dialogHeight:500px; scroll:no;');
}

function commentsWindow () {
	window.showModalDialog('/getRecordCommentaryForm.action','add_commentary','dialogWidth:900px; dialogHeight:400px; scroll:no;');
}

	
//Change the buttons visualization
function changeStopButton(){
    $j('#feedbackSend').remove();
    $j('#reportIssueLink').removeClass('hide');
	$j('#recordingStop, #commentaryAddition, #recordingCancel').addClass('hide');
	$j('#pageFeedback, #recordingStart').removeClass('hide');
}

//Extract URL parameter values
//Returns String 'null' if parameter is not present
function getURLParameter(name) {
    return unescape(
        (RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
    );
}

$j(document).ready(function () {
	//Set keyboard focus to the first component on the first form and select the text, now excludes attendance forms
	$j("form:not(#attendance) :input:not(:button, :checkbox, :radio):visible:enabled:first").each(function (idx, el) {
		el.focus();
		if (el.type == "text") {
			el.select();
		}
	});

	initBehaviors();
	setActive();
	// Remove the Report an Issue link if the feature is disabled
	if(typeof feedbackEnabled != 'undefined' && !feedbackEnabled){
		$j("#reportIssueLink").remove();
	} 
	//  This is now activated by a link on the bottom of the page. Only do this here when recording is active	
	//  Also only activate link on the bottom of the page if it isn't of class pslogin and frameMenu
	var temp = $j('body:not(.pslogin,.frameMenu)').length;
	if (recordingActivated && temp>0)
	{
		psSystemFeedback();
	}
	psEnableCheck();
	fourDTableFix();
		
	// Checks if the recording function is active. if it does, the info page is submitted to the recording action
	if (recordingActivated){
		sendRecordingScreenShot();	
	}

	/*Invoke widgets, and hooks into DOM*/

	$j('<div id="psDialog"></div>').appendTo('body').hide();//Create a dialog div
	$j('a.dialog').live('click',psDialog);
	$j('a.dialogDiv').live('click',psDialog);
	$j('a.dialogDivC').live('click',psDialog);
	$j('a.dialogDivM').live('click',psDialog);
	$j('a.dialogC').live('click',psDialog);
	$j('a.dialogM').live('click',psDialog);
	$j('a.dialogR').live('click',psDialog);
	$j('a.dialogF').live('click',psDialog);//Listen for clicks on links with these classes

	$j('a.replaceNext').live('click',replaceNext);
	$j('table.linkDescList').find('tr:not(thead tr):even').addClass('alt');
	
	$j('#expand_all_changes-button').live('click',function(){psToggleAll('expand', '#change_reasons_div');});//YUI dialogs' buttons to expand all
	$j('#collapse_all_changes-button').live('click',function(){psToggleAll('collapse', '#change_reasons_div');});//YUI dialogs' buttons to collapse all
	$j('.expandAll').live('click',function(){psToggleAll('expand', '#content-main');});//buttons to expand all toggles: 'class','parent constraint'
	$j('.collapseAll').live('click',function(){psToggleAll('collapse', '#content-main');});//buttons to collapse all toggles: 'class','parent constraint'
	$j('h2.toggle').live('click', psToggle);//turns h2 with class="toggle collapsed" or class="toggle expanded" toggle-able widget
	
	$j('button.toggle').live('click', function(){$j(this).addClass('hide').next().removeClass('hide');});//toggles next element
	$j('button.toggleParent').live('click', function(){$j(this).parent().addClass('hide').prev().removeClass('hide');});//toggles parent tag off, used with toggle above
	
	$j('button#btnSubmit.disabled').attr('disabled','true');//workaround for disabling button to aid LoadRunner
	
	$j('form.submitOnce').submit(function(){loadingDialog()});
	$j('form.submitOnceCond').submit(function(){if(submitOnce_shouldShow){loadingDialog()}});
	
	$j('a.popWin').click(function(){
		var winURL = $j(this).attr('href');
		window.open(winURL);
		return false;
	});
	//$j( 'div#statsBuddy table' ).addClass('tableToGrid');

	//jQgrid convert table to grid...
	//tableToGrid('.tableToGrid', {altRows: true, altclass: 'alt', width: "100%",height: "200", scrollOffset:0, pager: '#pagernav'});

	//These functions create a button next to an input classed with 'massFill' that will copy the value from that input to all inputs in that column
	$j('input.massFill').live('focus', function(){
		var button = $j(this).siblings().filter('button.btnMassFill');
		if (button.length === 0){
			$j(this).parent().append('<button type="button" class="btnMassFill"><span>&nbsp</span></button>');
		}
	});
	$j('button.btnMassFill').live('click', function(){
		var source = $j(this).siblings().filter('input').val();
		$j(this).parents('table').find('td:nth-child(' + ($j(this).parent().index() + 1) + ') input').val(source);
	});

	//initially implemented to open requestformpreview.html from admin portal
	if (getURLParameter('mode') == 'preview' && $j('#header a').length) {
		$j('#header a, #usercontext-bar a, #nav-main a').removeAttr('href');
		$j('#header a, #nav-main a').css('color', 'grey');
		$j('#userName span').css('text-decoration', 'line-through').css('color', 'gray');
		$j('#header a, #nav-main a, #tools2 a').removeClass();
	}
/*End DOC Ready*/
});

/* ------------------------------------------------------
JS for inserting the selected field list item into the 
HTML object value, aka INPUT/TEXTAREA tag.

Parameters:
		inputObjName: ID of HTML object to have item inserted into.
		insertValue: The value to be inserted.
		option: Any additional options, number value.
			* If negative, add ^() around the insert value.
			* If 99 or -99, then add a carriage return after insert value.
			* If 5 or -5, then replace the value, aka oldValue=insertValue.
------------------------------------------------------ */
function ads (inputObjName, insertValue, option) {
	var inputObject = document.getElementById(inputObjName),
		s = 0;
	
	// verify and convert option to an integer.
	option = parseInt(option);
	
	/* Check to add code tag around value... If negative, add code tag */
	if (option<0) {
		insertValue="^("+insertValue+")";
		option=((-1)*option);
	}

 if (document.selection) { /* IE */
 	inputObject.focus();
 	if (option==5) {
 		inputObject.value=insertValue;
 	} else if (option==99) {
 		document.selection.createRange().text=insertValue+"\n";
 	} else {
 		document.selection.createRange().text=insertValue;
 	}
	} else { /* Mozilla/Netscape */
		s = inputObject.selectionStart;
		
		var startValue = inputObject.value.substring(0, s),
			endValue = inputObject.value.substring(s),
			insertReturn="";

		/* Replace the oldValue with insertValue */
		if (option==5) {
			inputObject.value=insertValue;
			startValue='';
			endValue='';
		}
		/* Check to add carriage return after value... */
		if ( (option==99) && endValue.substring(0, 1)!="\n" ) {
			insertReturn="\n";
		} 
		/* Check for carriage return between startValue and endValue */
		if (endValue.substring(0, 1)=="\n") {
			insertValue="\n"+insertValue;
		}
		
		insertValue=insertValue+insertReturn;
		inputObject.value = startValue+insertValue+endValue;
		
		setSelectionRange(inputObject,s+insertValue.length,s+insertValue.length);
	}
		
	oResizePanel.hide();
	/* oResizePanel.destroy(); */
	inputObject.focus(1);
}

/*FUTURE Scripts*/
//Frame nav, and Left nav hide: This feature is for a future release...
$j('document').ready( function(){
//	$j.getScript("/scripts/jquery.cookie.js", function(){ navCollapse(); }); //Commenting this one line disables the left nav show/hide functionality
	function setNavCookie(state){
		if(state == 'collapsed'){
			$j.cookie('navState','collapsed',{ path: '/', expires: 1 });
		} else if (state == 'expanded'){
			$j.cookie('navState', null, { path: '/', expires: 1 });
		}
	}

	function navCollapse(){
		var context = window.document.content;
		if ( $j('#frameSet', top.document).length !== 0 ){
			//Inject nav-main into frames.
			if ( $j('#navMainInject').length === 0 ){
				//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
				$j('#nav-main-frame').prepend('<h3 id="navMainToggle" class="toggle collapsed">Main Navigation</h3><div id="navMainInject"></div>');
				$j('#navMainInject').psLoad('/admin/admin_nav_main_inject.html', function(){ $j('#nav-main a').attr('target','_top')});
				$j('h3#navMainToggle').live('click',function() {
					$j(this).next().toggle();
					if ( $j('h3#navMainToggle').hasClass('collapsed') ){
						$j(this).removeClass('collapsed').addClass('expanded');
					} else {
						$j('h3#navMainToggle').removeClass('expanded').addClass('collapsed');
					}
					return false;
				}).next().hide();
			}
		}
		if ( $j('#frameSet', top.document).length !== 0 ){

			if ( $j('#navCollapse', context ).length === 0 ){
				//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
				$j('#content', context ).prepend('<div id="navCollapseFrame" class="expanded" title="Hide Left Navigation"></div>');
			}
			if ($j.cookie('navState') == 'collapsed'){
				$j('#frameSet', top.document).attr({'cols':'0,*'})
				//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
				$j('#navCollapseFrame', context ).addClass('collapsed').removeClass('expanded').attr({'title':'Show Left Navigation'});
			}
			$j('#navCollapseFrame').click( function() {				
				if ( $j('#frameSet', top.document).attr('cols') == '0,*' ){
					setNavCookie('expanded');
					$j('#frameSet', top.document).attr({'cols':'208,*'});
					//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
					$j('#navCollapseFrame', context ).addClass('expanded').removeClass('collapsed').attr({'title':'Hide Left Navigation'});
				} else if( $j('#frameSet', top.document).attr({'cols':'208,*'}) ){
					setNavCookie('collapsed');
					$j('#frameSet', top.document).attr({'cols':'0,*'})
					//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
					$j('#navCollapseFrame', context ).addClass('collapsed').removeClass('expanded').attr({'title':'Show Left Navigation'});
				}

			});
		} else {

			if ( $j('#navCollapse').length === 0 ){
				//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
				$j('#nav-main').before('<div class="expanded" id="navCollapse" title="Hide Left Navigation"></div>');
			}
			if ($j.cookie('navState') == 'collapsed'){
				$j('body').addClass('navHide');
				//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
				$j('#navCollapse').addClass('collapsed').removeClass('expanded').attr({'title':'Show Left Navigation'});
			}
			$j('#navCollapse').click( function() {

				if ( $j('#nav-main').css('display') === 'none' ){
					setNavCookie('expanded');
					$j('body').removeClass('navHide');
					//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
					$j('#navCollapse').removeClass('collapsed').addClass('expanded').attr({'title':'Hide Left Navigation'});
				} else {
					setNavCookie('collapsed');
					$j('body').addClass('navHide');
					//*****This text is not in message key format because we do not want to expose this to our customers yet!!!
					$j('#navCollapse').addClass('collapsed').removeClass('expanded').attr({'title':'Show Left Navigation'});
				}
			});
		}
	}
});
//End frame nav, and Left nav hide	

//Not implemented yet, but the start of a method to control a standardized feedback (success/failure) area on all pages
/*function psFeedback(m){
		//this is a stub for the feedback-div system for every page
		if (m == 'alert'){
		$j('#feedback:first-child').switchClass('feedback-confirm','feedback-alert');
		} else if (m == 'confirm'){
		$j('#feedback:first-child').switchClass('feedback-alert','feedback-confirm');
		}
	}*/

/*
//This function returns the TH on a clicked table cell
$j('td').click(function(){
var col = $j(this).prevAll().length;
var headerObj = $j(this).parents('table').find('th').eq(col);
// A quick test!
alert("My cell header is called: " + headerObj.text());
});
 */

//This function highlights the rows and columns when hovering over a cell
/*$j("td").hover(
		function() {
			$j(this).addClass('highlight');
			//$j(this).parentsUntil('table').find('td:nth-child(' + ($j(this).index() + 1) + ')').add($j(this).parent()).addClass('highlight');
			console.log('highlight');
      },
      function() {
			$j(this).removeClass('highlight');
			//$j(this).parentsUntil('table').find('td:nth-child(' + ($j(this).index() + 1) + ')').add($j(this).parent()).removeClass('highlight');
		});*/
 

