/* Standards compliant hyperlinks that open in a new window.

   <a href="http://example.url" rel="external">link text</a>
   ------------------------------------------------------------------------------------------------------------------------*/
   
   
   function FormValidation(formElem, errorArray) 
   {
       this.formElem = formElem;
       this.errorArray = errorArray;
       this.debug = false;
       this.strDebugMessage = "";
       
        
       this.ErrorMessage =  function (elem, value, error) 
       {
           this.elem = elem;
           this.value = value;
           this.error = error;
       };
   
       this.validateInput = function(formValidationObj,inputElem, inputName, inputValue)
       {
           
           inputValue = TrimString(inputValue);
           //console.log(inputValue);
          
           //this.debugMessage("inputName = inputValue - "+inputName+" = "+inputValue);
           
           if(inputName.indexOf("usr_") > -1 || inputName.indexOf("xml_") > -1)
           {
               var nameParts = inputName.split("_");
               
               nameParts = nameParts.slice(0,4);
               
               var partLength = nameParts.length;
               
               if(partLength < 4 && partLength > 2 )
               {
                  
                   var strPrefix = nameParts[0].toLowerCase();
                   var strKeyType = nameParts[1].toLowerCase();
                    
                    switch (strPrefix) {
                        case "xml":
                        case "usr":
                            switch (strKeyType) {
                                   case "req":
                                        if(inputValue=="" || this.isString(inputValue)==false)
                                        {
                                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid value"));
                                        }                                       
                                        break;
                                    case "eml":
                                        if(inputValue=="" || this.isEmail(inputValue)== true)
                                        {
                                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid email"));
                                        }                       
                                    case "emlopt":
                                        if(inputValue!="" && this.isEmail(inputValue)== true)
                                        {
                                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid email"));
                                        }                           
                                        break;   
                                    case "std":
                                        if(inputValue!="" && this.isString(inputValue)==false)
                                        {
                                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid value"));
                                        }
									break;	
                                }
                                break;                        
                    }//end switch (strPrefix)
                   
             
             }//end if (partLength < 4 && partLength > 2 )
             else
             {
				//This must be a new style form name
				//TODO: again break this out to another method to keep it clean
				//concatenate the requirement and data type
				var strKeyType = nameParts[1].toLowerCase()+nameParts[2].toLowerCase();
				
				switch(strKeyType)
				{
					case "reqflt":
						if(inputValue=="" || this.isNumber(inputValue)==false)
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid number"));
                        }                                       
                        break;
                    case "reqfltrestricted":
						if(inputValue=="" || this.isNumber(inputValue)==false || inputValue < 5)
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid value (must be greater than 5)"));
                        }                                       
                        break;
                    case "reqfltrestricted5":
						if(inputValue.length > 0 && (this.isNumber(inputValue)==false || inputValue < 5))
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid value (must be 15 or more)"));
                        }                                       
                        break;    
					case "reqint":
						if(inputValue=="" || this.isNumber(inputValue)==false)
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid number"));
                        }                                       
                        break;                   
					case "reqxml":
					case "reqmult": //TODO: What is a mult?
					case "reqstr":                        
						if(inputValue=="" || this.isString(inputValue)==false)
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid value"));
                        }       
						break;
					case "reqeml":
						if(inputValue=="" || this.isEmail(inputValue)== true)
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid email"));
                        } 
						break;
					case "reqbool":
						//standard boolean
						var arBoolValsSTD = new Array("true","false","yes","no","1","0","on","off"); 
                        var validBool = false;
						for(var m = 0;m< arBoolValsSTD.length;m++)
						{
							if(inputValue == arBoolValsSTD[m])
							{
								validBool=true;
								break;							
							}
						}
						
					
						if (validBool==false)
						{							
							formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid value"));
						}
                        break;
					case "stdflt":
						if(inputValue!="" && this.isNumber(inputValue)==false)
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid number"));
                        }                                       
                        break;
					case "stdint":
						if(inputValue!="" && this.isNumber(inputValue)==false)
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid number"));
                        }                                       
                        break;
					case "stdxml":						
					case "stdstr":
						if(inputValue!="" && this.isString(inputValue)==false)
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid value"));
                        }
                        break;
					case "stdeml":
						if(inputValue!="" &&  (this.isEmail(inputValue)== false || this.isEmailValid(inputValue) == false))
                        {
                            formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid email"));
                        }
						break;
					case "stdbool":
						//standard boolean
						var arBoolValsSTD = new Array("true","false","yes","no","1","0","on","off"); 
                        var validBool = false;
						for(var m = 0;m< arBoolValsSTD.length;m++)
						{
							if(inputValue == arBoolValsSTD[m] || inputValue == "")
							{
								validBool=true;
								break;							
							}
						}
						
						
						if (validBool==false)
						{							
							formValidationObj.errorArray.push(new formValidationObj.ErrorMessage(inputElem,inputValue,"Not a valid value"));
						}
						break;				
					
				}//end switch	
               
                 
           }//end else
           }//end if type
       };
       
        this.isString =  function(strValue)
        {
            //return (typeof strValue == 'string' && strValue != '' && isNaN(strValue));
            //this.debugMessage("strValue type - "+strValue+" = "+typeof strValue);
            return (typeof strValue == 'string' && strValue != '');
        };
        
        this.isNumber =  function(strValue)
        {
            return (!isNaN(strValue) && strValue != '');
        };
        
        this.isEmail =  function(strValue)
        {   
            //"\\S+?@\\S+?\\.\\S+?"
            //var objRE = /^[\w-\.\']{1,}\@([\da-zA-Z-]{1,}\.){1,}[\da-zA-Z-]{2,}$/; 
            var objRE = /^.+@.+\..{2,3,4,6}$/;
            return (strValue != '' && objRE.test(strValue));
        };
        
        this.isEmailValid =  function(strValue)
        {  
            var illegalChars= /[\(\)\<\>\,\;\:\\\/\"\[\]]/
            if (strValue.match(illegalChars)) {
                return false;         
            }
            else
            {
                return true;
            }
        };
        
       this.displayErrors =  function()
       {
            var errorString = "";
            //offsetHeight
            var minOffsetHeight = 0;
            var firstInput = null;
            for (var l = 0; l < this.errorArray.length; l++) 
            {  
                var errorObj = this.errorArray[l];                
                var inputError= errorObj.error;
                var inputValue = errorObj.value;
                var inputElem =errorObj.elem;
                var inputName = inputElem.getAttribute("name");
                var parentElem = inputElem.parentNode;
                var errorEM = document.createElement('em'); 
                var inputElemoffsetTop = inputElem.offsetTop;
                //var inputElemoffsetTop = inputElem.tabIndex;
                if(inputElemoffsetTop < minOffsetHeight || minOffsetHeight == 0 )
                {
                    minOffsetHeight = inputElemoffsetTop;
                    firstInput = inputElem;
                    
                }
                
                errorEM.setAttribute("class","error");
                errorEM.appendChild(document.createTextNode("* "+inputError));
                
                parentElem.insertBefore(errorEM,inputElem);
            }
            
            firstInput.focus();
          
       };
       
       this.removeError = function (elem)
       {
           if(elem.getAttribute("name")!=null)
           {
               var inputName = elem.getAttribute("name");
               if(inputName.indexOf("usr_") > -1 || inputName.indexOf("xml_") > -1 && elem.hasChildNodes())
               {
                this.debugMessage("removing error from - "+inputName);
                
                var parentElem = elem.parentNode;  
                //this.debugMessage(elem.getAttribute("name")+" parentElem.innerHTML - \n"+parentElem.innerHTML);
                var emArray  = parentElem.getElementsByTagName('em'); // should only be 
                for (var i = 0; i < emArray.length; i++) 
                {               
                   if(emArray[i] != null)
                   {
                     emArray[i].parentNode.removeChild(emArray[i]);
                   }
                }
                }
           }
       };
       
       this.debugMessage = function(message)
       {
           if(this.debug==true)
           {
               console.log(message);
               this.strDebugMessage += "\n"+message;
               //alert(this.strDebugMessage);
           }

       };
   }//end FormValidation class
   
    function TrimString(sInString) {
        sInString = sInString.replace( /^\s+/g, "" );// strip leading
        return sInString.replace( /\s+$/g, "" );// strip trailing
    }

   
   function validateForm(formElem){
        
        var errorArray = new Array();
        
        var formValidationObj = new FormValidation(formElem,errorArray);
       
        formValidationObj.debugMessage("--------------------------------------------");
        var arInputs = formElem.getElementsByTagName('input');
        var arSelects = formElem.getElementsByTagName('select');
        var arTextareas = formElem.getElementsByTagName('textarea');
        
        
       
        for (var i = 0; i < arInputs.length; i++) 
        {    
            var inputElem = arInputs[i];
            formValidationObj.removeError(inputElem);
            if(inputElem.getAttribute("name") != null && TrimString(inputElem.getAttribute("name"))!=""  &&  inputElem.getAttribute("value") != null )
            {
                var inputName= inputElem.getAttribute("name");
                var inputValue = inputElem.value;
                //check if it's required
                //formValidationObj.debugMessage("inputName - "+inputName+" = "+ inputValue);
                formValidationObj.validateInput(formValidationObj,inputElem, inputName, inputValue);
                
            }
        
        }
        
        for (var j = 0; j < arSelects.length; j++) 
        {    
            
            var selectElem = arSelects[j];
            formValidationObj.removeError(selectElem);
            var selectedElem = selectElem.options[selectElem.selectedIndex]
            if(selectElem.getAttribute("name") != null && TrimString(selectElem.getAttribute("name"))!=""  &&  selectedElem.getAttribute("value") != null )
            {
                var inputName= selectElem.getAttribute("name");
                var inputValue = selectedElem.value;
                //formValidationObj.debugMessage("inputName - "+inputName+" = "+ inputValue);
                formValidationObj.validateInput(formValidationObj,selectElem, inputName, inputValue);
              
            }
        
        }
        
        for (var k = 0; k < arTextareas.length; k++) 
        {    
            var textareaElem = arTextareas[k];
            formValidationObj.removeError(textareaElem);
            if(textareaElem.getAttribute("name") != null && TrimString(textareaElem.getAttribute("name"))!=""  && textareaElem.innerHTML != null )
            {
                var inputName= textareaElem.getAttribute("name");
                var inputValue = textareaElem.innerHTML;
                if(TrimString(inputValue)=="")
                {
                    inputValue =textareaElem.value;
                }               
                //formValidationObj.debugMessage("inputName - "+inputName+" = "+ inputValue);
                formValidationObj.validateInput(formValidationObj,textareaElem, inputName, inputValue);
            
            }
        
        }
        
        
        //check all of the form fileds to check for req values
        if(formValidationObj.errorArray.length > 0)
        {
            formValidationObj.displayErrors();
            formValidationObj.errorArray = new Array();          
            return false;
        }
        else
        {            
            return true;   
        }
   };
  
   
   function loadFormValidation(){  
           
           var arA = document.getElementsByTagName('form');
      
           for (var i = 0; i < arA.length; i++) 
           {
               arA[i].onsubmit = function()
               {
                   return validateForm(this);
               }
        
           }
         
   };
   
   
   
  addLoadListener(loadFormValidation);
   
  
   
   
