var debugOn = false;

var okAction = null;
var cancelAction = null;

function playOkAction() {
	// gets called by the popup to once the ok/apply button is pressed.
	// it executes the js code stored as a string in the okAction variable.
	//alert("playing playokaction()");
//	enableLinks();
	eval(okAction);
	okAction = null;
	cancelAction = null;
}

function playCancelAction() {
	// gets called by the popup to once the cancel button is pressed.
	// it executes the js code stored as a string in the cancelAction variable.
	//alert("playing cancelAction");
//	enableLinks();
	eval(cancelAction);
	cancelAction = null;
	okAction = null;
}

function showErrorAlert(errorType, errorMsg, myOkAction, myCancelAction) {
	return showErrorAlert2(errorType, errorMsg, myOkAction, myCancelAction, false);
}

function showErrorAlert2(errorType, errorMsg, myOkAction, myCancelAction, runFlag) {
// displays an alert if of errorType == error or a confirmation box if errorType == note.
	// determine error string to use..
	
	if (!runFlag) {
		//setTimeout("test = showErrorAlert2('" + errorType + "', '" + escape(errorMsg) + "', '" + escape(myOkAction) + "', '" + escape(myCancelAction) + "', true);", 1000);
		return showErrorAlert2(errorType, errorMsg, myOkAction, myCancelAction, true);
	} else {
		errorMsg = unescape(errorMsg);
		myOkAction = unescape(myOkAction);
		myCancelAction = unescape(myCancelAction);
		var myMsg = "BASIX Alert: ";
		switch (errorMsg) {
			case '':
			case 'general':
				myMsg += "There are errors on the page (see the notes in the bottom left corner of the page).\n                     Select OK to continue and address these errors later;\n                     or Cancel to address these errors now.";
				break;
			case 'general_popup':
				myMsg += "There are errors on the page (see the hint section at the bottom of the page).";
				//myMsg = "There are errors on the page.  Please check the notes in the bottom left corner of the page.";
				break;
			case 'onCalculate':
				myMsg += "There are errors on the page (see the notes in the bottom left corner of the page).\nThese errors need to be fixed before the project can be calculated.";
				break;
			case 'crossVentCheck':
				myMsg += "Please note that Cross ventilation is not permissible in this project's postcode.  See help for more information.";
				break;
			case 'createCertificate':
				myMsg += "Are you sure you wish to generate a certificate for this project?\nPlease note that the Certificate will open in a new window.";
				break;
			case 'createReport':
				myMsg += "Are you sure you wish to generate a report for this project?\nPlease note that the Report will open in a new window.";
				break;
			case 'removeDwellings':
				myMsg += "Are you sure you wish to remove the selected dwellings?";
				break;
			case 'removeBuildings':
				myMsg += "Are you sure you wish to remove the selected buildings?";
				break;
			case 'mandatoryCheck':
				myMsg += "Please complete all mandatory fields.";
				break;
			case 'deleteProject':
				myMsg += "Are you sure you wish to delete this project? Once a project has been deleted it can not be restored.";
				break;
			case 'copyProject':
				myMsg += "Are you sure you want to make a copy of this project?";
				break;
			case 'prereleaseProject':
				myMsg += "Recent updates made to the BASIX tool may cause the targets and scores for this project to vary and some data may be lost. Contact the BASIX helpline at basix@planning.nsw.gov.au if you require assistance.   Would you like to continue?.";
				break;
			case 'notCopyProject':
				myMsg += "This project cannot be copied as it is incompatible with the latest version of BASIX.";
				break;
			case 'dtcFull':
				myMsg += "This option is not currently available. Please select simulation or the DTC (rapid) option.";
				break;
			case 'pressCalculate':
				myMsg += "The project must be calculated before this page can be displayed.";
				break;
			case 'maxDwellings':
				myMsg += "The default limit on the number of dwellings you can enter on the BASIX multi-unit tool is set at 50 separate houses, 50 attached houses and 100 units.\nIf you would like to enter a larger project, please contact the Help Desk on 1300 650 908, and access will be arranged for you."
				break;
			case 'projectName':
				myMsg += "The project name must be entered before you can continue from this page.";
				break;
			case 'mustHaveDwellings':
				myMsg += "You must add at least one dwelling to this project in order to proceed beyond the Project details section.";
				break;
			case 'selectProject':
				myMsg += "Please select a project.";
				break;
			case 'removePoolSpa':
				myMsg += "Selecting 'No' for Swimming pool or Spa will remove any associated data you have entered in the Water and Energy sections for Pool or Spa respectively.\nDo you wish to continue?";
				break;
			case 'newProjectName':
				myMsg += "The project name you have entered already exists, please enter a new name.";
				break;
			case 'dwellingTypes':
				myMsg += "Please specify the dwelling types for your project.";
				break;
			case 'landscapeCap':
				myMsg += "You have entered a 'zero' or 'very small' formal landscape area.  Please ensure the landscape area entered in BASIX is correct and consistent with your DA plans, otherwise you may invalidate your development application.";
				break;
            case 'updateAlternativeAssessmentProject':
                myMsg += "This project has been assessed via an Alternative Assessment. Updating this certificate will  Would you like to continue?";
                break;
            case 'copyAlternativeAssessmentProject':
                myMsg += "Copy message for alternative assessment. Would you like to continue?";
                break;
            case 'copyOldProjectInProgress':
                myMsg += "A newer version of the BASIX tool has been released. Details for this project will be migrated to the new tool. This may alter some selections and scores. Would you like to continue?";
                break;			
            default:
				myMsg += errorMsg;
		}
		
		if (okAction == null) {
			//delayed with timer due to browser not rendering innerHTML of notes before displaying this alert box..
			return outputAlert(errorType, myMsg, myOkAction, myCancelAction);
		}
	}
	return;

}

function outputAlert(errorType, myMsg, myOkAction, myCancelAction) {
	// setup actions
	okAction = myOkAction;
	cancelAction = myCancelAction;

	// check if document has been opened (ie. an opener exists) if so then it is a popup of some description with the modal effect on which will need to be disabled.
	if (currentlyInPopUp()) {
		unsetModal();

		// setup modal effect when returning to popup
		okAction += "setModal();";
		cancelAction += "setModal();";
	}
	// alert or confirm error string..
	if (errorType == "error" || errorType == "") {
		alert(myMsg);
		playOkAction();
		return false;
	} else {
		if (errorType == "note" || errorType == "okCancel") {
			//showErrorAlert('confirm', myMsg, 'return true;', 'return false;');
			if (myCancelAction == "") {
				myCancelAction = "return false;";
			}
			if (confirm(myMsg)) {
				playOkAction();
				return true;
			} else {
				playCancelAction();
				return false;
			}
		} else {
			debugAlert("please specify valid error type");
			return false;
		}
	}
}

function mandatoryCheck() {
	// return true; //For debugging/development
	// Scans through all form fields on the page looking for enabled fields that have the classname of "mandatory".
	// It then checks each of these mandatory fields that they have a value depending of the type of the field object.
	var myForm = document.basix_form;
	var errorFound = false;
	var tempFound = false;
	var multiMandatoryArray = new Array();
	var i=0, j=0;
	for (i=0; i < myForm.elements.length; i++) {
		if (myForm.elements[i].disabled == false && myForm.elements[i].className.indexOf("mandatory") != -1) {
			// field is marked as a mandatory field.
			
			var multiMandatory = false;
			// if field is a joint mandatory field.. ie. if it OR another field are mandatory but not necessarily both of them..
			if (myForm.elements[i].className.indexOf("mandatory_") != -1) {
				multiMandatory = true;
				
			}
			
			tempFound = false;
			switch (myForm.elements[i].type) {
				// depending on type of field..
				case 'text':
					if (myForm.elements[i].className.indexOf("textflt") != -1) {
						// field content is of type float.. check to see if value of 0 or more exists.
						if (myForm.elements[i].value == "" || !(parseFloat(myForm.elements[i].value) >= 0)) {
							tempFound = true;
						}
					} else {
						//alert("checking " + myForm.elements[i].id + ".");
						if (myForm.elements[i].value == "") {
							tempFound = true;
						}
					}
					break;
				case 'select':
				case 'select-one':
					if (myForm.elements[i].options.selectedIndex == 0) {
						tempFound = true;
					}
					break;
				case 'radio':
					// added by Helen -> helen@massmedia.com.au on 01/03/05
					var radioSelected = false;
					if (!myForm.elements[i].checked) { 
						var radioElement = myForm.elements[i].name;
						for (k=0; k < myForm.elements.length; k++) {
							if (radioElement == myForm.elements[k].name && i != k) {
								if (myForm.elements[k].checked) {
									radioSelected = true;
								}
							}
						}
						if (radioSelected == false) {
							tempFound = true;
						}
					}
					break;
				default:
			}
			if (multiMandatory) {
				myReg = /^.*mandatory_(.*)[ ]*.*$/;
				var myMatchArray = myReg.exec(myForm.elements[i].className);
				if (tempFound) {
					if (multiMandatoryArray[myMatchArray[1]] == null) {
						multiMandatoryArray[myMatchArray[1]] = true;
						//break; // may as well break out here as only need to find the first mandatory field.. comment this line out if you wish to search through and discover every mandatory field.
					}
				} else {
					multiMandatoryArray[myMatchArray[1]] = false;
				}
			} else {
				if (tempFound) {
					errorFound = true;
					break; // may as well break out here as only need to find the first mandatory field.. comment this line out if you wish to search through and discover every mandatory field.
				}
			}
		}
	}
	// for all joint mandatory fields check if any had an error..
	for (mandatoryGroup in multiMandatoryArray) {
		// foreach key in the multiMandatoryArray..
		if (multiMandatoryArray[mandatoryGroup]) {
			errorFound = true;
			break;
		}
	}
	
	if (errorFound) {
		if (!currentlyInPopUp()) {
			// must be on main window..
			parent.frames[1].addNote("Please complete all mandatory fields.", "normal");
		} else {
			// must be in a popup..
			addNote("Please complete all mandatory fields.", "normal");
		}
		//alert("showing eeror showErrorAlert");
//		return showErrorAlert("note","","nav2();","");
		//return showErrorAlert("note", "", "nav2('" + nextPageUrl + "', true, true);", "nav2('" + nextPageUrl + "', true, false);waitDiv(false);");
		return false;
	} else {
		return true;
	}
}

function checkZeroFirst(myStr) {
	// need to check for strings of length greater than 2 instead of 1, since when a field contains a zero and the user tabs to it, the field data
	// is highlighted.  When the user presses to over-write the highlighted value, it is returned to this function as not being a string of length=1,
	// but being a string of length 2.  The remove_char() function needs to cater for this.
//debugAlert(myStr);
	if (myStr.length == 2 && myStr.indexOf(".") == 1) {
		// allow the 2 character string of a Character followed by a Decimal point.
		return false;
	}
	if (myStr.length > 2 && myStr.indexOf("0") == 0 && myStr.indexOf(".") != 1) {
		return true;
	} else {
		return false;
	}
}

function checkDecimalPlaces(myStr) {
	// need to restrict to 2 decimal places at most..
	if (myStr.search(/^[0-9]*(\.[0-9]{0,2})?$/) != -1) { // removes any occurence of all characters except digits and the decimal point
		return true;
	} else {
		return false;
	}
}

function hasSelected(myObj) {
// determine if any characters are highlighted in the input field.
	if (document.selection) {
		str = document.selection.createRange().text;
	}
	else if (myObj.selectionStart || myObj.selectionStart == '0') {
		var selStart = myObj.selectionStart;
		var selEnd = myObj.selectionEnd;
		str = myObj.value.substring(selStart,selEnd);
	}
	if (str != "") {
		return true;
	} else {
		return false;
	}
}

//Ensure only numeric values entered. doesn't allow values beginning with zero other than zero itself.
function validate_numeric_sf(e, myObj) {
	var key;
	if (window.event || !e.which) {
		key = e.keyCode;
	} else if (e) {
		key = e.which;
	}
	var keyChar = String.fromCharCode(key);
	if ((key >=35 && key <=40) || key==8 || key==9) { // allow functional keys eg. arrows, home, end, del, decimal point... etc.
		return true;
	}
	if ((key > 47 && key < 58) || key == 46) {  // allow numeric keys
		if (hasSelected(myObj) || (!checkZeroFirst(myObj.value + keyChar) && checkDecimalPlaces(myObj.value + keyChar))) {
			return true;
		} else {
			return false;
		}
	}
	if (key == 99 || key == 118 || key == 67 || key == 86) { // allow c and v in for copy and paste functionality - any c and v characters can be removed by the remove_char function added to the onkeyup event and the onblur event.
		return true;
		// can't perform check for "0" value or decimal length here because control key press is not captured therefore will skip past pasted values
	} else {
		// deny all other keys
		return false;
	}
}

// to remove all but numerical values and the decimal point, in case user attempts to paste in other characters 
function remove_char(myField, isBlur) {
	var myFieldStr = myField.value.substr(-1,(myField.value.length));
	var myRegEx = /[^0-9.]+/;
	if(myRegEx.test(myFieldStr)) {
		myField.value = myField.value.replace(/[^0-9.]+/,""); // removes any occurence of all characters except digits and the decimal point
	}
	if(myField.value.length > 1 && myField.value.charAt(0) == 0 && myField.value != "" && myField.value.charAt(1) != ".") {  // caters for zero as first character only, removing all subsequent characters if it is the case. Remembering to allow for 0 followed by a decimal point.
		myField.value = 0;
	}
	if(myField.value.indexOf(".") != -1) {
		var numbers = new Array();
		numbers = myField.value.split(".");
		if(!checkDecimalPlaces(myField.value)) {
			myField.value = numbers[0] + "." + numbers[1].substr(1,2);
		}
		if (isBlur && !numbers[1]) {
			myField.value = numbers[0];
		}
	}
}

//Ensure only numeric values entered. doesn't allow values beginning with zero other than zero itself.
function validate_integer_sf(e, myObj) {
	var key;
	if (window.event || !e.which) {
		key = e.keyCode;
	} else if (e) {
		key = e.which;
	}
	var keyChar = String.fromCharCode(key);
	if ((key >=35 && key <=40) || key==8 || key==9)  // allow functional keys eg. arrows, home, end, del... etc.
		return true;
	if (key > 47 && key < 58) // allow numeric keys
		return (!checkZeroFirst(myObj.value + keyChar));
	if (key == 99 || key == 118 || key == 67 || key == 86) { // allow c and v in for copy and paste functionality - any c and v characters can be removed by the remove_char function added to the onkeyup event and the onblur event.
		return true;
	} else {
		// deny all other keys
		return false;
	}
}

function validate_phoneNumbers_sf(e, myObj) {
	if (validate_numbers_sf(e, myObj)) {
		return true;
	} else {
		// check if character is an additional space character, "(", "), or "+"...
		var key;
		if (window.event || !e.which) {
			key = e.keyCode;
		} else if (e) {
			key = e.which;
		}
		var keyChar = String.fromCharCode(key);
		if (key == 32 || key == 40 || key == 41 || key == 43) {
			return true;
		} else {
			return false;
		}
	}
}

//Ensure only integers values entered, includes values beginning with zero
function validate_numbers_sf(e, myObj) {
	var key;
	if (window.event || !e.which) {
		key = e.keyCode;
	} else if (e) {
		key = e.which;
	}
	var keyChar = String.fromCharCode(key);
	if ((key >=35 && key <=40) || key==8 || key==9)  // allow functional keys eg. arrows, home, end, del... etc.
		return true;
	if (key > 47 && key < 58) // allow numeric keys
		return true;
	if (key == 99 || key == 118 || key == 67 || key == 86) { // allow c and v in for copy and paste functionality - any c and v characters can be removed by the remove_char function added to the onkeyup event and the onblur event.
		return true;
	} else {
		// deny all other keys
		return false;
	}
}

// to remove all but numerical values, in case user attempts to paste in other characters 
function integerField_remove_char(myField) { 
	var myFieldStr = myField.value.substr(-1,(myField.value.length));
	var myRegEx = /[^0-9]+/;
	if(myRegEx.test(myFieldStr)) {
		myField.value = myField.value.replace(/[^0-9]+/,""); // removes any occurence of all characters except digits
	}
	if(myField.value.length > 1 && myField.value.charAt(0) == 0 && myField.value != "") {
		myField.value = 0;
	}
}

// to remove all but phone number values, in case user attempts to paste in other characters 
function phoneNumber_remove_char(myField) { 
	var myFieldStr = myField.value.substr(-1,(myField.value.length));
	myField.value = myField.value.replace(/[^(0-9)^( )^\(^\)^\+]+/,""); // removes any occurence of all characters except digits, +, (, ) or a space.
}

function checkLength(e, myFieldObj, myLength) {
	// Acts as maxLength attribute. Used with an onkeypress event.
	// Written for textarea fields which do not cater for maxLength.
	var key;
	if (window.event || !e.which) {
		key = e.keyCode;
	} else if (e) {
		key = e.which;
	}
	if ((key >=35 && key <=40) || key == 8 || key == 9 || key == 46)  // allow functional keys eg. arrows, home, end, delete... etc.
		return true;
	if (myFieldObj.value.length >= myLength) {
		// if greater than maximum length, deny key to be written out.
		return false;
	} else {
		// allow key.
		return true;
	}
}

function minLength(myFieldObj, myLength) {
	if (myFieldObj.value.length < myLength) {
		return true; // return true for length of value is less than myLength
	} else {
		return false;
	}
}

function displayMandatory(myFieldId, isMandatory) {
// make or remove a field as being mandatory.
// change the classname of the field object and add "mandatory" class to className if isMandatory == true else remove "mandatory" from the className.
// hide or show the mandatory div tag with the * indicating whether it is mandatory or not.
	var myFieldObj = document.getElementById(myFieldId);
	if (isMandatory) {
		// add mandatory..
		if (myFieldObj.className.indexOf("mandatory") == -1) {  // if not already mandatory.
			if (myFieldObj.className == "") {
				myFieldObj.className = "mandatory";
			} else {
				myFieldObj.className += " mandatory";
			}
			// show * div..
			show(myFieldId + "_star");
		}
	} else {
		// remove mandatory..
		if (myFieldObj.className.indexOf("mandatory") != -1) {  // only if currently mandatory.
			myFieldObj.className = myFieldObj.className.replace(/[ ]*mandatory/g, ''); // remove " mandatory" from the class name
			// hide * div..
			hide(myFieldId + "_star");
		}
	}
}

function makeMandatory(mySelectBox, myMandatoryFieldId, myValueArray) {
// will make the form element, myMandatoryFieldId, mandatory if the current selected value of the dropdown is in the myValueArray..
// if current selected value not in array, then make the myMandatoryFieldId not mandatory.
// if myValueArray element begins with a "!" character then treat as for all values but not that one.
	for (var i=0; i < myValueArray.length; i++) {
		if (myValueArray[i].substr(0,1) == "!") {
			if (myValueArray[i].substr(1) == mySelectBox.options[mySelectBox.options.selectedIndex].value) {
				displayMandatory(myMandatoryFieldId, false);
			} else {
				displayMandatory(myMandatoryFieldId, true);
				break;
			}
		} else {
			if (myValueArray[i] == mySelectBox.options[mySelectBox.options.selectedIndex].value) {
				// if exists in value array then make mandatory..
				displayMandatory(myMandatoryFieldId, true);
				break;
			} else {
				// if does not exist in value array then remove mandatory if exists..
				displayMandatory(myMandatoryFieldId, false);
			}
		}
	}
}

function showMandatoryIndication(mySelectBox, myMandatoryFieldId, myValueArray) {
// will hide/show the mandatory field indication, myMandatoryFieldId, if the current selected value of the dropdown is in the myValueArray..
// if current selected value not in array, then make the myMandatoryFieldId hidden.
// this function only shows/hides the * that indicates that a field is mandatory, the makeMandatory field is a function that adds/removes the mandatory class for that field
	for (var i=0; i < myValueArray.length; i++) {
		if (myValueArray[i] == mySelectBox.options[mySelectBox.options.selectedIndex].text) {
			// if exists in value array then show mandatory indication (i.e. *) ..
			document.getElementById(myMandatoryFieldId).style.display = "inline";
			break;
		} else {
			// if does not exist in value array then hide mandatory indication (i.e. *)..
			document.getElementById(myMandatoryFieldId).style.display = "none";
		}
	}
}	

function resetOtherField(currentFieldName, otherFieldName) {
	// reset the otherFieldName form field if the currentFieldName does not have content.
	var currentFieldObj = document.basix_form.elements[currentFieldName];
	var otherFieldObj = document.basix_form.elements[otherFieldName];
	switch (currentFieldObj.type) {  // depending on type of field object..
		case 'select-one':
		case 'select':
			if (currentFieldObj.options.selectedIndex == 0) {
				otherFieldObj.options.selectedIndex = 0;  //reset to default first option in select list.
			}
			break;
		default:
			break;
	}
}

function either(currentFieldName, otherFieldName) {
	// reset the otherFieldName form field if the currentFieldName has content.
	var currentFieldObj = document.basix_form.elements[currentFieldName];
	var otherFieldObj = document.basix_form.elements[otherFieldName];
	switch (currentFieldObj.type) {  // depending on type of field object..
		case 'select-one':
		case 'select':
			if (currentFieldObj.options.selectedIndex != 0) {
				otherFieldObj.options.selectedIndex = 0;  //reset to default first option in select list.
			}
			break;
		case 'text':
			if (currentFieldObj.value != "") {
				otherFieldObj.value = "0";  //reset to default value of zero (0)
			}
			break;
	}
}

var myPageLinks = new Array();

function disableLinks() {
// loops through all links on the current document and sets all the href attributes to a void javascript call.
// It also keeps record of each link's href attribute value in the global array myPageLinks, to be used when reestablishing the links with function enableLinks().
	if (myPageLinks.length == 0) {
		for (var i=0; i < document.links.length; i++) {
//debugAlert("disabling link: " + document.links[i].href);
			myPageLinks[i] = document.links[i].href;
			if (document.links[i].getAttribute("rel") && document.links[i].getAttribute("rel").indexOf("popupWin") != -1) {
				document.links[i].href = "javascript://";
			} else {
				document.links[i].href = "javascript: if (checkOpenWindows()) void(0);";
			}
		}
	}
}

function checkOpenWindows() {
	if (popupWindowRef) {
		if (popupWindowRef != null && typeof(popupWindowRef) != 'undefined' && !popupWindowRef.closed) {
			//if (popupWindowRef.myErrorWin != null && typeof(popupWindowRef.myErrorWin) != 'undefined' && !popupWindowRef.myErrorWin.closed) {
			//	popupWindowRef.myErrorWin.focus(true); 
			//} else {
				popupWindowRef.focus(true); 
			//}
			return true;
		}
	}
}

function enableLinks() {
//alert("enabling " + myPageLinks.length + " links out of " + document.links.length + " links");
// if links are currently stored in the global array variable myPageLinks, then
// loop through all links in the current document and reassign the links as per the myPageLinks variable array values.
	if (myPageLinks.length > 0) {
		for (var i=0; i < document.links.length; i++) {
		// for each link in the document associate the first link array value from myPageLinks with the current link's href.
		// Then pop off the first element of the myPageLinks array.
			document.links[i].href = myPageLinks[0];
			myTemp = myPageLinks.slice(1);
			myPageLinks = myTemp;
		}
	}
	return true;
}

function waitingForAlert() {
// returns true if the confirmation or alert popup box is open.. else returns false.
	if (typeof(myErrorWin) != "undefined" && !myErrorWin.closed) {
		// not back from confirmation window.
		return true;
	} else {
		// not currently waiting for the confirmation window.
		return false;
	}
}

/*************************************/
/* for debugging                     */
function debugAlert(myMessage) {
	if (debugOn) {
		if (currentlyInPopUp()) {
			unsetModal();
			myMessage += "\n\n(NB. the popup modal effect has been disabled in order to display this alert.)";
		}
		alert(myMessage);
	}
}

/*************************************/
