//SyberWorks JavaScript Functions

//060911 SAC
//Replaced the use of global variable z with global variable SOTcount (Submit One Time count)
//It is not advisable to have a variable name like z as a global variable
var fromwhere;
var campusname;
var classid;
var coursecode;
var lessonnumber;
var QIDsUsed;
var QIDsUsed2="";

function addEventFunc(object, event, newFunc)
{
	//alert('adding an on' + event + ' to a ' + object.type + ': \n' + newFunc);
	var curFunc = object['on' + event];	
	if (typeof curFunc != 'function') {
		object['on' + event] = newFunc;
	} else {
		object['on' + event] = function() {
			curFunc();
			newFunc();
		}
    }
}

function isDefinedEval(objectname)
{
	return(eval('typeof(' + objectname + ')') != 'undefined' && eval(objectname) != null);
}

function isDefined(objectname)
{
	var script='';
	var c=0;
	script += 'true';

	c = objectname.indexOf('.');
	while (c != -1)
	{	
		if ( !isDefinedEval(objectname.substr(0,c) ))
			return(false);

		c = objectname.indexOf('.',c+1);
		
	}
	return (isDefinedEval(objectname));
}

function WriteCookie(name, value, expires, domain, path, secure){
	var CookieVal, CookError;
	var temp;
	CookieVal=CookError="";
	if (name) {
		CookieVal=CookieVal+escape(name)+"=";
		if (value) {
			CookieVal=CookieVal+escape(value);
			if (expires)CookieVal=CookieVal+"; expires="+expires.toGMTString();
			if (domain)	CookieVal=CookieVal+"; domain="+domain;
			if (path) CookieVal=CookieVal+"; path="+path;
			if (secure) CookieVal=CookieVal+"; secure";
		} else {CookError=CookError+"Value failure";}
	} else {CookError=CookError+"Name failure";}
	if (!CookError){
		document.cookie=CookieVal;
		temp=ReadCookie(name);
		if (value!=temp) CookError="<p>Please make sure your browser can accept cookies.";
	
	}
	return (CookError);
}

function ReadCookie(name){
	var allCookie, CookieVal, length, start, end;
	cookieVal="";
	name=name+"=";
	allCookie=document.cookie;
	length=allCookie.length;
	if (length>0) {
		start=allCookie.indexOf(name,0)
		if (start!=-1) {
			start+=name.length;
			end=allCookie.indexOf(";",start);
			if (end==-1) {end=length;}
			cookieVal=unescape(allCookie.substring(start, end));
		}
	}
  	return (cookieVal);
}



function SetCoursesCookies(fromwhere, campusname, classid) {
  	var coursescookie;
	coursescookie=WriteCookie("fromwhere", fromwhere, "", "", "/");
	coursescookie=WriteCookie("campusname", campusname, "", "", "/");
	coursescookie=WriteCookie("classid", classid, "", "", "/");
}

function ReadCoursesCookies() {
	fromwhere=ReadCookie("fromwhere");
	campusname=ReadCookie("campusname");
	classid=ReadCookie("classid");
}

function findSelectIndex(selectfield, optionvalue)
{
	var i=0;
	for (i=0;i < selectfield.options.length;i++)
	{
		if (selectfield.options[i].value.toLowerCase() == optionvalue.toLowerCase())
		{ 
			return(i);
		}
	}
	return(-1);
}

function getDefaultCampus()
{
	var campusname = ReadCookie('DefaultCampusName');
    var i=0;
    for (i=0;i < document.forms.length;i++)
	{
		if (isDefined('document.forms[' + i + '].CampusName'))
		{
			if (document.forms[i].CampusName.type == 'text')
			{
				if (isDefined('document.forms[' + i + '].IDs'))
				{
					if (document.forms[i].IDs.type == 'select-one')
					{	
						var index = findSelectIndex(document.forms[i].IDs, campusname);
						
						if (index > -1) {
							document.forms[i].IDs.selectedIndex = index;
							document.forms[i].CampusName.value = campusname;
						}
						eval('addEventFunc(document.forms[i], \'submit\', function () { setDefaultCampus(\'\',document.forms[' + i + '].CampusName.value) } )'); 
					}
				}
			}
		}
	}
}
	
function setDefaultCampus(campusID, campusname)
{
	if (campusID != '') 
	{
		//alert('Set campusid: ' + campusID);
		WriteCookie('DefaultCampusID', campusID, "", "", "/")	
	}

	if (campusname != '')
	{
		//alert('Set campusid: ' + campusname);
		WriteCookie('DefaultCampusName', campusname, "", "", "/");
	}
}

// Added 3/29/04 to check a survey to make sure all questions answered before submitting
function getSurveyQuestionName(name) {
	var iter;
	iter=name.indexOf("Option");
	if (iter > -1) {
		return (name.slice(0,iter));
	} else {
		return(name);
	}
}
var surveychecked=0;
function checksurvey(f, AnswerAllQuestions)
{
   var missed;
   numq=0;
   i=0;
   questmiss="";

   // 10/12/2009   The checksurvey function in Syberworks.js will get a second, optional parameter, named AnswerAllQuestions.  
   // The $Survey code will populate this parameter to be the AnswerAllQuestions database value:
   // - If the AnswerAllQuestions field is N, checksurvey will be called with AnswerAllQuestions parameter set to N;
   //   the javascript code will not require all questions to be filled in, and will not give a warning if a question is missed.
   // - If the AnswerAllQuestions field is Y, checksurvey will be called with the AnswerAllQuestions parameter set to Y.  
   //   The javascript code will give a warning if one or more questions are missed but will allow the survey to be submitted anyway. 
   // - If the AnswerAllQuestions field is R (meaning Required Completion), checksurvey will be called with the
   //	AnswerAlLQuestions parameter set to R.
   //   The javascript code will give an error message if one or more questions are missed, and will NOT allow the user to 
   //   ever submit the survey results until the user has answered all of the survey questions.
   
   if (AnswerAllQuestions == undefined)
   {
		AnswerAllQuestions = 'N';
   }
 
   if (AnswerAllQuestions == 'N') 
   {
		return(true);
   }
   
   if(AnswerAllQuestions == 'Y')
   {
		// We have already given the warning; allow the submit.
		if (surveychecked == 1)
		{
			return(true);
		}

		// Continue below with warning or error message.
		surveychecked=1;
   }

   while (i < (f.elements.length - 1)) {
	if (f.elements[i].name.slice(0,	8) == "Question") {
		numq++;
		answered = 0;
		elemName = getSurveyQuestionName(f.elements[i].name);
		while (getSurveyQuestionName(f.elements[i].name) == elemName) {
		    if (f.elements[i].type.slice(0,4) == "text") {
			answered = f.elements[i].value != "";
		    } else if (f.elements[i].type.slice(0,6) == "select") {
			answered += f.elements[i].value!='NA';
		    } else {
			answered += f.elements[i].checked;
		    }
		    i++;
		}	
		
		if (!answered) {
			if (questmiss=="") {
		        	questmiss += numq;
			} else {
				if ( numq % 1 == 20) questmiss +="\n";
				questmiss += ", " + numq;
			}
		}
	} else {
		i++;
	}
   }
   if (questmiss=="") return(true);

   // 10/12/2009 Give warning or error, based on AnswerAllQuestions.
   if(AnswerAllQuestions == 'Y')
   {
	    msg = "You have not answered the following questions: \n"
		msg += "\n" + questmiss + "\n\n";
		msg += "Questions that are not applicable should be left blank.\n";
		msg += "Please review the above list of questions to confirm\n";
		msg += "that they are not applicable and resubmit the survey.\n ";	
	}
	else
	{
	    msg = "You have not answered the following questions: \n"
		msg += "\n" + questmiss + "\n\n";
		msg += "Please answer the above list of questions and resubmit the survey.\n ";	
	}

   alert (msg );
  return(false);
}

function checkformdata(f){
errorflag = false
emptyfields = ""
msg = "_________________________________________________\n\n";
msg += "The form was not submitted because of the following errors.\n\n";
msg += "Please correct these errors and re-submit.\n\n";
msg += "__________________________________________________\n\n";
if (f.FirstName.value == "")
{
  errorflag = true;
  emptyfields += "-  First Name\n";
}
if (f.LastName.value == "")
{
  errorflag = true;
  emptyfields += "-  Last Name\n";
}
if (f.UserID.value == "")
{
  errorflag = true;
  emptyfields += "-  User ID\n";
}
if (f.Password.value == "")
{
  errorflag = true;
  emptyfields += "-  Password\n";
}
if (errorflag)
{
  msg += "The following required fields were empty:\n\n";
  msg += emptyfields;
  alert(msg);
  return false;
}
else return true;
}

function LimitSelections(SelectBox, Name, Maximum) {
	//alert("LimitSelections");
	var i;
	var numSelected;
	numSelected=0;
	if(typeof(SelectBox)=='undefined')
	{
		//alert("SelectBox = " + SelectBox);
		return true;
	}
	for(i=0;i<SelectBox.length;i++) {
		numSelected+=SelectBox[i].selected ;
	}
	//alert("numSelected = " + numSelected);
	if (numSelected > Maximum) {
		alert ('You may not select more than ' + Maximum + ' items from the ' + Name + ' selection box');
		return false;
	} else {
		return true;
	}
	
}

function NewWindow(filename, winname, windowfeatures)
{
   window.open(filename, winname, windowfeatures)
}

// Added 041109

function CheckLogin(CampusID) {
   var str = document.cookie;
   if (str.indexOf('SWAUTH') == -1) {
      var str1 = document.URL;
      int1 = 0;
      for (i=0; i<3; i++)
      {   int1 = str1.indexOf('/', int1);
          int1++;
      }
      var str2 = str1.substr(0,int1);
      var str3 = 'StartURL=' + escape(str1);
      var str4 = 'SWAUTH=' + escape('CampusID=' + CampusID + '&' + str3);
      var str5 = str2 + 'cgi-win/$login.dll?' + str4;
      document.location=str5;
   }
}

function QuestionFeedback() {
  var WindowQuestion=window.open("../AnswerWait.htm", "Answer_Feedback", "resizable=yes,scrollbars=yes,width=400,height=350")
}

// Added 3-28-05

function SelectResp(qid, choice, alt){
  QuestionFeedback();
  var obj;
  obj = eval("document." + qid + "form");
  obj.elements[0].value = choice;
  obj.elements[1].value = alt;
  obj.submit();
}

// Added 5/3/03 to check a test to make sure all questions answered before submitting

function checktest(f,toomanytimesmessage)
{
   //alert ("Start of checktest.");
   //alert ("f is " + f);

   var returnfromSOT;
   returnfromSOT=SubmitOneTime(toomanytimesmessage);
   //alert ("checktest after call to SubmitOneTime. SOTcount is " + SOTcount);

   if (returnfromSOT==false)   
   {
      return false;
   }

   var i = 0;
   var j = 0;
   var numq = 0;
   var tmpqname = "";
   var questmiss = "";
   var tmpstr = "notblank";
   var tmpchk = "notchecked";
   var foundtest = false;
   var firsthiddenaftertest = true;
   var currtype = "";
   var QIDlength;
   var qidmask="";
   var foundQuestion=false;
   var baseqid=coursecode+lessonnumber+"QS";
   msg = "You have not answered all the questions.  Please\n";
   msg += "check the question numbers listed below and resubmit\n"
   msg += "the test.\n\n";
   var QIDlength;
   QIDlength=getQIDlength(f,baseqid);

   do
   {


      if (i > 2000)
      {
         alert("Problem in checking program or over 2000 question options.");
         //Reset SOTcount.
         SOTcount=0;
         return false;
      }

      if (i >= (f.elements.length - 1))
      {
         // action if increment past last array element

         if (questmiss != "")
         {
            msg += questmiss + "\n";
            alert (msg);
            //Reset SOTcount.
            SOTcount=0;
            return false;
         }
         return true;
      }

      if (f.elements[i].type == "checkbox" || f.elements[i].type == "radio" || 	f.elements[i].type.toString() == "text")
      {
         foundtest = true;

         if (f.elements[i].type == "text")
         {
            // First question element.  Only one for FIB, but multiple for Matching

            currtype = f.elements[i].type;

            bfoundQuestion=false;
			for (j=0; j<arrQIDs.length; j++)
			{
				if (arrQIDs[j] == f.elements[i].name.substr(0,arrQIDs[j].length))
				{
					qidmask = arrQIDs[j];
					foundQuestion=true;
					break;
				}
			}
			//if (f.elements[i].name.substr(0,QIDlength) != tmpqname)
			//if the element is not a question then the qidmask should be set to the name of the element
			if (!foundQuestion) {qidmask=f.elements[i].name;}
			if (qidmask != tmpqname)
            {
               // Different name means new question number.
               // First see how to process old question to see if answered.
			   if (numq > 0 && !(f.elements[i].name == 'TestUserID' ||
								 f.elements[i].name == 'TestPassword'))
               {
					if (f.elements[i].type == "text")
                  {
                     if (tmpstr == "blank")
                     {
			
                        questmiss += numq + " ";
                     }
                  }
                  else
                  {
                     if (tmpchk == "notchecked")
                     {
                        questmiss += numq + " ";
                     }
                  }
               }
 
               numq++;
               //tmpqname = f.elements[i].name.substr(0,QIDlength);
			   tmpqname=qidmask;
               tmpstr = "notblank";
               tmpchk = "notchecked";
            } 
  
            //tmpstr = "notblank";
           

            if (f.elements[i].value == "")
            { 
               tmpstr = "blank";
            }

            do
            {
               i++;

               if (i > 2000)
               {
                   alert("Problem in checking program or over 2000 question options.");
                   //Reset SOTcount.
                   SOTcount=0;
                   return false;
               }

               if (i == f.elements.length)
               {
                  // action if increment past last array element
                  if (questmiss != "")
                  {
                     msg += questmiss + "\n";
                     alert (msg);
                     //Reset SOTcount.
                     SOTcount=0;
                     return false;
                  }
                  return true;
               }
               // incrementing i has moved to new question so mark status of previous question.
			   foundQuestion=false;
				for (j=0; j<arrQIDs.length; j++)
				{
					if (arrQIDs[j] == f.elements[i].name.substr(0,arrQIDs[j].length))
					{
						qidmask = arrQIDs[j];
						foundQuestion=true;
						break;
					}
				}
				//if (f.elements[i].name.substr(0,QIDlength) != tmpqname)
				//if the element is not a question then the qidmask should be set to the name of the element
				if (!foundQuestion) {qidmask=f.elements[i].name;}
				if (qidmask != tmpqname)
				{
                  if (numq > 0 && !(f.elements[i-1].name == 'TestUserID' ||
								 f.elements[i-1].name == 'TestPassword'))
                  {
                     if (f.elements[i-1].type == "text")
                     {
                        if (tmpstr == "blank")
                        {
                           questmiss += numq + " ";
                        }
                        tmpstr = "notblank";
                     }
                     else
                     {
                        if (tmpchk == "notchecked")
                        {
                           questmiss += numq + " ";
                        }
                        tmpchk = "notchecked";
                     }
                  }
 
                  numq++;
                  //tmpqname = f.elements[i].name.substr(0,QIDlength);
					tmpqname=qidmask;

                  currtype = f.elements[i].type;
                  if (f.elements[i].type == "text")
                  {
                     if (f.elements[i].value == "")
                     {
                        tmpstr = "blank";
                     }
                  }
                  else
                  {
                     if (f.elements[i].checked)
                     {
                        tmpchk = "checked";
                     }
                  }
                  break;
				} 


               if (f.elements[i].value == "")
               { 
                  tmpstr = "blank";
               }

             
            } while (true);
         }

         if (f.elements[i].type == "radio" || f.elements[i].type == "checkbox")
         {

            currtype = f.elements[i].type;

			foundQuestion=false;
            for (j=0; j<arrQIDs.length; j++)
			{
				if (arrQIDs[j] == f.elements[i].name.substr(0,arrQIDs[j].length))
				{
					qidmask = arrQIDs[j];
					foundQuestion=true;
					break;
				}
			}
			//if (f.elements[i].name.substr(0,QIDlength) != tmpqname)
			//if the element is not a question then the qidmask should be set to the name of the element
			if (!foundQuestion) {qidmask=f.elements[i].name;}
			if (qidmask != tmpqname)
            {
               // Different name means new question number.
               // First see how to process old question to see if answered.
               if (numq > 0  && !(f.elements[i-1].name == 'TestUserID' ||
								 f.elements[i-1].name == 'TestPassword'))
               {
                  if (f.elements[i-1].type == "text")
                  {
                     if (tmpstr == "blank")
                     {
                        questmiss += numq + " ";
                     }
                  }
                  else
                  {
                     if (tmpchk == "notchecked")
                     {
                        questmiss += numq + " ";
                     }
                  }
               }
 
               numq++;
			   tmpqname=qidmask;
               //tmpqname = f.elements[i].name.substr(0,QIDlength);
               tmpchk = "notchecked";
               tmpstr = "notblank";
            } 
  
            //tmpchk = "notchecked"

            if (f.elements[i].checked)
            { tmpchk = "checked"; }

            do
            {

               i++;

               if (i > 2000)
               {
                   alert("Problem in checking program or over 2000 question options.");
                   //Reset SOTcount.
                   SOTcount=0;
                   return false;
               }

               if (i >= f.elements.length)
               {
                  // action if increment past last array element
                  if (questmiss != "")
                  {
                     msg += questmiss + "\n";
                     alert (msg);
                     //Reset SOTcount.
                     SOTcount=0;
                     return false;
                  }
                  return true;
               }
			foundQuestion=false;
            for (j=0; j<arrQIDs.length; j++)
			{
				if (arrQIDs[j] == f.elements[i].name.substr(0,arrQIDs[j].length))
				{
					qidmask = arrQIDs[j];
					foundQuestion=true;
					break;
				}
			}
			if (!foundQuestion) {qidmask=f.elements[i].name;}
			//if (f.elements[i].name.substr(0,QIDlength) != tmpqname)
			if (qidmask != tmpqname)
               {
                  if (numq > 0  && !(f.elements[i-1].name == 'TestUserID' ||
								 f.elements[i-1].name == 'TestPassword'))
                  {
                     if (f.elements[i-1].type == "text")
                     {
                        if (tmpstr == "blank")
                        {
                           questmiss += numq + " ";
                        }
                     }
                     else
                     {
                        if (tmpchk == "notchecked")
                        {
                           questmiss += numq + " ";
                        }
                     }

                     tmpstr = "notblank";
                     tmpchk = "notchecked";
                  }
 
                  numq++;
					tmpqname=qidmask;
                  //tmpqname = f.elements[i].name.substr(0,QIDlength);
                  currtype = f.elements[i].type;
                  if (f.elements[i].type == "text")
                  {
                     if (f.elements[i].value == "")
                     {
                        tmpstr = "blank";
                     }
                  }
                  else
                  {
                     if (f.elements[i].checked)
                     {
                        tmpchk = "checked";
                     }
                  }
                  break;
               } 

               
               if (f.elements[i].checked)
               { tmpchk = "checked"; }

             } while (true);
         }


      } else {
	      i++;  
      }
	  if (foundtest && f.elements[i].type == "hidden" && firsthiddenaftertest && false)
      {
         firsthiddenaftertest = false;
         if (f.elements[i-1].type == "text")
         {
			if (tmpstr == "blank")
            {
               questmiss += numq + " ";
            }
         }
         if (f.elements[i-1].type == "checkbox" || f.elements[i-1].type == "radio")
         {
            if (tmpchk == "notchecked")
            {
               questmiss += numq + " ";
            }
         }
       }

   } while (true);
}

var SOTcount = 0;
function SubmitOneTime(toomanytimesmessage)
{
   //alert("Inside SubmitOneTime. SOTcount is " + SOTcount);
   SOTcount = SOTcount + 1;
   if (SOTcount > 1) 
   {
      alert(toomanytimesmessage);
      return false;
   }
   else
   {
      return true;
   }
}

//Determines how many characters are in a qid.  Assume that 
function isLetter (c)
{   return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )
}

function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}

//Determine the length of QIDs in a form;
function getQIDlength(f, qidmask)
{
    var i, j;
    var name;
    var QIDlength=0;
    j=qidmask.length;
	for(i=0; i < f.elements.length; i++)
    {
		name=f.elements[i].name;
		if (qidmask == name.substr(0,qidmask.length))
		{
			//Find how many digits there are
			while(isDigit(name.substr(j, 1)) && j < name.length) 
			{
				j++;
			}
			return(j);
		}
    }
    // var i, j=8;
    // var name;
    // var QIDlength=0;
	
    //alert ("getQIDlength f is " + f);
    //alert ("getQIDlength f.elements is " + f.elements);
    // for(i=0; i < f.elements.length; i++)
    // {
	// name=f.elements[i].name;
	//Is this a test question?
	// if (isLetter(name.substr(0,1)) && 
   	    // isLetter(name.substr(1,1)) && 	
	    // isDigit(name.substr(2,1)) &&	
	    // isDigit(name.substr(3,1)) &&
	    // isDigit(name.substr(4,1)) &&
	    // isDigit(name.substr(5,1)) &&

	    // name.substr(6,2) == "QS"
	// )
	// {
		//Find how many digits there are
		// while(isDigit(name.substr(j, 1)) && j < name.length) 
		// {
		    // j++;
		// }
		// return(j);
	// }
    // }
}

//Added 9/1/2006 SAC - Ensure that the form has loaded properly
//Summary: checkForm is called either when the onLoad event is fired 
var counter=0;
var bFormChecked=false;
var errmsg="A problem has been detected loading the test. \r Please load the test again.";
var arrQIDs = new Array(); //Made global to be used when checking if every question in the test has been answered
function checkForm()
{
	if (!bFormChecked)
	{
		if (isDefined('formIsLoaded'))
		{
			checkNumQuestions();
			bFormChecked=true;
		}
		else
		{
			if (counter < 3)
			{
				window.setTimeout("checkForm()",4000); 
				counter=counter+1;
			}
			else
			{
			alert(errmsg);
			}
		}
	}
}


function checkNumQuestions()
{
   var numQuestions=0;
   var tmpqname = "";
   var QIDlength;
   var NumberofQuestions;
   var bSubmitExists=false;
   //var arrQIDs = new Array();
   var theName;

   numQuestions=0;
  // Jim 12/04/06
  if (document.test == null ) return;
   //loop through the elements in the form
   for(i=0; i<document.test.elements.length; i++)
   {
      theName=document.test.elements[i].name
      switch (theName)
	  {
		case "CourseCode":
			//Set the CourseCode variable
			coursecode=document.test.elements[i].value
			break
		case "LessonNumber":
			//Set the LessonNumber variable
			lessonnumber=document.test.elements[i].value
			if (lessonnumber<10)
			{
			lessonnumber="0" + lessonnumber
			}
			break
		case "NumberOfQuestions":
			//Set the NumberOfQuestions variable. This is the number of questions expected to be loaded.
			NumberOfQuestions=document.test.elements[i].value
			break
		case "ListOfQuestionsUsedstr":
			//Set the QIDsUsed variable. This is the actual QIDs that are used in the test that has been loaded
			var tmp;
			QIDsUsed=document.test.elements[i].value + QIDsUsed2

			tmp=QIDsUsed.substr(1,QIDsUsed.length-2)
			arrQIDs=tmp.split(",")
			for (j=0; j<arrQIDs.length; j++)
			{
				arrQIDs[j]=arrQIDs[j].replace(" ", "")
				NumberOfQuestions=j;
			}
			NumberOfQuestions++;
			break
		case "ListOfQuestionsUsedstr2":
			//Set the QIDsUsed variable. This is the actual QIDs that are used in the test that has been loaded
			QIDsUsed2=document.test.elements[i].value
			break
	  }
	}
   for(i=0; i<document.test.elements.length; i++)
   {
		if (document.test.elements[i].type == "button")
		{
			//The Submit button exists
			bSubmitExists=true
		}
		else
		{

		  // 20100302 For tests with a ton of question, this routine can take way too long.
		  // So for tests with over 50 questions, we simply check that the submit
		  // button exists.  Hopefully, the questions will be displayed by the time the
		  // submit button is displayed.  This will speed up the launching of the test.
		  if (NumberOfQuestions < 50)
		  {
			for(j=0; j<arrQIDs.length; j++)
			{
				var qidmask
				qidmask=document.test.elements[i].name.substr(0,arrQIDs[j].length)
				
				//061201 SAC
				//The QIDs of the questions exepected in the test and the QIDs of the questions actually loaded in the test can be
				//different cases. JavaScript is case sensitive therefore would treat them as different values.
				//Change to UpperCase before comparing
				if (qidmask.toUpperCase() == arrQIDs[j].toUpperCase())
				{
					if (document.test.elements[i].type == "checkbox" || document.test.elements[i].type == "radio" || document.test.elements[i].type.toString() == "text")
					{
						//Element type is for a question
						var baseqid
						baseqid=coursecode+lessonnumber+"QS";
						QIDlength=getQIDlength(document.test,baseqid);
						// First question element.  Only one for FIB, but multiple for Matching
						
						//Check for the question id changing. If it does, increment the question count
						if (qidmask != tmpqname)
						{
							numQuestions++;
							tmpqname = qidmask;
						}
					}
				}
			}
		  } // If NumberOfQuestions
		}
	}

	// 20100302 We check the NumberOfQuestions only if we have less than 50 questions.
	// Otherwise, it takes way too long to launch the test.
//	if (NumberOfQuestions<numQuestions)
	if (NumberOfQuestions<numQuestions && (NumberOfQuestions < 50) )
	{
		//Number of questions loaded is less that the Number of questions that were expected
		//Display the generic error message
		alert (errmsg)
	}
	// 20100302 We check the NumberOfQuestions only if we have less than 50 questions.
	// Otherwise, it takes way too long to launch the test.
//	else if (NumberOfQuestions>numQuestions)
	else if (NumberOfQuestions>numQuestions && (NumberOfQuestions < 50) )
	{
		//Number of questions loaded is more than what was expected
		//Display the generic error message
		alert (errmsg)
	}
	else if (!bSubmitExists)
	{
		//Submit button does not exist in the form
		//Display the generic error message
		alert (errmsg)
	}
}

//Event Hooks
addEventFunc(window, 'load', getDefaultCampus);

//Functions for Comment Entry and Hiding Table Rows

var mousex = 0;
var mousey = 0;

function init()
{
   document.onmousemove = getMouseXY; // update(event) implied on NS, update(null) implied on IE
   getMouseXY();
}

function getMouseXY(e) // works on IE6,FF,Moz,Opera7
{
   
   if (!e) e = window.event; // works on IE, but not NS (we rely on NS passing us the event)
   if (e)
   {
      if (e.pageX || e.pageY)
      { // this doesn't work on IE6!! (works on FF,Moz,Opera7)
         mousex = e.pageX;
         mousey = e.pageY;
      }
      else if (e.clientX || e.clientY)
      { // works on IE6,FF,Moz,Opera7
         mousex = e.clientX + document.body.scrollLeft;
         mousey = e.clientY + document.body.scrollTop;
      }
   }
}

function togglecat(start, end)
{
    var i;
    for (i = start; i < end+1; i++) {
        toggleid("crsrow" + i);
    }
}

////////////////////////////////////////////////////////////////////////
// Functions to trim whitespace (all characters less then 'space').
function LTrim(str)
{
	for (var k=0; k<str.length && str.charAt(k)<=" " ; k++) ;
	return str.substring(k,str.length);
}

function RTrim(str)
{
	for (var j=str.length-1; j>=0 && str.charAt(j)<=" " ; j--) ;
	return str.substring(0,j+1);
}

function Trim(str)
{
	return LTrim(RTrim(str));
}


////////////////////////////////////////////////////////////////////////
// Function to hide a set of fields.
function hideTheseFields(fieldList)
{
	// Don't bother if we don't have anything to hide.
	if (fieldList != null && fieldList != "")
	{
		// Split up the fields to be hidden into an array.
		var splitData = fieldList.split(",");

		// Loop through each field in this category.
		for(i=0; i<splitData.length; i++)
		{
			// Make sure we have a field.
			if (splitData[i] != "")
			{
				// Trim before we process.
				splitData[i] = Trim(splitData[i]);

				// Make sure we have this field on the form.
				if (eval('typeof(document.' + splitData[i] + ')' ) != 'undefined')
				{
					// Now hide this field.
					toggleid(splitData[i]);
				}
			}
		}
	}
}
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
// Function to set up the fields' image to show that it is required.
function setupRequiredFields(requiredFieldsArray)
{
	// Is the variable set up?
	if (requiredFieldsArray != null)
	{
		// Loop through the requiredfields array and cause the red required star
		// to show up next to the field label.
		var i;
		for(i=0; i<requiredFieldsArray.length; i++)
		{
			// Make sure the field exists before we try to update the image.
			if (eval('typeof(document.' + requiredFieldsArray[i][0] + ')' ) != 'undefined')
			{
				document.images[requiredFieldsArray[i][0]].src='/Images/req.gif';
			}
		}
	}
}

////////////////////////////////////////////////////////////////////////
// This routine checks if any required fields are blank and displays
// a popup on error.
//
// Returns: false if any required fields are blank.
//			true if no required fields are blank.
//
function checkRequiredFields(formName, requiredFieldsList)
{
    var errorflag = false;
    var emptyfields = "";
    var msg = "__________________________________________________\n\n";
    msg += "The form was not submitted because of the following errors.\n";
    msg += "Please correct these errors and re-submit.\n";
    msg += "__________________________________________________\n\n";

////////////////////////////////////////////////////////////////////////
// Check for all of the required fields and display a pop up
// for all blank fields.
////////////////////////////////////////////////////////////////////////
	var i;
	var tempFieldValue;
	// Loop through all of the required fields, from the requiredFieldsList array.
	// Don't bother if we don't have anything to require.
	if (requiredFieldsList != null && requiredFieldsList != "")
	{
		for(i=0; i<requiredFieldsList.length; i++)
		{
			// Does this field exist?
			if (eval('typeof(formName.' + requiredFieldsList[i][0] + ')' ) != 'undefined')
			{
				// Yes, the field exists.  Check if it has a value.
				// Get the value of this field, from the form.
				tempFieldValue = eval('formName.' + requiredFieldsList[i][0] + '.value');
				// Is it empty? (Also catch memo fields, which are " ").
				if ( tempFieldValue == "" || tempFieldValue == " " )
				{
					// Yes, it is empty.  Flag an error and update the error message.
					errorflag = true;
					emptyfields += "-  " + requiredFieldsList[i][1] + "\n";
				}
			}
		}
	}

	// Did we find any empty fields?
    if (errorflag)
    {
		// Yes - finish setting up the error message.
        msg += "The following required fields were empty:\n\n";
        msg += emptyfields;

		// Display the error message in a pop up.
        alert(msg);
        return false;
	}

	// If we got to here, everything is fine.  Return true.
	return(true);
}

////////////////////////////////////////////////////////////////////////
// Function to set up any collapsables whose initial state is CLOSED.
// This data comes from the xml file.
function setupCollapsables(thisForm)
{
	// Get the number of collapsables
	var numberOfCollapsables = eval('document.' + thisForm + '.NumberOfCollapsables.value');

	var variableName;
	var initialState;

	// Loop through each collapsable
	for(j=1; j<=numberOfCollapsables; j++)
	{
		// Get the initial state hidden variable name
		variableName = 'Collapsable' + j + 'InitialState';

		// Get its value.
		initialState = eval('document.' + thisForm + '.' + variableName + '.value');

		// What is the initial state of this collapsable?
		if (initialState == 'CLOSED')
		{
			// It is closed, so close it up now.
			togglecatbycategorynumber(j, thisForm);
		}
	}
}
////////////////////////////////////////////////////////////////////////

// This function is used by course admin and class logistics, so that
// a category can be toggled.  The fields in each group are controlled
// by the courses.xml and classes.xml files.  The courses.js and classes.js
// files control which fields are hidden.
function togglecatbycategorynumber(categoryNumber, formName)
{
	// Get the vb hidden collapsable field name, based on the categoryNumber.
	var variableName = 'Collapsable' + categoryNumber + 'Fields';
	var fieldList;

	// Get the list of fields in this category.
	fieldList = eval('document.' + formName + '.' + variableName + '.value');

	// Split up the fields in this category into an array.
	var splitData = fieldList.split(",");

	var i;
	// Loop through each field in this category.
	for(i=0; i<splitData.length; i++)
	{
		// Trim before we process.
		splitData[i] = Trim(splitData[i]);

		// Now toggle this field.
		toggleid(splitData[i]);
	}
}

// This hiddenFields variable can be filled in with fields that are always to be hidden.
// We start with a leading comma, so the indexOf can work as an exact match.
// Otherwise, CourseApproval would match on CourseApprovalLogic.
var hiddenFields=",";

function toggleid(id)
{
	// Defensive code - we must have an ID.
	if (id != "")
	{
	   document.getElementById(id);
	   var curdisplay = document.getElementById(id).style.display;
		   // Since we want exact matches, delimit the ID and the hidden fields with commas.
		   var terminatedHiddenFields = hiddenFields + ",";
		   var terminatedID = "," + id + ","
		   var alwayshidden = terminatedHiddenFields.indexOf(terminatedID);
		   if (curdisplay == 'none' && alwayshidden == -1)
	   {
		  document.getElementById(id).style.display = '';
	   }
	   else
	   {
		  document.getElementById(id).style.display = 'none';
	   }
	}
}

function showid(id, usemouse, x, y)
{
   var obj = document.getElementById(id).style
   obj.display = '';
   if (!usemouse) {mousex = 0; mousey = 0;}
   obj.left = (mousex + x);
   obj.top = (mousey + y);
}

function hideid(id)
{
   document.getElementById(id).style.display = 'none';
   ToggleElementList(true,['select'],'tag')
}

function inputComment(srcform, srcfield, usemouse, x, y)
{
   var obj;
   var obj2;
   obj = eval('document.' + srcform + '.' + srcfield);
   document.EditorForm.comment.value = obj.value;
   document.EditorForm.commentname.value = srcfield;
   document.EditorForm.commentform.value = srcform;
   ToggleElementList(false,['select'],'tag')
   showid('commentinput', usemouse, x, y);
   showDesign(); //This loads string from form into the editor.
 }

function setComment(srcform)
{
   var obj;
   var srcform;
   showHTML(); //This from the editor to update the text area.
   srcform = document.EditorForm.commentform.value;
   obj = eval('document.' + srcform + '.' + document.EditorForm.commentname.value);
   obj.value = document.EditorForm.comment.value;
   hideid('commentinput');
   ToggleElementList(true,['select'],'tag')
}

function HelpWindow(filename) {
  var WindowDetail=window.open(filename, "HelpWindow", "menubar=no,resizable=yes,scrollbars=yes,width=600,height=400")
}

   DOM = document.getElementById ? true : false;
   IE  = document.all ? true : false;
   NS4 = document.layers ? true : false;

   function ToggleElementList(show,elList,toggleBy) {
      if(!(DOM||IE||NS4)) return true;

      if(NS4&&(toggleBy=="tag")) return true;

      for(var i=0; i<elList.length; i++) {
         var ElementsToToggle = [];
         switch(toggleBy) {
            case "tag":
               ElementsToToggle = (DOM) ? document.getElementsByTagName(elList[i]) :
                                  document.all.tags(elList[i]);
               break;
            case "id":
               ElementsToToggle[0] = (DOM) ? document.getElementById(elList[i]) :
                                     (IE) ? document.all(elList[i]) : 
                                     document.layers[elList[i]];
               break;
         }
         for(var j=0; j<ElementsToToggle.length; j++) {
            var theElement = ElementsToToggle[j];
            if(!theElement) continue;
            if(DOM||IE) {
               if(theElement.name != 'fontname' && theElement.name != 'fontsize' && theElement.name != 'formatblock'){
                  theElement.style.visibility = show ? "inherit" : "hidden";
               } 
            } else if (NS4) {
               if(theElement.name != 'fontname' && theElement.name != 'fontsize' && theElement.name != 'formatblock'){
                  theElement.visibility = show ? "inherit" : "hide";
               }
            }
         }
      }
      return true;
   }

   var theArray = new Object;
   theArray[0] = 'select';
   theArray[1] = 'form';
   theArray.length = 2;

//Jim's JavaScript functions for shuttling items back and
//forth between two dropdown selection boxes.



function PickOptionsCode( SelectBox) // Find the index of the selected option in the select box
{
    var ind = SelectBox.selectedIndex;
    if (ind < 0) { 
        alert("You didn't select an item from the correct select box!");
  } 
     else { 

          var str = SelectBox.options[ind].value;

          return str;
     }
}

function TransferOption( SelectBox1, SelectBox2 ) { // transfer a single option from SelectBox1 to SelectBox2
 
   var i = SelectBox1.selectedIndex;
   
   if(PickOptionsCode ( SelectBox1 ) != null){
        if (i >= 0) {
  
                    SelectBox2.options[ SelectBox2.options.length ] = new Option(PickOptionsCode( SelectBox1), PickOptionsCode( SelectBox1));

                    SelectBox1.options[i] = null;
                    
                   SelectBox1 = sorter(SelectBox1);
		   SelectBox2 = sorter(SelectBox2);
              
         }
    }
}

function SelectAll(selectBox) { // Pass in the name of the select box to be read, and select all the options to be submitted.
   	if (!selectBox) return;
	var len = selectBox.options.length;
   	for(i = 0; i < len;  i++ ) {
		selectBox.options[i].selected = true;

    	}
}



function sorter(selectBox) { // sorts the options of a select box, alphabetically using the text values.
	var o = new Array();

	for (var i=0; i < selectBox.options.length; i++) {
		o[o.length] = new Option( selectBox.options[i].text, selectBox.options[i].value ) ;
		}
	if (o.length==0) { return; }
	o = o.sort( 
		function(a,b) { 
			if ((a.text+"") < (b.text+"")) { return -1; }
			if ((a.text+"") > (b.text+"")) { return 1; }
			return 0;
			} 
		);

	for (var i=0; i<o.length; i++) {
		selectBox.options[i] = new Option (o[i].text, o[i].value );
		}
}



function TransferOptions( SelectBox1, SelectBox2 ) { // transfer multiple options from SelectBox1 to SelectBox2
	if (SelectBox2.options.length > 0 && SelectBox2.options[0].value == 'temp')
  	{
    		SelectBox2.options.length = 0;
  	}
	var sel = false;
  	for (i = 0;i < SelectBox1.options.length;i++)
  	{
    		var current = SelectBox1.options[i];
    		if (current.selected)
    		{
      			sel = true;
      			if (current.value == 'temp')
      			{
        			alert ('You cannot move this text!');
        			return;
      			}
      			txt = current.text;
      			val = current.value;
      			SelectBox2.options[SelectBox2.length] = new Option(txt,val);
      			SelectBox1.options[i] = null;
      			i--;
    		}
  	}
  	if (!sel) alert ('You haven\'t selected any options!');
         SelectBox1 = sorter(SelectBox1);
	 SelectBox2 = sorter(SelectBox2);
}

function Search(searchName, campusID, width, height, formName)
{
	var str = '';
	
	str = "'" + searchName + "','" + campusID + "','', " + width + "," + height + ",'" + formName + "'";
	for (i=5;i < arguments.length;i++)
	{
		str += ",'" + arguments[i] + "'";
		
	}

	str = "ScopedSearch(" + str+ ");";
 	eval(str);
}




function ScopedSearch(searchName, campusID, scope, width, height, formName)
{
   var i=0;
   var URL = ""
   var elementStr = "";

   for (i=6;i < arguments.length;i++)
   {
       elementStr += 'Element' + (i-6) + '=' + arguments[i] + '&';
   }

   URL = "/cgi-win/auth/$customsearch.DLL" +
         "/" + searchName +
         "?ReturnForm=" + formName + "&" +
         elementStr +
         "CampusID=" + campusID + "&" +
         "Scope=" + scope + "&";
   w=window.open(URL, "SearchWindow","scrollbars=yes,resizable=yes,width=" + width + ",height= " + height);
   w.focus();

}
function ScopedSearchCallback(searchName, campusID, scope, width, height, returnFunction)
{
   var i=0;
   var URL = ""
   var elementStr = "";

   URL = "/cgi-win/auth/$customsearch.DLL" +
         "/" + searchName +
         "?ReturnFunction=" + returnFunction+ "&" +
		 "Scope=" + scope + "&" +
         "CampusID=" + campusID + "&";

   w=window.open(URL, "SearchWindow","scrollbars=yes,resizable=yes,width=" + width + ",height= " + height);
   w.focus();
}
	
function SearchCallback(searchName, campusID, width, height, returnFunction)
{
   var i=0;
   var URL = ""
   var elementStr = "";

   URL = "/cgi-win/auth/$customsearch.DLL" +
         "/" + searchName +
         "?ReturnFunction=" + returnFunction+ "&" +
         "CampusID=" + campusID + "&";

   w=window.open(URL, "SearchWindow","scrollbars=yes,resizable=yes,width=" + width + ",height= " + height);
   w.focus();
}

function add_it()
{
 if (eval(document.input)) 
  { 
   if (eval('typeof(document.input.Myuserid)' ) != 'undefined') 
    {  
     document.input.Myuserid.value = (document.EditUser.UserID.value);
	} 
  }
}  
function get_radio_value()
{
var pbook = document.EditUserProperties.PreBooks.value;
for (var i=0; i < document.EditUserProperties.Active.length; i++)
   {
   if (document.EditUserProperties.Active[i].checked)
      {
      var rad_val = document.EditUserProperties.Active[i].value;
      if (rad_val == 'N'){
	   var x = window.confirm("If you continue to inactivate this user " + pbook + " prebook(s) will be deleted"); 
	    if (x == true){
	  	    return true; 	
	    }else{
		    return false;
		}		
       }
	  }
   }
}

function ShowOrDisableEditor()
{
 if (document.NewClass.Directions.value != 'Disabled') {
     inputComment('NewClass', 'Directions', true, -300, -200)
	 }
 else {
	 alert("The Direction field is disabled for this class type")
	 }
}

function ShowOrDisableEditorRemarks()
{
 if (document.NewClass.Remarks.value != 'Disabled') {
     inputComment('NewClass', 'Remarks', true, -300, -200)
	 }
 else {
	 alert("The Remarks field is disabled for this class type")
	 }
}

/**
 * DHTML date validation script. Courtesy of SmartWebby.com (http://www.smartwebby.com/dhtml/)
 */
// Declaring valid date character, minimum year and maximum year
var dtCh= "/";
var minYear=1900;
var maxYear=2100;

function isInteger(s) {
	var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag){
	var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31
		if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
		if (i==2) {this[i] = 29}
   } 
   return this
}

function isDate(dtStr){
	var daysInMonth = DaysArray(12)
	var pos1=dtStr.indexOf(dtCh)
	var pos2=dtStr.indexOf(dtCh,pos1+1)
	var strMonth=dtStr.substring(0,pos1)
	var strDay=dtStr.substring(pos1+1,pos2)
	var strYear=dtStr.substring(pos2+1)

	// 20090706 If the year is two digits, assume 19xx or 20xx.
   if (strYear.length == 2)
   {
	   if (parseFloat(strYear) <= 50)
	   {
			strYear = (parseFloat(strYear) + 2000).toString();
	   }
	   if (parseFloat(strYear) <= 99)
	   {
			strYear = (parseFloat(strYear) + 1900).toString();
	   }
   } // 2 digit year

	strYr=strYear
	if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
	if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
	for (var i = 1; i <= 3; i++) {
		if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
	}
	month=parseInt(strMonth)
	day=parseInt(strDay)
	year=parseInt(strYr)
	if (pos1==-1 || pos2==-1){
		alert("The date format should be : mm/dd/yyyy")
		return false
	}
	if (strMonth.length<1 || month<1 || month>12){
		alert("Please enter a valid month")
		return false
	}
	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
		alert("Please enter a valid day")
		return false
	}

	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
		alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
		return false
	}
	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
		alert("Please enter a valid date")
		return false
	}
return true
}

var LanguagePairs = new Array();
function registerLanguageString(key, value)
{
	LanguagePairs[key] = value;
}

function getLanguageString(key)
{
	return(LanguagePairs[key]);
}
