/*
'       APP Name:  dbzap
'        Version:  2.0
'         Module:  form.js
'     Created By:  Gunnit S. Khurana
'  Last Modified:  May 23, 2011
'      Copyright:  2000-2003 Cyzap Inc, Inc.
'-----------------------------------------------------------------*/

if( !Array.prototype.indexOf ) {
	Array.prototype.indexOf = function( searchElement /*, fromIndex*/ ) {
		"use strict";

		if( this === void 0 || this === null ) {
			throw new TypeError();
		}

		var t = Object(this);
		var len = t.length >>> 0;
		if( len === 0 ) {
			return -1;
		}

		var n = 0;
		if( arguments.length > 0 ) {
			n = Number(arguments[1]);
			if( n !== n) { // shortcut for verifying if it's NaN
				n = 0;
			}
			else if( n !== 0 && n !== (1 / 0) && n !== -(1 / 0) ) {
				n = (n > 0 || -1) * Math.floor(Math.abs(n));
			}
		}

		if( n >= len ) {
			return -1;
		}

		var k = n >= 0
			? n
			: Math.max(len - Math.abs(n), 0);

		for( ; k < len; k++ ) {
			if( k in t && t[k] === searchElement ) {
				return k;
			}
		}

		return -1;
	};
}

if( !Array.prototype.lastIndexOf ) {
	Array.prototype.lastIndexOf = function( searchElement /*, fromIndex*/ ) {
		"use strict";

		if( this === void 0 || this === null ) {
			throw new TypeError();
		}

		var t = Object(this);
		var len = t.length >>> 0;
		if( len === 0 ) {
			return -1;
		}

		var n = len;
		if( arguments.length > 1 ) {
			n = Number(arguments[1]);
			if( n !== n ) {
				n = 0;
			}
			else if( n !== 0 && n !== (1 / 0) && n !== -(1 / 0) ) {
				n = (n > 0 || -1) * Math.floor(Math.abs(n));
			}
		}

		var k = n >= 0
			? Math.min(n, len - 1)
			: len - Math.abs(n);

		for( ; k >= 0; k-- ) {
			if( k in t && t[k] === searchElement ) {
				return k;
			}
		}

		return -1;
	};
}

function Info(obj)
 {
 var r = '\n';
 var numLoops = 0;
 var theObject = obj;
 var msg = "*** Properties " + " ***" + r + r; 
  

     for (var i in theObject)
     {   
         msg += i + " =  " + eval("theObject."  + i) + r;  
         numLoops++;
         if (numLoops % 20 == 0) {
           alert(msg);
           msg = "";
         }
     }
  
     msg += r + "Number of Properties= " + numLoops;
     alert(msg);
//     d.value = msg;
}

var TF_Chars_AlphaUpper="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var TF_Chars_AlphaLower="abcdefghijklmnopqrstuvwxyz";
var TF_Chars_Alpha=TF_Chars_AlphaUpper + TF_Chars_AlphaLower;
var TF_Chars_Digits="0123456789";
var TF_Chars_Name=TF_Chars_Alpha + TF_Chars_Digits + "-";



   function TF_getFrameContentWindow(frameID, frameName)
   {
  
  // to set iframe
    var objFrameID = document.getElementById(frameID);
      cwFrame = null;
      //set up a reference to the window object of the iframe
      if(window.frames && window.frames[frameName]) { //IE5, Konq, Safari
         cwFrame = window.frames[frameName];
      }
      else if(objFrameID.contentWindow) { //IE5.5+, Moz 1.0+, Opera
         cwFrame = objFrameID.contentWindow;
      }
      else { //Moz < 0.9 (Netscape 6.0)
         cwFrame = objFrameID;
      }
      return cwFrame;
   }



function TF_Trim(s,removeQuote)
{ 
  // removes leading and trailing spaces, and returns the shortened string
  // if removeQuote == true then remove double-quote as well

  if (removeQuote == null) removeQuote=true;

  var i = 0;
  var j = 0;

  for (i=0; i<s.length; i++) {
    if (s.charAt(i) != " ") {
       for (j=s.length - 1; j > i; j--) {
         if (s.charAt(j) != " ")
           break;
       }
       break;
    }
  }
  if (i > j)
    i = j;
  if (s.length > 0 && s.charAt(j) != " ")
    j++;
  var s = s.substring(i, j);
  var s2 = '';
  if (removeQuote) {
    for (i=0; i<s.length; i++) {
      if (s.charAt(i) != "\"") s2 = s2 + s.charAt(i);
    }
    s = s2;
  }
  return s;
}

var lastTrimControlName = ''; // To remember the last control that used the trim functions

function TF_TrimField(ctl)
{
  if (lastTrimControlName == ctl.name) return;
  ctl.value = TF_Trim(ctl.value);
  lastTrimControlName = ctl.name;
}

function TF_TrimField_LeaveQuotes(ctl)
{
  if (lastTrimControlName == ctl.name) return;
  ctl.value = TF_Trim(ctl.value,false);
  lastTrimControlName = ctl.name;
}


function CheckParentVisibility(fldname)
{
	if( typeof jQuery === 'function' && typeof jQuery.fn.dzLib === 'function' ) {
		jQuery(fldname).dzLib( 'fieldShowTab' );
	}

	var parent = fldname.parentElement;
	if(!parent)
		return;
         
        do
        {
             while(parent.id == "")
             {
                  parent = parent.parentElement;
                  if(!parent)
                     break;
              
             }
             if(parent)
             {
                 //check is part of tabber control - gsk
								 if (parent.id.substr(0,10) == 'tabbertab_') {
									 var tabber = parent.parentElement.tabber;  									   
									 for (var i=0; i < tabber.tabs.length; i++) {
										 if (tabber.tabs[i].div.id == parent.id) break;
									 }
									 if (i < tabber.tabs.length) parent.parentElement.tabber.tabShow(i);									     
								 }

                 //check if part of show hide div - joey
                 if(parent.style.visibility == 'hidden')
                 	parent.style.visibility = 'visible';
                 if(parent.style.display == 'none')
                 	parent.style.display = 'block';
                 parent = parent.parentElement;
             }
         } while(parent);
}


/**
 * @param {DOMElement} el An element that exists in the current window's DOM
 * @param {Boolean} partial If true, the function will return true if the element is partially in view,
 *   otherwise only if it is fully within view
 * @returns true if the element is in view, otherwise false
 */
function TF_IsElementInViewport( el, partial ) {
	var isInView;
	var top = el.offsetTop;
	var left = el.offsetLeft;
	var width = el.offsetWidth;
	var height = el.offsetHeight;

	while( el.offsetParent ) {
		el = el.offsetParent;
		top += el.offsetTop;
		left += el.offsetLeft;
	}

	if( partial ) {
		isInView = top < (window.pageYOffset + window.innerHeight) &&
			left < (window.pageXOffset + window.innerWidth) &&
			(top + height) > window.pageYOffset &&
			(left + width) > window.pageXOffset;
	}
	else {
		isInView = top >= window.pageYOffset &&
			left >= window.pageXOffset &&
			(top + height) <= (window.pageYOffset + window.innerHeight) &&
			(left + width) <= (window.pageXOffset + window.innerWidth);
	}
	
	return isInView;
}


/**
 * @method
 * @param {HTMLFormElement} objform The HTML form containing the field
 * @param {String} fldobjectname The name of the HTML field element
 * @param {String} fldcaption The caption for the field used in the UI
 * @param {Object} config A configuration object containing additional parameters
 *
 * config properties:
 * [for text and password fields]
 * required {Boolean} True if the field must have a non-empty value
 * minlen {Number} The minimum number of characters allowed
 * maxlen {Number} The maximum number of characters allowed
 * validascii {Boolean} Enforce only ASCII characters
 * validemail {Boolean} Enforce e-mail address format
 * validnum {Boolean} Enforce a valid number (no grouping separators, like comma, allowed)
 *   REQUIRES:
 *   decimalchar {String} Character used to indicate the decimal separator in a number (e.g. '.' in 5.6)
 *   maxdecimals {Number} The maximum number of values allowed after the decimal point
 * validdigits {Boolean} Enforce valid digits
 *   REQUIRES:
 *   separatorchars {String} Characters (multiple chars may be specified) used to separate groups in a number (e.g. '-' in 555-666-8888)
 *   mindigits {String} The minimum number of digits required
 *   maxdigits {String} The maximum number of digits allowed
 *   numtype {String} A descriptive word for the type of number (e.g. "Phone Number", "ZIP Code")
 * validdate {Boolean} Enforce a valid date
 *   OPTIONAL:
 *   (if mindate and maxdate are specified, 'validdate' is implied and can be omitted)
 *   mindate {String} A string representing a minimum acceptable date value
 *   maxdate {String} A string representing a maximum acceptable date value
 *
 * [for radio, checkbox, and select fields]
 * minselected {Number} The minimum number of options to select (only applicable to a multi-select field, default=1)
 * maxselected {Number} The maximum number of options to select (only applicable to a multi-select field, default=0 [unlimited])
 *
 * [for custom checkbox groups]
 * checkboxcount {Number} The number of fields in the checkbox group
 * (fldobjectname will be treated as the field name prefix)
 *
 * [for select fields]
 * disallowfirstoption {Boolean} Disallow the selection of the first option in a select field (default=false)
 *
 * [for hidden fields]
 * Hidden fields only support basic validation - does it have a value?  No config object is necessary (it will be ignored)
 *
 * Examples:
 * TF_ValidateField( document.forms[0], "FirstName", "First Name", { maxlen: 40 } )
 * TF_ValidateField( document.forms[0], "Email", "E-mail Address", { validemail: true } )
 * TF_ValidateField( document.forms[0], "Age", "Age", { validnum: true, groupchar: ',', decimalchar: '.', maxdecimals: 0 } )
 * TF_ValidateField( document.forms[0], "PostalCode", "ZIP/Postal Code", {
 *     validdigits: true,
 *     separatorchars: ' -',
 *     mindigits: 5,
 *     maxdigits: 9,
 *     numtype: 'ZIP/Postal Code'
 * } )
 */
function TF_ValidateField( objform, fldobjectname, fldcaption, config )
{
	/***********
	 * NOTICE:  any updates should be mirrored in P_VALIDATE_FIELD in CSSNET\dzApps\Subs\Data\ControlsDefinition.sub
	 ***********/
	if( (typeof objform) === 'undefined' )
	{
		alert( 'ERROR: TF_ValidateField:  objform is undefined.' );
		return false;
	}

	if( !config ) {
		return true;
	}

	if( config.required && config.required === false ) {
		return true;
	}
	
	var field = objform[fldobjectname];
	
	if( !field ) {
		// if the named field does not exist, but the config.checkboxcount option is set, then it's a custom checkbox group
		if( config.checkboxcount !== undefined ) {
			if( !TF_ValidateCustomCheckbox( objform, fldobjectname, config.checkboxcount, fldcaption, config.minselected, config.maxselected ) ) {
				return false;
			}
			
			return true;
		}

		if( (typeof console) !== 'undefined' ) {
			console.log( 'TF_ValidateField:  field "' + fldobjectname + '" does not exist on form "' + objform.name + '" (returning true)' );
		}
		return true;
	}
	
	if( fldcaption === undefined || fldcaption === '' ) {
		fldcaption = fldobjectname;
	}

	if( field.length > 1 && field.tagName !== 'SELECT' ) {
		switch( field[0].type )
		{
			case 'radio':
				if( !TF_RequiredOK_RadioCheckBox( field, fldcaption, 1, 1 ) ) {
					return false;
				}
				
				return true;

			case 'checkbox':
				if( !TF_RequiredOK_RadioCheckBox( field, fldcaption,
					config.minselected === undefined ? 1 : config.minselected,
					config.maxselected === undefined ? 0 : config.maxselected )
					) {
					return false;
				}
				
				return true;

			default:
				alert( 'Field validation error: there are multiple fields named "' + fldobjectname + '".' );
				return false;
		}
	}
	
	switch( field.type )
	{
		// normal validation methods call field.focus() - this throws an error on hidden fields
		case 'hidden':
			if( config.required !== undefined && config.required ) {
				if( field.value === '' ) {
					alert( 'WARNING: The hidden field "' + fldcaption + '" is empty - please contact support.' );
					return false;
				}
			}
			return true;

		case 'password':
		case 'text':
			if( config.required !== undefined && config.required ) {
				if( !TF_RequiredOK( field, fldcaption ) ) {
					return false;
				}
			}
			
			if( config.minlen !== undefined && config.minlen > 0 ) {
				if( !TF_MinLengthOK( field, fldcaption, config.minlen ) ) {
					return false;
				}
			}
			
			if( config.maxlen !== undefined && config.maxlen > 0 ) {
				if( !TF_MaxLengthOK( field, fldcaption, config.maxlen ) ) {
					return false;
				}
			}
			
			if( config.validdate !== undefined && config.validdate ) {
				if( !TF_ValidateDate( field, fldcaption ) ) {
					return false;
				}
			}
			
			if( config.mindate !== undefined || config.maxdate !== undefined ) {
				if( !TF_ValidateDate( field, fldcaption ) ) {
					return false;
				}
				
				if( !TF_ValidateDateRange( field, config.mindate, config.maxdate, fldcaption ) ) {
					return false;
				}
			}
			
			if( config.validascii !== undefined && config.validascii ) {
				if( !TF_ValidASCII( field, fldcaption ) ) {
					return false;
				}
			}
			
			if( config.validemail !== undefined && config.validemail ) {
				if( !TF_ValidEmail( field, fldcaption ) ) {
					return false;
				}
			}
			
			if( config.validnum !== undefined && config.validnum ) {
				if( !TF_ValidateNumber( field, fldcaption, config.decimalchar, config.maxdecimals ) ) {
					return false;
				}
			}
			
			if( config.validdigits !== undefined && config.validdigits ) {
				if( !TF_ValidDigits( field, fldcaption, config.separatorchars, config.mindigits, config.maxdigits, config.numtype ) ) {
					return false;
				}
			}
			
			return true;

		case 'select-multiple':
			if( !TF_RequiredOK_SelectList( field, fldcaption,
				config.minselected === undefined ? 1 : config.minselected,
				config.maxselected === undefined ? 0 : config.maxselected,
				config.disallowfirstoption === undefined ? false : config.disallowfirstoption )
				) {
				return false;
			}
			
			return true;
		case 'select-one':
			if( !TF_RequiredOK_SelectList( field, fldcaption, 1, 1,
				config.disallowfirstoption === undefined ? false : config.disallowfirstoption )
				) {
				return false;
			}
			
			return true;

		default:
			return true;
	}
}

function TF_RequiredOK(fld,fldname)
{
    if (fld.value == "")
    {
    	  alert("Please enter a value for the \"" + fldname + "\" field.");	  
    	  CheckParentVisibility(fld);
    	  fld.focus();
	  return (false);
    }
    return (true);
}

function TF_MinLengthOK(fld,fldname,len){
    if (fld.value.length < len){
      alert("Please enter at least " + len + " characters in the \"" + fldname + "\" field.");
      CheckParentVisibility(fld);
      fld.focus();
      return (false);
    }
    return (true);
}

function TF_MaxLengthOK(fld,fldname,len){
    if (fld.value.length > len){
      alert("Please enter at most " + len + " characters in the \"" + fldname + "\" field.");
      CheckParentVisibility(fld);
      fld.focus();
      return (false);
    }
    return (true);
}


function TF_ValidASCII(fld,fldname)
{
  var checkStr = fld.value;
  var i; 

  for (i=0; i<checkStr.length; i++) {
    if ((checkStr.charAt(i) < " ") || (checkStr.charAt(i) > "~")) {
      alert("Please enter only ASCII characters in the \"" + fldname + "\" field.");
      CheckParentVisibility(fld);
      fld.focus();
      return false;
    }
  }
  return true;
}

function TF_ValidChars(fld,fldname,validchars,chartext){
    var checkOK = validchars;
    var checkStr = fld.value;
    var allValid = true;
    for (i = 0;  i < checkStr.length;  i++){
      ch = checkStr.charAt(i);
      if (checkOK.indexOf(ch) == -1){
        allValid = false;
        break;
      }
    }
    if (!allValid){
     alert("Please enter only " + chartext + " characters in the \"" + fldname + "\" field.");
     CheckParentVisibility(fld);
     fld.focus();
     return (false);
    }
    return (true);
}

function TF_InvalidChars(fld,fldname,invalidchars){
    var checkStr = fld.value;
    var allValid = true;
    for (i = 0;  i < checkStr.length;  i++){
      ch = checkStr.charAt(i);
      if ((ch < " ") || (ch.charAt(i) > "~") || (invalidchars.indexOf(ch) != -1))
      {
        alert("You have entered an invalid character (\"" + ch + "\") in the \"" + fldname + "\" field.");
        CheckParentVisibility(fld);
        fld.focus();
        return false;
      }
    }
    return (true);
}

function TF_ValidEmail(fld,fldname){

   if (fld.value == "") return (true);
   if (!TF_InvalidChars(fld,fldname,"\"|&;<>!*\\")) return(false);
   if ((fld.value.indexOf('@', 0) == -1) || (fld.value.indexOf('.', 0) == -1)){
     alert("Please enter a valid Internet email address (e.g. abc@xyz.com) in the \"" + fldname + "\" field.");
     CheckParentVisibility(fld);
     fld.focus();
     return (false);
    }
   if (fld.value.indexOf(' ', 0) != -1){
     alert("Sorry, no blank space is allowed in the \"" + fldname + "\" field.");
     CheckParentVisibility(fld);
     fld.focus();
     return (false);
   }
   if (window.RegExp) {
    var reg1str = "(@.*@)|(\\.\\.)|(@\\.)|(\\.@)|(^\\.)";
    var reg2str = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
    
    var email = fld.value;
    var reg1 = new RegExp (reg1str);
    var reg2 = new RegExp (reg2str);
    if (reg1.test(email) || !reg2.test(email)) {
      alert("The \"" + fldname + "\" field does not appear to be a valid email address. Please check it again.");
      return false;
    }
   }
   return (true);
}

/**
 * @param {HTMLInputElement} fld The field to validate
 * @param {String} fldname The caption for the field in the UI
 * @param {String} decimalchar A single character specifying the decimal point
 * @param {Number} maxdecimals The maximum number of digits allowed after the decimal point
 */
function TF_ValidateNumber( fld, fldname, decimalchar, maxdecimals )
{
	var numtype = "number";
	
	if( maxdecimals === 0 ) {
		numtype = "integer";
	}
	
	if( fld.value.length === 0 ) {
		alert("Please enter a valid " + numtype + " in the \"" + fldname + "\" field.");
		return false;
	}
	
	var validChars = "0123456789" + decimalchar.charAt(0);
	var isDecimal = false;
	
	var currentchar = fld.value.charAt(0);
	if( validChars.indexOf( currentchar ) === -1 && currentchar !== '-' ) {
		alert("Please enter a valid " + numtype + " in the \"" + fldname + "\" field.");
		return false;
	}
	
	if( currentchar === decimalchar ) {
		isDecimal = true;
	}
	
	var decimalCount = 0;
	
	for( var i = 1; i < fld.value.length; i++ ) {
		currentchar = fld.value.charAt(i);
		
		if( validChars.indexOf( currentchar ) === -1 ) {
			alert("Please enter a valid " + numtype + " in the \"" + fldname + "\" field.");
			return false;
		}
		
		if( isDecimal ) {
			if( maxdecimals === 0 ) {
				alert("Please enter a valid " + numtype + " in the \"" + fldname + "\" field.");
				return false;
			}
			
			decimalCount++;
		}
		else if( currentchar === decimalchar ) {
			isDecimal = true;
		}
		
		if( decimalCount > maxdecimals ) {
			alert("Please enter no more than " + maxdecimals + " decimals in the \"" + fldname + "\" field.");
			return false;
		}
	}
	
	return true;
}

function TF_ValidNum(fld,fldname,groupchar,decimalchar,maxdecimals){

  var checkOK = "0123456789" + groupchar + decimalchar;
  var checkStr = fld.value;
  var allValid = true;
  var decPoints = 0;
  var allNum = "";
  var isDecimal = false;
  var numtype = "number";
  
  if (maxdecimals == 0) {
	numtype = "integer";
  }
  
  var ch = checkStr.charAt(0);
  if( checkOK.indexOf(ch) === -1 && ch !== '-' ) {
    alert("Please enter a valid " + numtype + " in the \"" + fldname + "\" field.");
    return ("Invalid");
  }
  
  if( ch !== groupchar ) {
	allNum += ch;
  }
  
  for (i = 1;  i < checkStr.length;  i++){
    ch = checkStr.charAt(i);
    if (checkOK.indexOf(ch) == -1){
        allValid = false;
        break;
    }
    if (ch != groupchar) allNum += ch;
	
	if (ch == decimalchar) {
		if (isDecimal) {
			alert("Please enter a valid " + numtype + " in the \"" + fldname + "\" field.");
			return ("Invalid");
		}
		else {
			isDecimal = true;
		}
	}
	else if (isDecimal && ch != groupchar) {
		decPoints++;
	}
  }

  if (!allValid){
    alert("Please enter only digit characters in the \"" + fldname + "\" field.");
    CheckParentVisibility(fld);
    fld.focus();
    return ("Invalid");
  }

  if (decPoints > maxdecimals){
    alert("Please enter a valid " + numtype + " in the \"" + fldname + "\" field.");
    CheckParentVisibility(fld);
    fld.focus();
    return ("Invalid");
  }
  return (allNum);
}

function TF_ValidDigits(fld,fldname,separatorchars,mindigits,maxdigits,numtype){

  var checkOK = "0123456789-" + separatorchars;
  var checkStr = fld.value;
  var allValid = true;
  var numDigits = 0;

  if (checkStr == "") return(true);
  for (i = 0;  i < checkStr.length;  i++){
    ch = checkStr.charAt(i);
    if (checkOK.indexOf(ch) == -1){
        allValid = false;
        break;
    }
    if (separatorchars.indexOf(ch) == -1) numDigits++;
  }

  if (!allValid){
    alert("Please enter a valid " + numtype + " in the \"" + fldname + "\" field.");
    CheckParentVisibility(fld);
    fld.focus();
    return (false);
  }

  if (mindigits > 0 && numDigits < mindigits){
    alert("Please enter at least " + mindigits + " digits in the \"" + fldname + "\" field.");
    CheckParentVisibility(fld);
    fld.focus();
    return (false);
  }

  if (maxdigits > 0 && numDigits > maxdigits){
    alert("Please enter at most " + maxdigits + " digits in the \"" + fldname + "\" field.");
    CheckParentVisibility(fld);
    fld.focus();
    return (false);
  }
  return (true);
}

/**
 * Check for min/max selected checkboxes in a custom checkbox group
 * (where each checkbox has a different name, but all sequentially numbered with the same prefix)
 *
 * @param {HTMLFormElement} objform The HTML form containing the fields
 * @param {String} fieldPrefix The common prefix used in all field names (e.g. "check" in "check1, check2, check3" OR "check_" in "check_1, check_2, check_3")
 * @param {Number} fieldCount The total number of fields (they must be sequentially numbered starting from 1)
 * @param {String} fieldCaption The field caption as displayed in the UI
 * @param {Number} minselected The minimum number of boxes that can be checked
 * @param {Number} maxselected The maximum number of boxes that can be checked
 */
function TF_ValidateCustomCheckbox( objform, fieldPrefix, fieldCount, fieldCaption, minselected, maxselected )
{
	var totalChecked = 0;

	for( var i = 1; i <= fieldCount; i++ )
	{
		if( objform[fieldPrefix + i] && objform[fieldPrefix + i].checked ) {
			totalChecked++;
		}
	}

	if( minselected && minselected > 0 ) {
		if( totalChecked < minselected ) {
			var msgText = minselected === 1 ? 'one' : 'at least ' + minselected;
			alert( 'Please select ' + msgText + ' of the ' + fieldCaption + ' options.' );
			return false;
		}
	}

	if( maxselected && maxselected > 0 ) {
		if( totalChecked > maxselected ) {
			var msgText = maxselected === 1 ? 'one' : 'at most ' + maxselected;
			alert( 'Please select ' + msgText + ' of the ' + fieldCaption + ' options.' );
			return false;
		}
	}

	return true;
}

function TF_SelectedOK(fld,fldname,numselected,minselected,maxselected){

  if (numselected < minselected){
    var msgText = "one";
    if (minselected > 1) msgText = "at least " + minselected;
    alert("Please select " + msgText + " of the \"" + fldname + "\" options.");
    return (false);
  }
  if (maxselected == 0) return(true);
  if (numselected > maxselected){
    var msgText = "one";
    if (maxselected > 1) msgText = "at most " + maxselected;
    alert("Please select " + msgText + " of the \"" + fldname + "\" options.");
    return (false);
  }
  return (true);
}

function TF_RequiredOK_RadioCheckBox(fld,fldname,minselected,maxselected){
  var numselected = 0;
  if (typeof fld.length == 'undefined'){
    if (fld.checked) numselected++;
  } else {
		for (i = 0;  i < fld.length;  i++){
			if (fld[i].checked) numselected++;
		}
  }		
  
  return (TF_SelectedOK(fld,fldname,numselected,minselected,maxselected));
}

// Returns number of options selected in list/combo box
function TF_GetNumSelected(fld){

  var numselected = 0;
  for (i = 0;  i < fld.length;  i++)
  {
    opt = fld.options[i];
    if (opt.selected && opt.value != "") numselected++;
  }
  return numselected;
}

//Checks for selection in the list/combo box
 
function TF_RequiredOK_SelectList(fld,fldname,minselected,maxselected,disallowfirstoption){
  if (fld.selectedIndex < 0){
    alert("Please select one of the \"" + fldname + "\" options.");
    CheckParentVisibility(fld);
    fld.focus();
    return (false);
  }

  if (disallowfirstoption) {
    if (fld.selectedIndex == 0){
      alert("Please enter a value for the \"" + fldname + "\" field.");
      CheckParentVisibility(fld);
      fld.focus();
      return (false);
    }
  }

  var numselected = 0;
  var startoption = 0;
  if (disallowfirstoption) startoption = 1;
  for (var i = startoption;  i < fld.options.length;  i++)
  {
    opt = fld.options[i];
    if (opt.selected){
      numselected++;
      if (opt.value == ""){
        alert("The \"" + fldname + "\" option: '" + opt.text + "' is not a valid selection.  Please choose one of the other options.");
        CheckParentVisibility(fld);
        fld.focus();
        return (false);
      }
    }
  }
  return (TF_SelectedOK(fld,fldname,numselected,minselected,maxselected));
}


function TF_ValidUSZip(fld,fldname){

  var separatorchars = "-";
  var checkOK = "0123456789" + separatorchars;
  var checkStr = fld.value;
  var allValid = true;
  var numDigits = 0;

  if (checkStr == "") return(true);
  for (i = 0;  i < checkStr.length;  i++){
    ch = checkStr.charAt(i);
    if (checkOK.indexOf(ch) == -1){
        allValid = false;
        break;
    }
    if (separatorchars.indexOf(ch) == -1) numDigits++;
  }

  if (!allValid){
    alert("Please enter a valid zip in the \"" + fldname + "\" field.");
    CheckParentVisibility(fld);
    fld.focus();
    return (false);
  }

  if (!(numDigits == 5 || numDigits == 9)){
    alert("You cannot have " + numDigits + " digits in the \"" + fldname + "\" field.\n\nPlease enter a valid Zip code.");
    CheckParentVisibility(fld);
    fld.focus();
    return (false);
  }
  return (true);
}

function TF_ValidCanadaZip(fld,fldname){
  var separatorchars = " ";
  var checkOK = TF_Chars_Alpha + TF_Chars_Digits + separatorchars;
  var checkStr = fld.value;
  var allValid = true;
  var numDigits = 0;

  if (checkStr == "") return(true);
  for (i = 0;  i < checkStr.length;  i++){
    ch = checkStr.charAt(i);
    if (checkOK.indexOf(ch) == -1){
        allValid = false;
        break;
    }
    if (separatorchars.indexOf(ch) == -1) numDigits++;
  }

  if (!allValid){
    alert("Please enter a valid Canadian Postal Code in the \"" + fldname + "\" field.");
    CheckParentVisibility(fld);
    fld.focus();
    return (false);
  }

  if (!(numDigits == 6)){
    alert("You cannot have " + numDigits + " characters in the \"" + fldname + "\" field.\n\nPlease enter a valid Canadian Postal Code.");
    CheckParentVisibility(fld);
    fld.focus();
    return (false);
  }
  return (true);
}


function TF_DeleteOption(selectList,optNum) {
    if (selectList.options.length == 0){
      alert('The list is empty.');
      return(false);
    }
    if (optNum == null) optNum = selectList.selectedIndex; 
    if (optNum == null || optNum < 0){
      alert('Please select the option to delete.');
      return(false);
    }
    selectList.options[optNum] = null;
}

function TF_AddOption(selectList,optText,optValue,defaultSelected,selected,unique) {
    var i;
    if (defaultSelected == null) defaultSelected = true;
    if (selected == null) selected = true;
    if (unique == null) unique = true;

    /* Unselect all the options so far */
    for (i=0;i<selectList.options.length;i++){
      selectList.options[i].selected = false;
    }

    if (unique) {
      for (i=0;i<selectList.options.length;i++){
        if (selectList.options[i].value == optValue){
          selectList.options[i].selected = true;
          return (false);
        }
      }
    }

    var optionName = new Option(optText, optValue, defaultSelected, selected)
    if (document.all || document.getElementById) {
      selectList.options.add(optionName,0);
    }
    if (document.layers) {
      for (i=selectList.options.length;i>0;i--)
        selectList.options[i] = selectList.options[i-1];
      selectList.options[0] = optionName;
      selectList.options[0].defaultSelected = defaultSelected;
      selectList.options[0].selected = selected;     
    }
    return(true);

}
//Adds http:before URL
function TF_FormatURL(fld){
  if (fld.value.length == 0) return;
  if (fld.value.substring(0,1) == "/") return;
  var protocol = fld.value.substring(0,3).toLowerCase();
  if (protocol == "htt" || protocol == "ftp" || protocol == "mai") return;
  fld.value = "http://" + fld.value;
  return true;
}

//Selects All the Options of a Multi-Select List Box
function TF_SelectAll(selectList){
 for (var i=0;i<selectList.options.length;i++)
    selectList.options[i].selected = true; 
}

function TF_GetRadioValue(radioList){
 for (var i=0;i<radioList.length;i++) {
   if (radioList[i].checked) {
     return (radioList[i].value);
     break;
   }
 }
}

function TF_GetSelectValue(selectList){
 for (var i=0;i<selectList.options.length;i++){
   if (selectList.options[i].selected) {
     return (selectList.options[i].value);
     break;     
   }
 }
}

function TF_GetSelectValue(selectList){
  var comma = "";
  var selOptionList = "";
  for (var i=0;i<selectList.options.length;i++){
   if (selectList.options[i].selected && selectList.options[i].value.length > 0) {
     selOptionList = selOptionList + comma + selectList.options[i].value;
     comma = ",";
   }
  }
  return (selOptionList);
}


function TF_GetSelectText(selectList){
  var comma = "";
  var selOptionList = "";
  for (var i=0;i<selectList.options.length;i++){
   if (selectList.options[i].selected && selectList.options[i].text.length > 0) {
     selOptionList = selOptionList + comma + selectList.options[i].text;
     comma = ",";
   }
  }
  return (selOptionList);
}



function TF_GetSelectedText(selectList){
  var comma = "";
  var selOptionList = "";
  for (var i=0;i<selectList.options.length;i++){
   if (selectList.options[i].selected) {
     selOptionList = selectList.options[i].text;
     comma = ",";
   }
  }
  return (selOptionList);
}


function TF_SetSelectValue(selectList,optValue){
 for (var i=0;i<selectList.options.length;i++){
   if (selectList.options[i].value == optValue) {
     selectList.selectedIndex = i;
     return i;
   }
 }
 return null;
}

var TF_Zoom_Field;
var TF_Zoom_Caption;
function TF_Zoom(e,zoomField,caption){
  TF_Zoom_Field = zoomField;
  TF_Zoom_Caption = caption;
  var winURL = '/dzapps/docs/popup/zoom.htm';
  var hwnd=open(winURL,"_blank",'resizable=no,width=550,height=430,left=10,top=10');
  if (!hwnd.opener) hwnd.opener=self;
  if (hwnd.focus) hwnd.focus();
  return (false);
}

function makeGreeting(){
  var today = new Date();
  var dayOfMonth = today.getDate();
  var dayOfWeek = today.getDay();
  var hour = today.getHours();
  var monthOfYear = today.getMonth();
  var year = today.getYear();
  var greeting;

  var dayArray = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
  var monthArray = new Array("January","February","March","April","May","June","July","August","September","October","November","December");

  if (hour < "12") {
    greeting = "Good Morning"
    }
  else if (hour >= "12" && hour < "17") {
    greeting = "Good Afternoon"
    }
  else {
    greeting = "Good Evening"
    }

  if (year <= 200) {
    year += 1900;
    }

  greeting = greeting + ". It's " + dayArray[dayOfWeek] + ", " + monthArray[monthOfYear] + " " + dayOfMonth + ", " + year + ".";

  return(greeting);

}

function toggleBlockDisplay(blockID,visibility){
  if (document.getElementById) {
    var current = (document.getElementById(blockID).style.display == 'block' || document.getElementById(blockID).style.display == '') ? 'none' : '';
    if (visibility != null) current = visibility;
    document.getElementById(blockID).style.display = current;
  }
  else if (document.all) {
    current = (document.all[blockID].style.display == 'block') ? 'none' : 'block'
    if (visibility != null) current = visibility;
    document.all[blockID].style.display = current;
  }
}


function TF_GetVarValue(varName,varValueIfUndefined){
   var variableDefined = eval("typeof " + varName + " != 'undefined'");
   if (variableDefined) return(eval(varName));
   return varValueIfUndefined;   
}

function TF_GetYear(theDate) {
	x = theDate.getYear();
	var y = x % 100;
	y += (y < 38) ? 2000 : 1900;
	return y;
}

function TF_AddDate(date1, numDays, DestDateFld)
{	
	if (date1.length==0) return null;
	
		
	var NewDate = new Date(date1);
	NewDate.setDate(NewDate.getDate() + numDays);
/*	
	var objSourceDate = new Date(date1);
        var SourceDateinMs = objSourceDate.getTime();
        var DestDateinMs = SourceDateinMs + 1000 * 60 * 60 *24 * numDays
	var objDestDate = new Date();	
        objDestDate.setTime(DestDateinMs);
	var NewDateYear = objDestDate.getYear();
        if (NewDateYear.toString().length==1) NewDateYear="0"+NewDateYear.toString();
	
	var NewDate=((objDestDate.getMonth() + 1)+"/" + (objDestDate.getDate())+"/"+NewDateYear);
*/
	NewDate=(NewDate.getMonth() + 1)+"/" + (NewDate.getDate())+"/"+TF_GetYear(NewDate);
	if(DestDateFld)
	{
		DestDateFld.value=NewDate;
	}
	return NewDate;
}

function TF_DateAdd(startDate, numDays, numMonths, numYears)
{
	var objStartDate = new Date(startDate);
	var returnDate = new Date(objStartDate.getTime());
	var yearsToAdd = numYears;
	
	var month = returnDate.getMonth()	+ numMonths;
	if (month > 11)
	{
		yearsToAdd = Math.floor((month+1)/12);
		month -= 12*yearsToAdd;
		yearsToAdd += numYears;
	}
	returnDate.setMonth(month);
	returnDate.setFullYear(returnDate.getFullYear()	+ yearsToAdd);	
	returnDate.setTime(returnDate.getTime()+60000*60*24*numDays);
	strReturnDate=((returnDate.getMonth() + 1)+"/" + (returnDate.getDate())+"/"+returnDate.getFullYear());
	return strReturnDate;
}

  
function TF_ReplaceString(string,text,by,all) {

    // Replaces text with by in string
    // If all is false then only one replacement is made
    if (all == null) all = true;
    var strLength = string.length;
    var txtLength = text.length;

    if ((strLength == 0) || (txtLength == 0)) return string;

    var i = string.indexOf(text);
    if ((!i) && (text != string.substring(0,txtLength))) return string;

    if (i == -1) return string;

    var newstr = string.substring(0,i) + by;

    if (all) {
      if (i+txtLength < strLength) {
        newstr += TF_ReplaceString(string.substring(i+txtLength,strLength),text,by,all);
      }
    } else {
        newstr += string.substring(i+txtLength,strLength);
    }
    

    return newstr;
  
}

function TF_ShowGreeting () {
  var today = new Date()
  var time = today.getTime();
  var dayOfMonth = today.getDate();
  var dayOfWeek = today.getDay();
  var hour = today.getHours();
  var minutes = today.getMinutes();
  var monthOfYear = today.getMonth();
  var yearPast = today.getYear();
 
  var day
  if (dayOfWeek == 1) day = "Monday";
  if (dayOfWeek == 2) day = "Tuesday";
  if (dayOfWeek == 3) day = "Wednesday";
  if (dayOfWeek == 4) day = "Thursday";
  if (dayOfWeek == 5) day = "Friday";
  if (dayOfWeek == 6) day = "Saturday";
  if (dayOfWeek == 0) day = "Sunday";

  var greeting
  if (hour < "12") greeting = "Good Morning";
  if (hour > "11" && hour < "17") greeting = "Good Afternoon";
  if (hour > "16") greeting = "Good Evening";

  var month
  if (monthOfYear == "0") month = "January";
  if (monthOfYear == "1") month = "February";
  if (monthOfYear == "2") month = "March";
  if (monthOfYear == "3") month = "April";
  if (monthOfYear == "4") month = "May";
  if (monthOfYear == "5") month = "June";
  if (monthOfYear == "6") month = "July";
  if (monthOfYear == "7") month = "August";
  if (monthOfYear == "8") month = "September";
  if (monthOfYear == "9") month = "October";
  if (monthOfYear == "10") month = "November";
  if (monthOfYear == "11") month = "December";

  var year
  year = yearPast
  if (year <= 200) year = year + 1900;
  document.write(greeting + "&nbsp;-&nbsp;" + day + " " + month + " " + dayOfMonth +  ", " + year); 
}


function TF_DatePart(strDate){
  var dt = new Date(strDate);
  var yy = dt.getYear();
  var year = (yy < 1000) ? yy + 1900 : yy;
  return dt.getMonth()+1+"/"+dt.getDate()+"/"+ year;
}

function TF_RefreshStaticPageIfNeeded(url) {
  if (location.search.length == 0) {
    var today = new Date(TF_DatePart(new Date()));
    var pgDate = new Date(TF_DatePart(document.lastModified));
    if (pgDate < today) {
      location.href = url;
    } 
  }
}

function TF_RefreshStaticPageAfterMinutes(url,numMinutes) {
  if (location.search.length == 0) {
    var refreshTime = new Date();
    refreshTime.setTime(refreshTime.getTime() - numMinutes * 60000);
    var pgDate = new Date(document.lastModified);
    // alert(refreshTime +"  /  " + pgDate);
    if (pgDate < refreshTime) {
      location.href = url;
    } 
  }
}

function TF_ValidateDate( fld, fldname )
{
	if( fld.value.length === 0 || isNaN( Date.parse( fld.value ) ) ) {
		alert( 'Please enter a valid date in the "' + fldname + '" field.' );
		CheckParentVisibility( fld );
		fld.focus();
		return false;
	}
	
	return true;
}

function TF_ValidateDateRange(fldDate,minDate,maxDate,fldName)
{
	var min = new Date(minDate);
	var max = new Date(maxDate);
        var entered = new Date(fldDate.value);
        if(entered < min || entered > max)
        {
          alert(fldName + " must be between " + minDate + " and " + maxDate);
          CheckParentVisibility(fldDate);
          fldDate.focus();
          return false;
        }
        return true;
}

function TF_StateZZ_CountryRequiredOK(fldState,fldCountry)
{          
	if (fldState.type == 'text') 
	   var zzState = fldState.value;
	else
           var zzState = TF_GetSelectValue(fldState);
  
  // get country value         
       
        if(fldCountry){

	  if (fldCountry.type == 'text') 
	   var zzCountry = fldCountry.value;
	  else
	   var zzCountry = TF_GetSelectValue(fldCountry); 
	   var zzCountry = zzCountry.toUpperCase();    
        }   


//if stats is US territories
if(zzState=="PR" || zzState=="VI" || zzState=="AS" || zzState=="GU"){
  if(fldCountry){
			if(zzCountry == ""){
				alert('Please select a value for Country');
				CheckParentVisibility(fldCountry);
				fldCountry.focus();
				return false;
			}
			if(zzState == "PR"){
						if(zzCountry !="PUERTO RICO"){
						alert('You have selected ' +TF_GetSelectValue(fldState)+ ' as a State. Please select PUERTO RICO for a Country');
						CheckParentVisibility(fldCountry);
						fldCountry.focus();
						return false;
						}
				}	
			if(zzState == "VI"){
						if(zzCountry !="VIRGIN ISLANDS (US)"){
						alert('You have selected ' +TF_GetSelectValue(fldState)+ ' as a State. Please select VIRGIN ISLANDS (U.S.) for a Country');
						CheckParentVisibility(fldCountry);
						fldCountry.focus();
						return false;
						}
				}			
			if(zzState == "AS"){
						if(zzCountry !="AMERICAN SAMOA"){
						alert('You have selected ' +TF_GetSelectValue(fldState)+ ' as a State. Please select AMERICAN SAMOA for a Country');
						CheckParentVisibility(fldCountry);
						fldCountry.focus();
						return false;
						}
				}	
                      if(zzState == "GU"){
						if(zzCountry !="GUAM"){
						alert('You have selected ' +TF_GetSelectValue(fldState)+ ' as a State. Please select GUAM for a Country');
						CheckParentVisibility(fldCountry);
						fldCountry.focus();
						return false;
						}
				}					
		}
	 
}
//if Canadian provinces or territories
      if(zzState == "AB" || zzState == "BC" || zzState == "MB" || zzState == "NB" || zzState == "NS" || zzState == "NT" || zzState == "ON" || zzState == "PE" || zzState == "QC" || zzState == "SK" || zzState == "YT"  || zzState=="NF"){
	if(fldCountry){
				if(zzCountry == "" || zzCountry != "CANADA"){
					alert('You have selected ' +TF_GetSelectValue(fldState)+ ' as a State. Please select CANADA for the Country');
					CheckParentVisibility(fldCountry);
					fldCountry.focus();
					return false;
				}
  
    }
}

// if state is outside USA and Canada	
	if(zzState=="ZZ" || zzState=="--" || zzState=="MP" || zzState=="PW")
	{
             if(fldCountry){
		  if(zzCountry == ""){
				
		    alert('Please select a value for Country');
		    CheckParentVisibility(fldCountry);
		    fldCountry.focus();
		    return false;
			
		  }
		  if(zzState == "--"){
		    if(zzCountry == "USA" || zzCountry == "CANADA"){
					alert('You have selected Outside US & CANADA as a State and ' +zzCountry+' as Country. Please select a value for a Country');
						CheckParentVisibility(fldCountry);
						fldCountry.focus();
						return false;		      
		    
		    }
		  }
		  if(zzState == "ZZ"){
		    if(zzCountry == "USA" || zzCountry == "CANADA"){
					alert('You have selected Outside US & CANADA as a State and ' +zzCountry+' as Country. Please select a value for a Country');
						CheckParentVisibility(fldCountry);
						fldCountry.focus();
						return false;		      
		    
		    }
		  }
		  
		  //if state outside US and Canada then they if the country falls in us territories they have to choose respective country
		  if(zzState=="ZZ" || zzState=="--"){
		    if(zzCountry == "PUERTO RICO"){
					alert('You have selected Outside US & CANADA as a State and ' +zzCountry+' as Country. Please select PUERTO RICO for a State');
						fldState.focus();
						return false;		      
		    
		    }
		  }
		  
		  if(zzState=="ZZ" || zzState=="--"){
		    if(zzCountry == "VIRGIN ISLANDS (US)"){
					alert('You have selected Outside US & CANADA as a State and ' +zzCountry+' as Country. Please select VIRGIN ISLANDS (U.S.) for a State');
						fldState.focus();
						return false;		      
		    
		    }
		  }

		  if(zzState=="ZZ" || zzState=="--"){
		    if(zzCountry == "AMERICAN SAMOA"){
					alert('You have selected Outside US & CANADA as a State and ' +zzCountry+' as Country. Please select AMERICAN SAMOA for a State');
						fldState.focus();
						return false;		      
		    
		    }
		  }

		  if(zzState=="ZZ" || zzState=="--"){
		    if(zzCountry == "GUAM"){
					alert('You have selected Outside US & CANADA as a State and ' +zzCountry+' as Country. Please select GUAM for a State');
						fldState.focus();
						return false;		      
		    
		    }
		  }
		  
		  if(zzState=="ZZ" || zzState=="--"){
		    if(zzCountry == "NORTHERN MARIANA ISLANDS"){
					alert('You have selected Outside US & CANADA as a State and ' +zzCountry+' as Country. Please select NORTHERN MARIANA ISLANDS for a State');
						fldState.focus();
						return false;		      
		    
		    }
		  }
		  
		  
		  
		  
		  if(zzState == "MP"){
		   if(zzCountry != "NORTHERN MARIANA ISLANDS"){
			 alert('You have selected ' +TF_GetSelectValue(fldState)+ ' as a State. Please select NORTHERN MARIANA ISLANDS for the Country');
			 CheckParentVisibility(fldCountry);
			 fldCountry.focus();
		   return false;
		  	}
		  }
                  if(zzState == "PW"){
		   if(zzCountry != "PALAU"){
			 alert('You have selected ' +TF_GetSelectValue(fldState)+ ' as a State. Please select PALAU for the Country');
			 CheckParentVisibility(fldCountry);
			 fldCountry.focus();
		   	 return false;
		  	}
		  }		  
 
		}
	} 
	

      
      if(zzState=="AE" || zzState=="AL"|| zzState=="AK"|| zzState=="AZ"|| zzState=="AR"|| zzState=="CA"|| zzState=="CO"|| zzState=="CT"|| zzState=="DE"|| zzState=="DC"|| zzState=="FL"|| zzState=="GA"|| zzState=="HI"|| zzState=="IA"||zzState=="ID"|| zzState=="IL"|| zzState=="IN"|| zzState=="KS"|| zzState=="KY"|| zzState=="LA"|| zzState=="ME"|| zzState=="MD"|| zzState=="MA"|| zzState=="MI"|| zzState=="MN"|| zzState=="MS"|| zzState=="MO"|| zzState=="MT"|| zzState=="NV"|| zzState=="NH"|| zzState=="NJ"|| zzState=="NM"|| zzState=="NY"|| zzState=="NC"|| zzState=="ND"|| zzState =="NE"|| zzState=="OH"|| zzState=="OK"|| zzState=="OR"|| zzState=="PA"|| zzState=="RI"|| zzState=="SC"|| zzState=="SD"|| zzState=="TN"|| zzState=="TX"|| zzState=="UT"|| zzState=="VT"|| zzState=="VA"|| zzState=="WA"|| zzState=="WV"|| zzState=="WI"|| zzState=="WY" || zzState=="AA"|| zzState=="AP"){

      if (zzState=="AE") {
      	if (typeof country_AE_validate == 'undefined'){
									country_AE_validate = true;
				}
				if (country_AE_validate) {

					 if(fldCountry){
						if (zzCountry !=""){

							if ((zzCountry !="USA")){

								alert('You have selected "' +  zzState + '", as a state. Please select or type "USA" for the Country');
								CheckParentVisibility(fldCountry);
								fldCountry.focus();
								return false;

							}

						}
					}
       }
     }else{ 
	 	if(fldCountry){
						if (zzCountry !=""){

							if ((zzCountry !="USA")){

								alert('You have selected "' +  zzState + '", as a state. Please select or type "USA" for the Country');
								CheckParentVisibility(fldCountry);
								fldCountry.focus();
								return false;

							}

						}
					}
	 	
	 }
    }
	
	return true;
}



function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

/**
 * @param {String} jqSelector A jQuery selector
 * @param {String} contentSource (optional) 'title' (default) if the tooltip content should be
 *   taken from the source element's 'title' attribute
 *   'id' if the tooltip content should be retrieved from an existing element on the page with a corresponding ID
 *   - the corresponding ID for the title should be <sourceID>-ToolTipTitle
 *   - the corresponding ID for the body should be <sourceID>-ToolTip
 *   'config' if the tooltip content is specified in the dzConfig object
 * @param {Object} dzConfig (optional) An object with extra configuration parameters:
 *   title {string} title content
 *   body {string} body content
 *   stem {boolean} true (default) to display stem, false to hide it
 *   closebutton {var} false to hide it, true to display default button, {string} to display button with specified title text
 *   menu {boolean} true if you want the tooltip to display in a context-menu mode
 *   sourceID {string} the tooltip title & body will use this ID instead of the source element's ID
 * @param {Object} qtipConfig a qtip2 configuration object to apply
 *
 * TF_ToolTip( '#myid', {title: 'mytitle', body: 'mybody', stem: false, closebutton: true} )
 *
 * @example
 * TF_ToolTip( '#myid', '#sourceID' ) - shorthand for:
 * TF_ToolTip( '#myid', 'id', {sourceID: 'sourceID'} )
 *
 * TF_ToolTip( '#myid', 'My ToolTip' ) - shorthand for:
 * TF_ToolTip( '#myid', 'config', {body: 'My ToolTip'} )
 */
function TF_ToolTip( jqSelector, contentSource, dzConfig, qtipConfig )
{
	// default configuration
	var defaultConfig = {
		content: {
			text: false,
			title: {
				text: false,
				button: false
			}
		},
		position: { viewport: $(window) },
		style: { tip: true },
		hide: { fixed: false }
	};

	if( dzConfig ) {
		if( dzConfig.title ) {
			defaultConfig.content.title.text = dzConfig.title;
		}

		if( dzConfig.body ) {
			defaultConfig.content.text = dzConfig.body;
		}

		if( dzConfig.stem !== undefined && dzConfig.stem === false ) {
			defaultConfig.style.tip = false;
		}

		if( dzConfig.menu ) {
			TF_ToolTip_SetDZOption( defaultConfig, 'menu' );
		}

		if( dzConfig.cellmenu ) {
			TF_ToolTip_SetDZOption( defaultConfig, 'cellmenu' );
		}
	}

	// runtime configuration additions and overrides
	// anything in qtipConfig will be added to, or overwrite, properties in defaultConfig
	if( qtipConfig ) {
		$.extend( true, defaultConfig, qtipConfig );
	}
	
	var sourceElem = $( jqSelector );

	sourceElem.each( function( index, elem ) {
		var config = $.extend( true, {}, defaultConfig );
		TF_ToolTip_SetOptions( $(elem), contentSource, config, dzConfig );

		if( config.content.text || config.content.title.text ) {
			$(elem).qtip( config );
		}
	});
}


function TF_ToolTip_SetOptions( sourceElem, contentSource, config, dzConfig )
{
	if( contentSource === 'function' ) {
		if( dzConfig.bodyCallback ) {
			config.content.text = dzConfig.bodyCallback;
		}

		if( dzConfig.titleCallback ) {
			config.content.title.text = dzConfig.titleCallback;
		}
	}
	// contentSource:  default = parse 'title' attribute
	else if( contentSource === undefined || contentSource.length === 0 || contentSource === 'title' ) {
		// if contentSource was not specified, default to 'title', but only if values haven't been populated from dzConfig
		if( !config.content.text ) {
			//config.content.text = function(api) { return TF_ToolTip_GetContent( this[0], api, 'title', 'body' ); };
			config.content.text = TF_ToolTip_GetContent( sourceElem, 'title', 'body', config );
		}

		if( !config.content.title.text ) {
			//config.content.title.text = function(api) { return TF_ToolTip_GetContent( this[0], api, 'title', 'title' ); };
			config.content.title.text = TF_ToolTip_GetContent( sourceElem, 'title', 'title', config );
		}
	}
	else if( contentSource === 'id' || contentSource.charAt(0) === '#' ) {
		if( contentSource.charAt(0) === '#' ) {
			sourceElem = $( contentSource );
			contentSource = 'id';
		}
		else if( dzConfig.sourceID ) {
			sourceElem = $( '#' + dzConfig.sourceID );
		}

		var bodyText = TF_ToolTip_GetContent( sourceElem, contentSource, 'body', config );
		if( bodyText ) {
			config.content.text = bodyText;
		}

		var titleText = TF_ToolTip_GetContent( sourceElem, contentSource, 'title', config );
		if( titleText ) {
			config.content.title.text = titleText;
		}
	}
	else if( contentSource !== 'config' ) {
		config.content.text = contentSource;
	}

	if( dzConfig && dzConfig.closebutton ) {
		config.content.title.button = dzConfig.closebutton;
		if( !config.content.title.text ) {
			config.content.title.text = 'tip';
		}
		config.hide = { event: false };
	}
}

/**
 * @param {Object} sourceElem The DOM element that triggered the tooltip
 * @param {string} contentSource 'title':  pull the content from the element's 'title' attribute
 *   'id':  pull the content from elements with corresponding id's
 * @param {string} contentType 'title' for the title, 'body' for the body
 */
function TF_ToolTip_GetContent( sourceElem, contentSource, contentType, config )
{
	var idSuffix = '-ToolTip';
	var content = '';

	if( contentType === 'title' ) {
		idSuffix += 'Title';
	}

	if( contentSource === 'title' ) {
		var titleAttrib = sourceElem.attr( 'title' );
		var bodySeparator = ':: ';
		var bodyIndex = titleAttrib.indexOf( bodySeparator );

		if( contentType === 'title' ) {
		// get the title portion - 'Title' from 'Title:: body'
			bodyIndex = bodyIndex === -1 ? 0 : bodyIndex;
			content = titleAttrib.substring( 0, bodyIndex );
		} else {
		// get the body portion - 'body' from 'Title:: body'
			bodyIndex = bodyIndex === -1 ? 0 : bodyIndex + bodySeparator.length;
			content = titleAttrib.substring( bodyIndex );
			content = content.replace( / -- /g, '<br>' );
			content = content.replace( /{/g, '<' );
			content = content.replace( /}/g, '>' );
		}
	}
	else if( contentSource === 'id' ) {
		var contentElem = $( '#' + sourceElem.attr( 'id' ) + idSuffix );
		if( contentElem.length > 0 ) {
			content = contentElem.html();

			TF_ToolTip_SetPropertiesFromAttributes( contentElem, config );
		}
	}

	return content;
}


function TF_ToolTip_SetDZOption( qtipConfig, option ) {
	if( option === 'menu' || option == 'cellmenu') {
		$.extend( true, qtipConfig, {
			show: {
				delay: 250
			},
			hide: {
				fixed: true,
				delay: 250
			}
		});
	}

	switch( option ) {
		case 'menu':
			$.extend( true, qtipConfig, {
				position: {
					target: 'mouse',
					adjust: {
						mouse: false
					}
				}
			});

			break;

		case 'cellmenu':
			$.extend( true, qtipConfig, {
				position: {
					target: false,
					my: 'right center',
					at: 'left center'
				}
			});

			break;
	}
}


function TF_ToolTip_SetPropertiesFromAttributes( contentElem, qtipConfig ) {
	var attrib;

	attrib = contentElem.attr( 'tip_menu' );
	if( attrib && attrib.toLowerCase() === 'true' ) {
		TF_ToolTip_SetDZOption( qtipConfig, 'menu' );
	}

	attrib = contentElem.attr( 'tip_cellmenu' );
	if( attrib && attrib.toLowerCase() === 'true' ) {
		TF_ToolTip_SetDZOption( qtipConfig, 'cellmenu' );
	}

	attrib = contentElem.attr( 'tip_qtip' );
	if( attrib ) {
		var extraConfig = JSON.parse( attrib );
		$.extend( qtipConfig, extraConfig );
	}
}

