//******************* GENERAL PURPOSE FORM VALIDATION FUNCTIONS *************************
function validate(check,obj,len,msg){
  /* 
  validate(checkType,formObject,length,message);
  
  checkType: Specifies the type of check to perform on the Form Object.
             Valid Values are:
             required      - Applies to TextFields - Ensures that characters have been entered in the field (spaces are ignored).
             isEmail       - Check is a Textfield contains a valid email address. 
                             For detailed email checking call the function emailCheck() directly.
             containsNumber- Checks is a Textfield contains any numeric characters.
             hasLength     - Checks if a Textfield contains at least a certain number of characters (spaces are ignored).            
             isNumeric     - Checks if a textfield is a number.
             selected      = Checks if a selectbox has a option with a value equal to length selected.
  
  formObject:Reference to the Form Object which is to be checked.
  length    : When checkType is 'hasLength' length specifies the minimu lenght that the Textfield must have. 
              When checkType is 'selected'  length specifies the option which must be selected for the function to return true.
              When checkType is 'findRegExpression' length specifies the regular expression to find in the string.              
              For all other checkTypes set length = 0
  message   : The text to display in the alert box if validation fails.
  
  NOTES:
  This function returns false if validation fails, true if validation is successfull.            
               
                      
  USAGE: 
  validate('required',document.formName.sFirstName,0,'Please enter your First Name!')
  */

  var bIsValid = true;
  switch (check)
  {
    case 'required'://Check if text has been entered into this field
      if (!isFilled(obj.value)){bIsValid = false;}
      break;        
    case 'isEmail'://Check if text is a email address.
      if(emailCheck(obj.value) != 0){bIsValid = false;}
      break;
    case 'containsNumber'://Check if text contains a number.
      if (containsNumber(obj.value)){bIsValid = false;}
      break;    
    case 'hasLength'://Check if text has a certain length.                
      if (len != 0 && !isLength(obj.value,len)){bIsValid = false;}
      break;
    case 'isNumeric'://Check if text contains a number.
      if (!isNumeric(obj.value)){bIsValid = false;}
      break;
    case 'selected'://Check if the SelectBox option has a value of 0.
      if(obj.options[obj.selectedIndex].value==len){bIsValid = false;}
      break
    case 'isChecked'://Check if a Checkbox has been ticked.
      if(!obj.checked){bIsValid = false;}
      break 
    case 'findRegExpression'://Check if a Regular Expression if found in string.
      if (findRegExpression(obj.value,len)){bIsValid = false;}
      break                               
  }
  if (!bIsValid)
  {
    alert(msg)
    obj.focus()
    return false  
  }
  return true;
}

// General purpose function to see if an input value has been entered.
function isFilled(inputStr) 
{
  if (inputStr == null || trim(inputStr) == "")
  {
    return false
  }
  return true
}

// General purpose function to see if an input value has a certain length.
function isLength(inputStr,iLen) 
{
  inputStr = trim(inputStr,iLen)
  if (inputStr.length < iLen)
  {
    return false
  }
  return true
}

// General purpose function to see if an input value contains a number.
function containsNumber(s)
{ 
  for (i=0; i <= 9;i=i+1)
  {
    if (s.search(i) != -1)
    {
      return true;
    }
  }
  return false;
}  

// General purpose function to see if a regular expression matches input value.
function findRegExpression(s,sExpression)
{ 
  var objRegExp = new RegExp(sExpression);
  var aMatch=s.match(objRegExp);
  if(aMatch==null)
    return false;

  return true;
}  

// General purpose function Trim.
function trim (s)
{
  return rtrim(ltrim(s));
}

// General purpose function Left Trim.
function ltrim (s)
{
  return s.replace(/^\s*/,"")
}

// General purpose function Right Trim.
function rtrim (s)
{
  return s.replace(/\s*$/,"");
}

// General purpose function is value a number.
function isNumeric(s)
{
   var ValidChars = "0123456789.";
   var IsNumber=true;
   var Char; 
   for (i = 0; i < s.length && IsNumber == true; i++) 
      { 
      Char = s.charAt(i); 
      if (ValidChars.indexOf(Char) == -1) 
         {
         IsNumber = false;
         }
      }
   return IsNumber;   
}

//General purpose function if value is a Email.
function emailCheck (emailStr) {
  /* 
     RETURN CODES
     0 = ValidEmail
     1 = @ and .'s check failed.
     2 = Non Valid Characters detected.
     3 = Non Valid Characters detected in domainname.
     4 = Email wrong and is not valid.
     5 = The IP Address is not valid.
     6 = Email is not valid.
     7 = Unknown country domain.
     8 = No Host Name Specified.
  */   
  var sFormattedEmail = emailStr.replace(/ /g,"");
  var checkTLD=1;
  var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
  var emailPat=/^(.+)@(.+)$/;
  var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
  var validChars="\[^\\s" + specialChars + "\]";
  var quotedUser="(\"[^\"]*\")";
  var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
  var atom=validChars + '+';
  var word="(" + atom + "|" + quotedUser + ")";
  var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
  var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
  var matchArray=sFormattedEmail.match(emailPat);
  if (matchArray==null){return 1;}   
  var user=matchArray[1];
  var domain=matchArray[2];  
  for (i=0; i<user.length; i++) 
  {
    if (user.charCodeAt(i)>127){return 2;}       
  }    
  for (i=0; i<domain.length; i++) 
  {
    if (domain.charCodeAt(i)>127){ return 3;}   
  }  
  if (user.match(userPat)==null){return 4;}    
  var IPArray=domain.match(ipDomainPat);
  if (IPArray!=null) 
  {
    for (var i=1;i<=4;i++) 
    {
      if (IPArray[i]>255){return 5;}        
    }
    return true;
  }
  var atomPat=new RegExp("^" + atom + "$");
  var domArr=domain.split(".");
  var len=domArr.length;
  for (i=0;i<len;i++) 
  {
    if (domArr[i].search(atomPat)==-1){return 6;}    
  }  
  if (checkTLD && domArr[domArr.length-1].length!=2 && domArr[domArr.length-1].search(knownDomsPat)==-1) 
  {
    return 7;
  }      
  // Make sure there's a host name preceding the domain.  
  if (len<2){return 8;} 
  return 0;
}

//Script for basic creditcard validation - http://www.evolt.org/article/rating/17/24700/
function isCreditCard(cardNumber, cardType) {
  var isValid = false;
  var ccCheckRegExp = /[^\d ]/;
  isValid = !ccCheckRegExp.test(cardNumber);

  if (isValid)
  {
    var cardNumbersOnly = cardNumber.replace(/ /g,"");
    var cardNumberLength = cardNumbersOnly.length;
    var lengthIsValid = false;
    var prefixIsValid = false;
    var prefixRegExp;

    switch(cardType)
    {
      case "2": //mastercard
        lengthIsValid = (cardNumberLength == 16);
        prefixRegExp = /^5[1-5]/;
        break;

      case "1"://visa
        lengthIsValid = (cardNumberLength == 16 || cardNumberLength == 13);
        prefixRegExp = /^4/;
        break;

      case "3"://amex
        lengthIsValid = (cardNumberLength == 15);
        prefixRegExp = /^3(4|7)/;
        break;

      default:
        prefixRegExp = /^$/;
        alert("Card type not found");
    }

    prefixIsValid = prefixRegExp.test(cardNumbersOnly);
    isValid = prefixIsValid && lengthIsValid;
  }

  if (isValid)
  {
    var numberProduct;
    var numberProductDigitIndex;
    var checkSumTotal = 0;

    for (digitCounter = cardNumberLength - 1; 
      digitCounter >= 0; 
      digitCounter--)
    {
      checkSumTotal += parseInt (cardNumbersOnly.charAt(digitCounter));
      digitCounter--;
      numberProduct = String((cardNumbersOnly.charAt(digitCounter) * 2));
      for (var productDigitCounter = 0;
        productDigitCounter < numberProduct.length; 
        productDigitCounter++)
      {
        checkSumTotal += 
          parseInt(numberProduct.charAt(productDigitCounter));
      }
    }

    isValid = (checkSumTotal % 10 == 0);
  }

  return isValid;
}

function $(sElementSelector) {
  switch(sElementSelector.substr(0,2)) {
    case 'n:':
      return document.getElementsByName(sElementSelector.substring(2,sElementSelector.length));
    case 't:':
      return document.getElementsByTagName(sElementSelector.substring(2,sElementSelector.length));
    default:
      return document.getElementById(sElementSelector);
  }
}

function createHTMLElement(sName,aAttributes,sContent) {
  var oElement = document.createElement(sName);

  for(var i=0; i<aAttributes.length; i++)
    oElement.setAttribute(aAttributes[i].sName,aAttributes[i].sValue);

  if(sContent && sContent != '')
    oElement.innerHTML = sContent;

  return oElement;
}

// General purpose function to select/unselect multiple checkboxes by selecting/unselecting one checkbox
function toggleSelectAll(selectAllField, checkboxNames) {
  var aCheckboxNames = checkboxNames.split(',');
  var checkboxes     = null;

  for(var nameIndex=0;nameIndex<aCheckboxNames.length;nameIndex++) {
    checkboxes = document.getElementsByName(aCheckboxNames[nameIndex]);
    for(var checkboxIndex=0; checkboxIndex<checkboxes.length; checkboxIndex++)
      checkboxes[checkboxIndex].checked = (selectAllField.checked == true ? true : false);
  }
}

// Replace all occurances of a string.
function xreplace(sString,toberep,repwith) {
  var temp = sString;
  var i = temp.indexOf(toberep);
  while(i > -1) {
    temp = temp.replace(toberep, repwith);
    i = temp.indexOf(toberep);
  }
  return temp;
}

// Replaces special characters by their HTML equivalent
function encodeSpecialChars(sString) {
  var sProcessedString = sString;
  var aSpecialChars    = [{sChar:'ä',sHTMLEncoding:'&auml;'},
                          {sChar:'ö',sHTMLEncoding:'&ouml;'},
                          {sChar:'ü',sHTMLEncoding:'&uuml;'},
                          {sChar:'ß',sHTMLEncoding:'&szlig;'},
                          {sChar:'Ä',sHTMLEncoding:'&Auml;'},
                          {sChar:'Ö',sHTMLEncoding:'&Ouml;'},
                          {sChar:'Ü',sHTMLEncoding:'&Uuml;'},
                          {sChar:'Á',sHTMLEncoding:'&Aacute;'},
                          {sChar:'á',sHTMLEncoding:'&aacute;'},
                          {sChar:'É',sHTMLEncoding:'&Eacute;'},
                          {sChar:'é',sHTMLEncoding:'&eacute;'},
                          {sChar:'Í',sHTMLEncoding:'&Iacute;'},
                          {sChar:'í',sHTMLEncoding:'&iacute;'},
                          {sChar:'Ñ',sHTMLEncoding:'&Ntilde;'},
                          {sChar:'ñ',sHTMLEncoding:'&ntilde;'},
                          {sChar:'Ó',sHTMLEncoding:'&Oacute;'},
                          {sChar:'ó',sHTMLEncoding:'&oacute;'},
                          {sChar:'Ú',sHTMLEncoding:'&Uacute;'},
                          {sChar:'ú',sHTMLEncoding:'&uacute;'},
                          {sChar:'¿',sHTMLEncoding:'&iquest;'},
                          {sChar:'¡',sHTMLEncoding:'&iexcl;'}];

  for(var i=0; i<aSpecialChars.length; i++)
    sProcessedString = sProcessedString.replace(new RegExp(aSpecialChars[i].sChar,'g'),aSpecialChars[i].sHTMLEncoding);

  return sProcessedString;
}

// Replaces HTML encoded characters by their special character equivalent
function decodeSpecialChars(sString) {
  var sProcessedString = sString;
  var aSpecialChars    = [{sChar:'ä',sHTMLEncoding:'&auml;'},
                          {sChar:'ö',sHTMLEncoding:'&ouml;'},
                          {sChar:'ü',sHTMLEncoding:'&uuml;'},
                          {sChar:'ß',sHTMLEncoding:'&szlig;'},
                          {sChar:'Ä',sHTMLEncoding:'&Auml;'},
                          {sChar:'Ö',sHTMLEncoding:'&Ouml;'},
                          {sChar:'Ü',sHTMLEncoding:'&Uuml;'},
                          {sChar:'Á',sHTMLEncoding:'&Aacute;'},
                          {sChar:'á',sHTMLEncoding:'&aacute;'},
                          {sChar:'É',sHTMLEncoding:'&Eacute;'},
                          {sChar:'é',sHTMLEncoding:'&eacute;'},
                          {sChar:'Í',sHTMLEncoding:'&Iacute;'},
                          {sChar:'í',sHTMLEncoding:'&iacute;'},
                          {sChar:'Ñ',sHTMLEncoding:'&Ntilde;'},
                          {sChar:'ñ',sHTMLEncoding:'&ntilde;'},
                          {sChar:'Ó',sHTMLEncoding:'&Oacute;'},
                          {sChar:'ó',sHTMLEncoding:'&oacute;'},
                          {sChar:'Ú',sHTMLEncoding:'&Uacute;'},
                          {sChar:'ú',sHTMLEncoding:'&uacute;'},
                          {sChar:'¿',sHTMLEncoding:'&iquest;'},
                          {sChar:'¡',sHTMLEncoding:'&iexcl;'}];

  for(var i=0; i<aSpecialChars.length; i++)
    sProcessedString = sProcessedString.replace(new RegExp(aSpecialChars[i].sHTMLEncoding,'g'),aSpecialChars[i].sChar);

  return sProcessedString;
}

// Inserts a string into a given textbox at the current selection or replacing it or surrounds the current selection by two given strings
function insertStringAtSelection(oTextbox,sStringStart,sStringEnd,bReplaceSelection) {
  var sSelectedText = '';

  if(!sStringEnd)
    sStringEnd = '';

  oTextbox.focus();

  if(document.selection) {
    var oRange = document.selection.createRange();
    var sSelectedText = oRange.text;
    oRange.move('character',-sStringEnd.length);

    oRange.text = sStringStart + sSelectedText + sStringEnd;

    oRange.moveStart('character',(sStringEnd != '' ? sStringStart.length + sSelectedText.length + sStringEnd.length : sStringStart.length));
    oRange.select();
  } else if(typeof oTextbox.selectionStart != 'undefined') {
    var iStart = oTextbox.selectionStart;
    var iEnd = oTextbox.selectionEnd;
    var iCursorPos = iStart + sStringStart.length;

    if(!bReplaceSelection)
      sSelectedText = oTextbox.value.substring(iStart,iEnd);
    oTextbox.value = oTextbox.value.substr(0,iStart) + sStringStart + sSelectedText + sStringEnd + oTextbox.value.substr(iEnd);

    if(sStringEnd != '')
      iCursorPos += sSelectedText.length + sStringEnd.length;

    oTextbox.selectionStart = iCursorPos;
    oTextbox.selectionEnd = iCursorPos;
  }

  return;
}

// Adds a site to the favorites (only IE, in other browsers the user will get an alert)
function addToFavorites(sURL, sFavName) {
  if(navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) >= 4)
    window.external.AddFavorite(sURL, sFavName);
  else {
    var FavText = "Add ";

    FavText += sFavName;
    if(navigator.appName == "Netscape")
       FavText += " with the shortcut CTRL+D";
    FavText += " to your favorites.";
    alert(FavText);
  }
}

// Adds an event listener to an object
function addObserver(oElement,sEvent,oHandler,bCapture) {
  if(oElement.addEventListener)
    oElement.addEventListener(sEvent,oHandler,bCapture);
  else
    oElement.attachEvent('on'+sEvent,oHandler);
}

// Removes an event listener from an object
function removeObserver(oElement,sEvent,oHandler,bCapture) {
  if(oElement.removeEventListener)
    oElement.removeEventListener(sEvent,oHandler,bCapture);
  else
    oElement.dettachEvent('on'+sEvent,oHandler);
}

// Stops the defined event
function stopEvent(oEvent) {
  if(!oEvent)
    oEvent = window.event

  oEvent.cancelBubble = true;
  if(oEvent.preventDefault)
    oEvent.preventDefault();
  if(oEvent.stopPropagation)
    oEvent.stopPropagation();
}

// Adds a JavaScript file to the document's head
function addJSScript(sURL) {
  var oHead          = document.getElementsByTagName('head')[0];
  var oScriptElement = document.createElement('script');
  var oScript        = document.getElementsByTagName('script')[0];

  oScriptElement.setAttribute('src',sURL);
  oScriptElement.setAttribute('type','text/javascript');

  if(oScript && oScript.parentNode.tagName.toLowerCase() == 'head')
    oHead.insertBefore(oScriptElement,oScript);
  else
    oHead.appendChild(oScriptElement);
}

//Adds an inline JavaScript code to the end of the document
function addInlineJSScript(sJavaScript) {
  var oBody            = document.getElementsByTagName('body')[0];
  var oScriptElement   = document.createElement('script');
  var oScriptContent   = document.createTextNode('<!--'+sJavaScript+'//-->');

  oScriptElement.setAttribute('type','text/javascript');
  oScriptElement.appendChild(oScriptContent);

  oBody.appendChild(oScriptElement);
}

function BrowserChecker()  {
  this.name = '';
  this.version = 0;
  this.isOpera = false;
  this.isFirefox = false;
  this.isIExplorer = false;

  var iVersion = 0;

  iVersion = getBrowserVersion('msie');
  if(iVersion != 0) {
    this.version = iVersion;
    this.name = 'msie';
    this.isIE = true;
  }

  if(this.version == 0) {
    iVersion = getBrowserVersion('firefox');
    if(iVersion != 0) {
      this.version = iVersion;
      this.name = 'firefox';
      this.isFirefox = true;
    }
  }

  if(this.version == 0) {
    iVersion = getBrowserVersion('opera');

    if(this.version != 0) {
      this.version = iVersion;
      this.name = 'opera';
      this.isOpera = true;
    }
  }

  function getBrowserVersion(searchKey) {
   var agt=navigator.userAgent.toLowerCase();
   var version = 0;

   if (searchKey=='msie' && agt.indexOf('opera')!=-1)
     return 0;

    var n = agt.indexOf(searchKey);
    if(n!=-1) {
      var sVersion = agt.substr(n+1+searchKey.length,4);
      try{version = parseFloat(sVersion)}catch(e){};
    }

    return version;    // return 0, if searchKey is not found in navigator.userAgent property
  }
}
//-----------------------------
function allowAJAX() {
  var browser = new BrowserChecker();
  
  if (browser.isIExplorer)    
    return browser.version >= 6.0;
  if (browser.isFirefox) 
    return browser.version >= 1.5;
  if (browser.isOpera)   
    return browser.version >= 8.5;

  return false;
}

/*
function callWebService(sURL,sXML) {
  var sRequestXML = Spry.Utils.encodeEntities(sXML);

  if(!Spry.Data) {
    addJSScript('/com/cfavatar/global/jscript/spry/xpath.js');
    addJSScript('/com/cfavatar/global/jscript/spry/SpryData.js');
  }

  return new Spry.Data.XMLDataSet(sURL,'/soapenv:Envelope/soapenv:Body/ns1:actionResponse',{method:'POST',postData:'<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:action soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://ws.demekon.de"><sActionXML xsi:type="xsd:string">'+sRequestXML+'</sActionXML></ns1:action></soapenv:Body></soapenv:Envelope>',headers:{'Content-Type':'text/xml; charset=utf-8','SOAPAction':'""'},useCache:false});
}
*/

function callWebService(sURL,sXML,oObserverFunction) {
  if(typeof Spry == 'undefined') {
    addJSScript('/com/cfavatar/global/jscript/spry/SpryData.js');
    addJSScript('/com/cfavatar/global/jscript/spry/xpath.js');
  }

  var sRequestXML = Spry.Utils.encodeEntities(sXML);
  var dsDataSource = new Spry.Data.XMLDataSet(sURL,'/soapenv:Envelope/soapenv:Body/ns1:actionResponse',{method:'POST',postData:'<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:action soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://ws.demekon.de"><sActionXML xsi:type="xsd:string">'+sRequestXML+'</sActionXML></ns1:action></soapenv:Body></soapenv:Envelope>',headers:{'Content-Type':'text/xml; charset=utf-8','SOAPAction':'""'},useCache:false});
  dsDataSource.setColumnType('actionReturn','html');
  dsDataSource.addObserver(oObserverFunction);
  dsDataSource.loadData();
}

//-----------------------------
// set "wait" cursor for the given element ID(or for document.body, if ID is not defined)  
function waitCursor(id) {
  var el = (id?document.getElementById(id):document.body);
  el.style.cursor = "pointer";
  el.style.cursor = "wait";
}

// set "default" cursor for the given element ID (or for document.body, if ID is not defined)  
function normalCursor(id) {
  var el = (id?document.getElementById(id):document.body);
  el.style.cursor = "default";
}

function openAddressBook(contactUserID, sEncURL) {
  var url = '/com/cfavatar/minos/index.cfm?' + sEncURL + '&sTarget=CONTACT&contactUserID='+contactUserID;
  winContact= window.open(url,'winContact','width=400,height=500,scrollbars=yes,resizable=yes');
  winContact.focus();
}