/*********************************************************
Set of JavaScript functions used throughout the database

JavaScript Validation 2.0, 19/Mar/2001
Jake Howlett, http://www.codestore.org/

**********************************************************/

/***********************************************************
errorHandler()
Used by Netscape to return the error message to the user.
Best used only when debuggind in development. Turn on by
adding the following line to a form:
if (navigator.appName=="Netscape") window.onerror = errorHandler;
***********************************************************/
function errorHandler( e, f, l ) {
	alert("Error\nFile: " + f + "\nLine: " + l + "\nError:" + e);
	return true;
}


/***********************************************************
trim is a simple function to remove leading/trailing spaces
************************************************************/

function trim(aStr) {
	return aStr.replace(/^\s{1,}/, "").replace(/\s{1,}$/, "")
}


var today  = new Date();
var expiry = new Date(today.getTime() + 365 * 24 * 60 * 60 * 1000);

function getCookieVal(offset) {
    var endstr = document.cookie.indexOf (";", offset);

    if (endstr == -1) {
	endstr = document.cookie.length;
    }

    return unescape(document.cookie.substring(offset, endstr));
}

function getCookie(name) {
	var end = 0; var result = 0;
	var myCookie = " " + document.cookie + ";";
	var searchFor = " " + name + "=";
	var start = myCookie.indexOf(searchFor);
	if (start > -1) {
		start += searchFor.length;
		end = myCookie.indexOf(";", start);
		if (end > -1)
			result = unescape(myCookie.substring(start, end));
 	}
 return result;
}

function getParameter ( queryString, parameterName ) {
// Add "=" to the parameter name (i.e. parameterName=value)
var parameterName = parameterName + "=";
if ( queryString.length > 0 ) {
// Find the beginning of the string
begin = queryString.indexOf ( parameterName );
// If the parameter name is not found, skip it, otherwise return the value
if ( begin != -1 ) {
// Add the length (integer) to the beginning
begin += parameterName.length;
// Multiple parameters are separated by the "&" sign
end = queryString.indexOf ( "&" , begin );
if ( end == -1 ) {
end = queryString.length
}
// Return the string
return unescape ( queryString.substring ( begin, end ) );


}
// Return "null" if no parameter has been found
return "null";
}
}

function getEncodedParameter ( queryString, parameterName ) {
//added 05/02/2006 by PDA fopr use with the Shipping parameter which is encoded
// Add "=" to the parameter name (i.e. parameterName=value)
var parameterName = parameterName + "=";
if ( queryString.length > 0 ) {
// Find the beginning of the string
begin = queryString.indexOf ( parameterName );
// If the parameter name is not found, skip it, otherwise return the value
if ( begin != -1 ) {
// Add the length (integer) to the beginning
begin += parameterName.length;
// Multiple parameters are separated by the "&" sign
end = queryString.indexOf ( "&" , begin );
if ( end == -1 ) {
end = queryString.length
}
// Return the string
return queryString.substring( begin, end );


}
// Return "null" if no parameter has been found
return "null";
}
}

function SetCookie(name, value, expires) {
 var expString = ((expires == 0) ? "" : ("; expires =" + expires.toGMTString()));
  document.cookie = name + "=" + (value == 0 ? "" : escape(value)) +";path=/"+expString;
}

function ClearCookie(name) {
 var expDate = new Date();
 SetCookie(name, 0, 0);
}


function isNetscape()
{
  return ((document.layers) ? true : false);
}

function getBase()
{
    if (isNetscape()) {
	return "";
    } else {
	var baseObj = document.all.tags('BASE');
	return ((baseObj && baseObj.length) ? baseObj[0].href : "");
    }
}


//
// openFaqPage()
//
//   This function will open a new window with the FAQ page.
//
function openFaqPage()
{
    window.open((getPath() + "/faq.html"), 'faq', '');
}

//
// openAboutPage()
//
//   This function will open a new window with the "About Harland" page.
//
function openAboutPage()
{
    window.open((getBase() + "about_harland.html"), 'about', '');
}

//
// openOtherProducts()
//
//   This function will open a new window with the Other Products page.
//
function openOtherProducts()
{
    window.open((getPath() + "/otherproducts?OpenPage"), 'otherproducts', 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,resizable=yes,width=650,height=600');
}

//
// openOtherProductsLabels()
//
//   This function will open a new window with the Other Products page for labels.
//
function openOtherProductsLabels()
{
    window.open((getPath() + "/otherproductslabel?OpenPage"), 'otherproductslabels', 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,resizable=yes,width=815,height=600');
}


//
// showProducts()
//
//   This function will be used in the software vendor pages to
//   redirect the customer to a page that shows Harland compatible
//   products for the combination software/printer selected by the
//   user.
//
//   Added prodGroup to allow for checks vs forms product group - Jeb 9/2002
function showProducts(softwareSelect,
		      printerSelect,
		      errorMsg,
			 prodGroup)
{
    var i = softwareSelect.selectedIndex;
    var j = printerSelect.selectedIndex;

    if ( i >=0 && j >= 0) {
	var productQuery= new String(prodGroup + ":" + softwareSelect.options[i].value + ":"+ printerSelect.options[j].value );
	//setcookie to remember the software product the user selected
	   SetCookie("SoftwareType",softwareSelect.options[i].value,expiry);
	   SetCookie("PrinterType",printerSelect.options[j].value,expiry);
        document.location = getBase() +"productview.dsp?OpenForm&ProductGroup="+productQuery;
    } else {
        alert(errorMsg);
    }
}


function getPath() {
//this function gets the path that the database belongs to.
	var pthname = location.pathname;
	pthLength = pthname.length;
	nsfLocal  = pthname.indexOf(".nsf") + 4;
	return pthname.substring(0,nsfLocal);
};

//end getPath

function getSecureURL() {
// this function gets the Secure Connection Url unless the host name is localhost.
// If localhost I'm testing and may not be online.--Greg Scott
// I changed this to always connect to the secure connection -- ed

var curl = location.hostname;
var surl = document.forms[0].SecureURL.value;

if (curl.indexOf("localhost") != -1) {
 	return getPath();
     } else {
	   return surl;
	   }
};

function openCart () {
//this function gets the cart id and passes it to the function to open the cart.
var dbPath = getPath();
cartId = "&CartID=" +getCookie("CartID");
location= dbPath +"/Cart?OpenForm"+cartId;
}; //end openCart

function addToCart (itemID) {
//this function will add the selected item to the user's shopping cart.
//the shoppin cart id is now a cookie value so that anyone can shop anonymously
//******************************************************************
cartId = "&CartID=" +getCookie("CartID");
dbPath = getPath();
var Qstring = cartId+itemID+"&RefID="+dbPath;
location=dbPath+"/(webAddtoCartPers)?OpenAgent"+Qstring;
}; // end addToCart

function initializepage() {
   //Look for CartID in cookie first
   var cookies=document.cookie;
   cartID = getcartid("cartid", cookies, ";");
   //If cookies aren't enabled, first determine if customer is coming from an external site.  If so, a new
   //CartID must be generated for them.  If they are changing pages within Liberty Fund, simply get the
   //CartID from the URL
   if (cartID==null || cartID==0 || cartID=="") {
     // if (document.referrer.substring (0, 30).toLowerCase() !=document.forms[0].Server_Name.value) {
         cartID=randomnum();
         /*  }
      else {
         var URLcartid = new String(document.URL);
         cartID=getcartid("cartid", URLcartid, "&");
        } */
    }
    //Append CartID to all links on the current page, regardless of whether cookies are enabled or not
//   setlinks(cartID);     12/26/200 changed by greg
		SetCookie("CartID",cartID,0);

 }
function getcartid(name, inputstring, trunc) {
        //Simply parses out CartID from either the cookie or URL passed to function
        inputstring = inputstring + trunc;
        inputstring = inputstring.toLowerCase();
        var start=inputstring.indexOf(name + "=");
        if (start>-1) {
             start=inputstring.indexOf("=", start)+1
           }
        var end = inputstring.indexOf(trunc, start);
        if (start==-1 || end==-1) {
              value=null
           }
        else {
              var value=unescape(inputstring.substring(start,end))
           }
        return value;
 };
  function showFont()
{
    winFont = window.open((getPath() + "/Font?OpenPage"), 'typestyle', 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,resizable=yes,width=500,height=600');
	winFont.focus();
}

  function showTaxParts()
{
// what is the otherproductslabel parameter?? - Jeb 9/17/02
    winTax = window.open((getPath() + "/taxparts.html?OpenPage"), 'taxparts', 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,resizable=yes,width=600,height=600');
	winTax.focus();
}

 function randomnum() {
      var TodaysDate=new Date();
      var rn = Math.floor(16000*Math.random()+1)+"-"+TodaysDate.getHours()+TodaysDate.getMinutes()+TodaysDate.getSeconds();
      return rn;
 };
 initializepage()

//
// isAnySelected()
//
//   This function takes as a parameter a referece to a radio button
//   group and returns true if one of its buttons has been selected.
//
function isAnySelected(rb)
{
    return (getRBSelected(rb) != null);
}

//
// getRBSelected()
//
function getRBSelected(rb)
{
    if(rb)
    {
	    if (rb.length > 0) {
		for (var i = 0; i < rb.length; ++i) {
	    		if (rb[i].checked)
			   return rb[i].value;
		}
    	    }
     }
     else
    	    return rb.value;
}
//getRBSelectedIndex
function getRBSelectedIndex(rb)
{
    if (rb.length > 1) {
	for (var i = 0; i < rb.length; ++i) {
	    if (rb[i].checked)
		return i;
	}
    } else {
	return 0;
    }
    return null;
}

function validatePhone(phone)
{
	// phone number should be in the following format (123) 456-7890
	test= /[(]\d{3}[)]\s\d{3}-\d{4}/;
	if (!phone.match(test))
	{
		alert('Please enter the phone number in the format shown:\n(123) 555-5432');
		return false;
	}
	return true;
}

/*********************************************************
Set of JavaScript functions used for validation

JavaScript Validation 2.0, 19/Mar/2001
Jake Howlett, http://www.codestore.org/

Updated on 12/Mar/2002 to allow periods (.) as date-separators
**********************************************************/
/***********************************************************
validateLength()
This function checks that the value of a field is a number
and, optionally within a certain range.
Arguments:
val = Value to be checked
reqLen = Optional string length must equal this value
************************************************************/

function validateLength(val,reqLen,notUsed){
	if ( val =="" ) return false;
	if ( reqLen && val.length != reqLen ) return false;
	return true;
}

/***********************************************************
validateNumber()
This function checks that the value of a field is a number
and, optionally within a certain range.
Arguments:
val = Value to be checked
min = Optional minimum allowed value
max = Optional maximum allowed value
************************************************************/

function validateNumber(val, min, max){
	if ( isNaN( val ) ) return false;
	if ( min && val < min ) return false;
	if ( max && val > max ) return false;
	return true;
}


/***********************************************************
dateComponents()
This function splits a date in to the day, month and year
components, depending on the format supplied. Used by Date
Validation routine.
Arguments:
obj = Input whose value is to be checked
format = date format, ie mm/dd or dd/mm
************************************************************/

function dateComponents(dateStr, format) {
	var results = new Array();
	var datePat = /^(\d{1,2})(\/|-|\.)(\d{1,2})\2(\d{2}|\d{4})$/;
	var matchArray = dateStr.match(datePat);

	if (matchArray == null) {
		return null;
	}
	//check for two digit (20th century) years and prepend 19.
	matchArray[4] = (matchArray[4].length == 2) ? '19' + matchArray[4] : matchArray[4];

	// parse date into variables
	if (format.charAt(0)=="d"){ //what format does the server use for dates?
		results[0] = matchArray[1];
		results[1] = matchArray[3];
	} else {
		results[1] = matchArray[1];
		results[0] = matchArray[3]; }
	results[2] = matchArray[4];
	return results;
}


/***********************************************************
valiDate()
This function checks that the value of a date is in the
correct format and, optionally, within a certain range.
Arguments:
obj = Input whose value is to be checked
min = Optional minimum allowed value
max = Optional maximum allowed value
format = date format, ie mm/dd or dd/mm
************************************************************/

function valiDate(obj, min, max, format){

	dateBits = dateComponents(obj.value, format);
	if (dateBits == null) return false;

//Check it is a valid date first
	day = dateBits[0];
	month = dateBits[1];
	year = dateBits[2];

	if ((month < 1 || month > 12) || (day < 1 || day > 31)) { // check month range
		return false;
	}
	if ((month==4 || month==6 || month==9 || month==11) && day==31) {
		return false;
	}
	if (month == 2) {
	// check for february 29th
		var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
		if (day>29 || (day==29 && !isleap)) {
			return false;
		}
	}

//Now check whether a range is specified and if in bounds
	var theDate = new Date(dateBits[2], parseInt(dateBits[1]) - 1, dateBits[0]);

	if ( min ) {
		minBits = dateComponents (min, format);
		var minDate = new Date(minBits[2], parseInt(minBits[1]) - 1, minBits[0]);
		if ( minDate.getTime() > theDate.getTime() ) return false;
	}
	if ( max) {
		maxBits = dateComponents (max, format);
		var maxDate = new Date(maxBits[2], parseInt(maxBits[1]) - 1, maxBits[0]);
		if ( theDate.getTime() > maxDate.getTime() ) return false;
	}
	return true;
}


/***********************************************************
validateEmail()
This function checks that the value of a field is a valid
SMTP e-mail address ie x@xx.xx
Arguments:
obj = Input whose value is to be checked

Original source:
http://javascript.internet.com
Author:
Sandeep V. Tamhankar (stamhankar@hotmail.com)

Note: Work in progress = validate SMTP OR Notes Canonical
************************************************************/

function validateEmail( obj ) {
	var emailStr = obj.value;
	var reg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid
	var reg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/; // valid
	if ( !reg1.test( emailStr ) && reg2.test( emailStr ) ) {
		return true;
	} else {
	 	return false;
	}
}


/***********************************************************
locateFileUpload()
Returns a handle to the file upload control on a form.
Used to get around the fact that there is no consistent
way to refer to the element cross-browser.
***********************************************************/
function locateFileUpload( f ) {
 for(var i = 0; i < f.elements.length; i ++)
  if( f.elements[i].type=='file' ){
  return f.elements[i];
 }
}


/***********************************************************
validateFileType()
This function checks that the type of file being uploaded
is allowed
Arguments:
obj = The File Upload control.
fTyp = Allowed file types
************************************************************/

function validateFileType( obj, fTyp ) {

dots = obj.value.split(".");
fType = "." + dots[dots.length-1];

if ( fTyp != null && fTyp.indexOf(fType) == -1 ) return false;

return true;
}


/***********************************************************
validateFileLimit()
This function checks that the value in a file upload
Arguments:
obj = The File Upload control
cur = Current number of file attachments
max = Limit on allowed files
************************************************************/

function validateFileLimit( obj, cur, max ) {

if ( cur >= max ) return false;

return true;
}


/***********************************************************
OnFailure()
This function returns the failure message to the user and
sets focus on the input in question.
Arguments:
obj = Input element on which to return focus
lbl = Field Label to prepend on to the message
msg = Array value for message to give the user
************************************************************/

function OnFailure( obj, lbl, msg ){
	var msgs = new Array();
	msgs["text"] = " is a required field. \n\nPlease enter a value.";
	msgs["textarea"] = " is a required field. \n\nPlease enter a value.";
	msgs["select-one"] = " is a required field. \n\nPlease select an entry.";
	msgs["select-multiple"] = " is a required field. \n\nPlease select an entry.";
	msgs["checkbox"] = " is a required field. \n\nPlease select an entry.";
	msgs["file"] = " is a required upload. \n\nPlease select a file.";
	msgs["fileType"] = " requires certain file types. \n\nPlease select a valid file type.";
	msgs["fileLimit"] = " is a limited file upload. \n\nPlease reduce number of attachment(s) first.";
	msgs["radio"] = " is a required field. \n\nPlease select an entry.";
	msgs["number"] = " is a numeric field. \n\nPlease enter a valid number.";
	msgs["date"] = " is a date field. \n\nPlease enter a valid date.";
	msgs["email"] = " is an email address field. \n\nPlease enter a valid e-mail address.";

	if (msg[0]=="validlength")
			alert(lbl + " must be " + msg[1] + " digits long.");
  else	if(msg[1]	|| msg[2])
	 { //upper/lower bound ranges have been specified
		if(msg[1]	&& msg[2]){//range
			term = ( msg[0] == "date" )? " ("+msg[3]+")" : "";
			alert(lbl + msgs[msg[0]] + term + " between " + msg[1] + " and " + msg[2]);
		} else if (msg[1]) {//lower bound
			term = ( msg[0] == "number" ) ? " greater than " : " (" + msg[3] + ") after ";
			alert(lbl + msgs[msg[0]] + term + msg[1]);
		} else {//upper bound
			term = ( msg[0] == "number" )? " less than " : " (" + msg[3] + ") before ";
			alert(lbl + msgs[msg[0]] + term + msg[2]);
		}
	} else {//no range given
		alert(lbl + msgs[msg[0]]);
	}

	obj.focus();
	return false;
}


/***********************************************************
isSomethingSelected()
This function is passed an object of type redio group or check
box. It then loops through all options and checks that
one of them is selected, returning true if so.
Arguments:
obj = Reference to the parent object of the group.
************************************************************/

function isSomethingSelected( obj ){
	for (var r=0; r < obj.length; r++){
		if ( obj[r].checked ) return true;
	}
}


/***********************************************************
validateRequiredFields()
This function is passed an array of fields that are required
to be filled in and iterates through each ensuring they have
been correctly entered.
************************************************************/

function validateRequiredFields( f, a ){

	for (var i=0; i < a.length; i++){
		e = a[i][0];

			//checks input types: "text","select-one","select-multiple","textarea","checkbox","radio","file"

				switch (e.type) {
					case "text":
							if ( trim(e.value) == "" ) return OnFailure(e, a[i][1], ["text"]);
							if ( a[i][2] ) {
								switch ( a[i][2][0] ){
									case "number":
										if ( !validateNumber(e.value, a[i][2][1], a[i][2][2]) ) return OnFailure(e, a[i][1], ["number", a[i][2][1], a[i][2][2]]);
										break
									case "date":
										if ( !valiDate(e, a[i][2][1], a[i][2][2], a[i][2][3]) ) return OnFailure(e, a[i][1], ["date", a[i][2][1], a[i][2][2], a[i][2][3]]);
										break
									case "email":
										if ( !validateEmail(e) ) return OnFailure(e, a[i][1], ["email"]);
										break
									case "validlength":
										if ( !validateLength(e.value, a[i][2][1], a[i][2][2]) ) return OnFailure(e, a[i][1], ["validlength", a[i][2][1], a[i][2][2]]);
										break
									default:
										break
								}
							}
						break
					case "file":
					//make sure AT LEAST one file gets attached
					if ( a[i][2][1] == 0 && trim(e.value) == "" ) return OnFailure(e, a[i][1], ["file"]);
					if ( trim(e.value) != "") {
						//check type of file that is being uploaded
						if ( a[i][2][0] != null && validateFileType( e, a[i][2][0] ) == false ) return OnFailure(e, a[i][1], ["fileType"]);
						//check that file limit has not been reached
						if ( a[i][2][2] != null && validateFileLimit( e, a[i][2][1], a[i][2][2] ) == false ) return OnFailure(e, a[i][1], ["fileLimit"]);
					}
						break
					case "textarea":
					if ( trim(e.value) == "" ) return OnFailure(e, a[i][1], ["textarea"]);
						break
					case "select-one":
					if ( e.selectedIndex == 0 ) return OnFailure(e, a[i][1], ["select-one"]);
						break
					case "select-multiple":
					if (e.selectedIndex == -1) return OnFailure(e, a[i][1], ["select-multiple"]);
						break

					default:
						//must be a checkbox or a radio group if none of above

 						if ( !e[0]) {//handle single item group first
							switch (e.type) {
							case "checkbox":
								if ( !e.checked )  return OnFailure(e, a[i][1], ["checkbox"]);
								break
							case "radio":
								if ( !e.checked )  return OnFailure(e, a[i][1], ["radio"]);
								break
							default:
									break
							}
						} else { //handle multi-item groups
							switch (e[0].type) {
							case "checkbox":
								if ( !isSomethingSelected( e ) )  return OnFailure(e[0], a[i][1], ["checkbox"]);
								break
							case "radio":
								if ( !isSomethingSelected( e ) )  return OnFailure(e[0], a[i][1], ["radio"]);
								break
							default:
									break
							}
						}
						break
				}
	}
	return true;
}

