// Perseus JavaScript Functions
// For assistance, please e-mail techsupport@perseus.com
// (c) 2002 Perseus Development Corp.

//Version 3.01 10/13/00
//Version 5.00 03/06/02 BP

var PdcForm;	//Form

function PdcValidate() {
	var ValidationType 	//String
	var ValCommands;	//Array
	var ElementIndex;	//Number
	var ErrorMessage;	//String
	var ArgOne;			//String
	var ArgTwo;			//String
	var Result;			//Boolean
	var ValArr;			//Array
	var MsgArr;			//Array
	var Message;		//Array
	var MessageTable;	//Object
	var QuestionName;	//String
	var S;				//String

	PdcForm = document.PdcSurvey;

	//If no validation field then exit and assume success.
	if (PdcForm.elements["PdcValidation"] == null) return true;

	S = PdcForm.elements["PdcValidation"].value;
	if (S != "") {ValArr = S.split(";");}

	S = PdcForm.elements["PdcValidationMessages"].value;
	if (S != "") {
		MsgArr = S.split(";");

		MessageTable = new Array();
		for (var i=0;i<MsgArr.length;i++) {
			//Build an array of the message name/value pairs.
			Message = MsgArr[i].split("|");
			MessageTable[Message[0]] = Message[1];
		}
	}

	for (var i=0;i<ValArr.length;i++){
		CurrentString = new String(ValArr[i]);

		if (CurrentString.length > 0) {

			ValCommands = CurrentString.split("|");

			QuestionName = ValCommands[0];
			ElementIndex = GetFormIndex(QuestionName);

			ValidationType = ValCommands[1];
			ArgOne = ValCommands[2];
			ArgTwo = ValCommands[3];

			switch (ValidationType) {
				//Question validations.
				case "ReqAns": {
					Result = IsQuestionAnswered(QuestionName);

					//Some questions use ArgOne to specify a more descriptive question name.
					if ((ArgOne != "") && (ArgOne != null)) QuestionName = ArgOne;
					break;
				}
				case "ChkMin": {
					Result = (SelectedCount(QuestionName) >= Number(ArgOne));
					break;
				}
				case "ChkMax": {
					Result = (SelectedCount(QuestionName) <= Number(ArgOne));
					break;
				}
				case "ChkExc": {
					Result = (SelectedCount(QuestionName) == Number(ArgOne));
					break;
				}
				case "ReqSum": {
					//#626 Get the current total as ArgTwo and verify against the expected
					//total (ArgOne). If the question has not been answered ArgTwo will
					//be zero, this is a valid condition.
					ArgTwo = QuestionTotal(QuestionName);
					Result = ((ArgTwo == 0) || (ArgTwo == Number(ArgOne)))
					break;
				}
				case "ReqRnk": {
					Result = ValidateRankings(QuestionName);
					if (ArgOne != "") QuestionName = ArgOne;
					break;
				}

				//Topic validations.
				//#530 Allow for empty field value.
				case "Email": {
					var fieldValue = PdcForm.elements[ElementIndex].value;
					Result = ((fieldValue == "") || (IsValidEmailAddress(fieldValue)));
					break;
				}
				case "Num": {
					var fieldValue = PdcForm.elements[ElementIndex].value;
					Result = ((fieldValue == "") || (IsNumber(fieldValue)));
					break;
				}

				case "MinLen": {
					var fieldValue = PdcForm.elements[ElementIndex].value;
					Result = ((fieldValue == "") || (fieldValue.length >= Number(ArgOne)));
					break;
				}

				case "Range": {
					var fieldValue = PdcForm.elements[ElementIndex].value;
					Result = ((fieldValue == "") || (ValidateNumber(fieldValue, ArgOne, ArgTwo)));
					break;
				}

				default: {
					//Used for debugging.
					//alert("An invalid validation command was specified (" + ValidationType + ").");
					return true;
				}
			}

			if (Result == false) {

				if (ElementIndex != -1) {
				with(PdcForm.elements[ElementIndex]) {
					if ((type == "text") || (type == "textarea") || (type == "password")) {
						select();
					} else {
						focus();
					}
				}
				}

				//Jump to the problem question.
				window.location = "#" + QuestionName;

				//Get the error message from the table and replace any placeholders.
				ErrorMessage = MessageTable[ValidationType];

				if (QuestionName == "QInformation") {
					ErrorMessage = ErrorMessage.replace(/%Q/, "What types of information are you looking for TODAY?");
					}
				if (QuestionName == "QDiseaseState") {
					ErrorMessage = ErrorMessage.replace(/%Q/, "Are you interested in information on any of the following?");
					}
				if (QuestionName == "QVisit") {
					ErrorMessage = ErrorMessage.replace(/%Q/, "I am visiting Depression.com today primarily for: ");
					}
				if (QuestionName == "QInfoChild") {
					ErrorMessage = ErrorMessage.replace(/%Q/, "What types of information are you looking for TODAY?");
					}
				if (QuestionName == "QDiseaseChild") {
					ErrorMessage = ErrorMessage.replace(/%Q/, "Are you interested in information on any of the following? ");
					}
				if (QuestionName == "QMoreQuestion") {
					ErrorMessage = ErrorMessage.replace(/%Q/, "You can stop now, or continue ");
					}

				ErrorMessage = ErrorMessage.replace(/%1/, ArgOne);
				ErrorMessage = ErrorMessage.replace(/%2/, ArgTwo);

				//Alert the user.
				alert(ErrorMessage);
				return false;
			}
	   }
	}
	return true;
}

function RandomizeChoices(QuestionName, SelectedValue) {
	//Randomizes the contents of an option list.
	//Don't move the first item which is the placeholder.
	//(e.g., "", or "(Click to choose)")

	var y;
	var XText, XValue;
	var YText, YValue;

	PdcForm = document.PdcSurvey;
	var ChoiceList = PdcForm.elements[GetFormIndex(QuestionName)];
	var OptionCount = ChoiceList.options.length - 1;
	var SelectedIndex = SelectedValue;

	// Loop thru the options.
	for (var x=1;x<OptionCount;x++){
	   	// Swap the current option with a randomly select different option
		y = Math.floor(Math.random() * OptionCount) + 1;
		XText = ChoiceList.options[x].text;
		XValue = ChoiceList.options[x].value;
		YText = ChoiceList.options[y].text;
		YValue = ChoiceList.options[y].value;
		ChoiceList.options[x] = new Option(YText, YValue);
		ChoiceList.options[y] = new Option(XText, XValue);

        // Preserve the selection.
        if (SelectedValue == XValue) {
			SelectedIndex = y;
		} else if (SelectedValue == YValue) {
			SelectedIndex = x;
		}
	}
	// Reset the selection.
	ChoiceList.selectedIndex = SelectedIndex;
	return;
}

// Autojump based on a list selection.
function SelectJump(sel, JumpString) {
   var SelArr = JumpString.split(";");
   var ValArr = new Array();

   for (var i=0;i<SelArr.length;i++){
     if (SelArr[i].length > 0) {
       ValArr = SelArr[i].split("|");
         if((ValArr.length == 2) && (parseInt(sel.options[sel.selectedIndex].value) == parseInt(ValArr[0]))){
            window.location = ValArr[1]
            break;
         }
      }
   }
}

// Support functions.

//Return true if the value falls within the range.
function ValidateNumber(Value, Minimum, Maximum) {
	var result = false;

	//Test if the value is a number. Exit if this fails.
	if (IsNumber(Value)) {
		result = true;
		Value = Number(Value);
	} else {
		return false;
	}

	if (Minimum != "" && Maximum != "") {
		result = ((Value >= Number(Minimum)) && (Value <= Number(Maximum)));
	} else if (Minimum != "") {
		result = (Value >= Number(Minimum));
	} else if (IsNumber(Maximum)) {
		result = (Value <= Number(Maximum));
	}

	return result;
}

//Return true if the supplied value is a number.
function IsNumber(Value) {
	//Use a regular expression to test if the value is a number.
	//Look for an optional minus sign followed by any number of digits
	//an optional decimal place (comma or period), and optional decimal digits.
	return Boolean(Value.match(/^-?\d+[,.]?\d*-?$/));
}

//Return the number of selected choices for the question.
function SelectedCount(QuestionName) {
	var x = 0;
	var r = new RegExp("^" + QuestionName + "_");

	for(var i=0;i<PdcForm.elements.length;i++) {
		//If the element matches the reg exp and is checked add it to the total count.
		if (PdcForm.elements[i].name.match(r) && PdcForm.elements[i].checked) {
			x = x + 1;
		}
	}
	return x
}

//Return the total for the specified question.
function QuestionTotal(QuestionName) {
	var FieldTotal = 0;
	var r = new RegExp("^" + QuestionName + "_");

	for(var i=0;i<PdcForm.elements.length;i++) {
		//If the element matches the reg exp and it's value is not empty add it to the total.
		if (PdcForm.elements[i].name.match(r) && (PdcForm.elements[i].value != "")) {
			FieldTotal += parseFloat(PdcForm.elements[i].value);
		}
	}

	//Return the accumulated total.
	return FieldTotal;
}

//Return true if the email address is valid.
function IsValidEmailAddress(address) {

	// Smallest email address is a@b.c
	if (address.length < 5) return false;

	// look for illegal characters.
	if (address.match(/[,|\/\\]|(@.*@)|(\.\.)|(\.$)/)) return false;

	// Check for proper format.
	if (address.match(/^[\w\-\.]+[\%\+]?[\w\-\.]*\@[0-9a-zA-Z\-]+\.[0-9a-zA-Z\-\.]+$/)) {
		return true;
	} else {
		return false;
	}
}

//Return whether the question has been answered.
function IsQuestionAnswered(QuestionName) {
	var r = new RegExp("^" + QuestionName);

	for(var i=0;i<PdcForm.elements.length;i++) {

		with (PdcForm.elements[i]) {
			//If the element matches the reg exp test based on type.
			if (name.match(r)) {
				if ((type == "text") || (type == "textarea")) {
					return (value != "");
				}
				else if ((type == "checkbox") || (type == "radio")) {
					if (checked) return true;
				}
				else if ((type == "select-one") || (type == "select-multiple")) {
					var selectedIndex = SelectedOption(options);

					//If there is a selected option and it's value is non-zero (the placeholder
					//value is zero) then return true.
					if ((selectedIndex != 0) && (options[selectedIndex].value != 0)) {
						return true;
					}
				}
			}
		}
	}
	return false;
}

//Return the index of the selected option from the array.
function SelectedOption(OptionArray) {

	for(var x=0;x<OptionArray.length;x++) {
		if (OptionArray[x].selected) return x;
	}
	return 0;
}

//Return true if all topics in the table have unique choice selections.
function ValidateRankings(QuestionName) {
	var Index;
	var r = new RegExp("^" + QuestionName + "_");
	var ChoiceValues = new Array();

	for(var i=0;i<PdcForm.elements.length;i++) {
		Index = 0;  //Clear index on each pass.

		with (PdcForm.elements[i]) {
			//If the element matches the reg exp test based on type.
			if (name.match(r)) {

				//Get the index of the selected item.
				if (type == "select-one") {
					Index = SelectedOption(options);
				} else if ((type == "radio") && checked) {
					Index = Number(value);
				}

				//If there is a selected index test if it has already been set.
				if (Index != 0) {
					if (ChoiceValues[Index] == 1) {
						return false;
					} else {
						ChoiceValues[Index] = 1;
					}
				}
			}
		}
	}
	return true;
}

//Return the index of the specified form element.
function GetFormIndex(ElementName) {
	var i;
	for(i=0;i<PdcForm.elements.length;i++) {
		if (PdcForm.elements[i].name == ElementName) {
			return i;
		}
	}
	return -1;
}

// These functions allow forms to be AutoSubmitted.
// If the user doesn't change any values before the timeout
// then the form will be submitted and the results cleared.

var AutoReset;	// Boolean
var InitialValues = new Array(); // Initial values of each control of the form
var LastValues = new Array(); 	 // Values of each control of the form the last time the timer elapsed

// Records initial values and starts the first call to the timer.
function AutoSubmit(ArgOne) {

	PdcForm = document.PdcSurvey;
	AutoReset = Boolean(ArgOne);

	RecordValues();
	RunTimer();
}

// Record the initial values of all of the form elements.
function RecordValues() {

   for (x=0;x<PdcForm.elements.length;x++) {
      if ((PdcForm.elements[x].type == "radio") || (PdcForm.elements[x].type == "checkbox")) {
         InitialValues[x] = PdcForm.elements[x].checked
      } else if ((PdcForm.elements[x].type == "select-one") || (PdcForm.elements[x].type == "select-multiple")) {
         InitialValues[x] = PdcForm.elements[x].options[PdcForm.elements[x].selectedIndex].value
      } else {
         InitialValues[x] = PdcForm.elements[x].value
      }
   }
}

// Set the window timeout.
function RunTimer() {
	// Set the time out to 5 minutes.
	// Specified in thousandths of a second (e.g., 1000 = 1 second, 60000 = 1 minute)
   	var Timeout = 300000;
	window.setTimeout("CheckValues();", Timeout)
}

function CheckValues() {
   // determine if the control values have changed, and if so, submit and reset
   var ChangeFromInit = false;
   var ChangeFromLast = false;

   // for each form element
   for (x=0;x<PdcForm.elements.length;x++) {
      // if the element doesn't equal the initial value
      if ((PdcForm.elements[x].type == "radio") || (PdcForm.elements[x].type == "checkbox")) {
         if (InitialValues[x] != PdcForm.elements[x].checked)
         	ChangeFromInit = true;
      } else if ((PdcForm.elements[x].type == "select-one") || (PdcForm.elements[x].type == "select-multiple")) {
         if (InitialValues[x] != PdcForm.elements[x].options[PdcForm.elements[x].selectedIndex].value)
         	ChangeFromInit = true;
      } else {
         if (InitialValues[x] != PdcForm.elements[x].value) ChangeFromInit = true;
      }
   }

   // if changed from the initial value
   if (ChangeFromInit) {
      // for each form element
      for (x=0;x<PdcForm.elements.length;x++) {

		 with(PdcForm.elements[x]) {

			 // if the element doesn't equal the last value
			 if ((type == "radio") || (type == "checkbox")) {
				if (LastValues[x] != checked) ChangeFromLast = true;
				LastValues[x] = checked
			 } else if ((type == "select-one") || (type == "select-multiple")) {
				if (LastValues[x] != options[selectedIndex].value) ChangeFromLast = true;
				LastValues[x] = options[selectedIndex].value
			 } else {
				if (LastValues[x] != value) ChangeFromLast = true;
				LastValues[x] = value;
			 }
		 }
      }

      // If not changed from last value submit the form.
      if (!ChangeFromLast) {

		// For a kiosk use of a web survey, reset the form to blank
		// else submit the form.
		if (AutoReset)
			// If Reset Button exists, click it
			if (PdcForm.reset) {
				PdcForm.reset.click();
			// Else perform form reset
			} else {
				PdcForm.reset();
			}
		else
			// If Submit Button exists, click it
			if (PdcForm.submit) {
				PdcForm.submit.click();
			// Else perform form submit
			} else {
				PdcForm.submit();
			}
	  }
   }
   RunTimer();
}

//Store a cookie with the supplied name/value (path and expires are optional).
function SetCookie(Name, Value, Path, Expires) {
	var CookieString;

	CookieString = Name + "=" + escape(Value)

	if (Path) CookieString += "; path=" + Path;
	if (Expires) CookieString += "; expires=" + Expires.toGMTString();

	document.cookie = CookieString
}

//Answer the stored value for the named cookie.
function GetCookieValue(Name) {
	var Cookies;
	var NameValuePair;
	var CookieString = document.cookie;

	//Get an array of cookie pairs by splitting on ;
	Cookies = CookieString.split("; ");

	for (var i=0;i<Cookies.length;i++){
		NameValuePair = Cookies[i].split("=");
		if (NameValuePair[0] == Name) {
			return unescape(NameValuePair[1]);
		}
	}
}

//Save the current page.
function SaveCurrentPage() {
	var d = new Date();

	//Set the cookie to expire in one month.
	d.setMonth(d.getMonth() + 1);
	SetCookie(CurrentPageCookieName(), document.PdcSurvey.PdcCurrentPage.value, "/", d);
}

//Check if there was a previous current page.
function CheckCurrentPage() {
	var CurrentPage = GetCookieValue(CurrentPageCookieName());

	//Verify that current page is non-null and not an empty string.
	//Verify that there is a nextpage field on this page.
	if ((CurrentPage != null) && (CurrentPage != "") && (document.PdcSurvey.PdcNextPage != null))
		document.PdcSurvey.PdcNextPage.value = CurrentPage;
}

//Answer the name of the cookie to save the current page with.
function CurrentPageCookieName() {
	var ProjectName;

	ProjectName = document.PdcSurvey.PdcProjectID.value;
	if (ProjectName == "")
		return "PdcCurrentPage";
	else
		return "Pdc" + ProjectName;
}
