﻿var regEmail = new RegExp( "^(([^<>()\\[\\]\\\\,;:@\"\\x00-\\x20\\x7F]|\\\\.)+)@(([a-z0-9-]|#\\d+?)*([a-z0-9]|#\\d+?)\\.)+([a-z]{2,4})$" );
var regPhone = new RegExp( /^\+?\d+[-\s\d]*\d+$/ );

// This should be set to true if you wish to alert the user with a div text surrounded by a shadow.
var alertShadow = false;

function Validator(){};

Validator.ValidateNotEmpty = function( fields, placename, alertText )
{
    return Validator.ValidateArray( fields, placename, alertText, 'notempty' );
}

Validator.ValidateNumeric = function( fields, placename, alertText )
{
    return Validator.ValidateArray( fields, placename, alertText, 'numeric' );
}
    
Validator.ValidateEmail = function( fields, placename, alertText )
{
    return Validator.ValidateArray( fields, placename, alertText, 'email' );
}
    
Validator.ValidatePhone = function( fields, placename, alertText )
{
    return Validator.ValidateArray( fields, placename, alertText, 'phone' );
}

Validator.ValidateArray = function( fields, placename, alertText, type )
{
    var errors = 0;
    var isValid = true;	
	var currField = null;
	var arrayLength = fields.length;
	var firstFieldMissing;
	
	for( var i=0; i < arrayLength && isValid; i++ )
	{
		currField = document.getElementById( placename + fields[ i ] );
		// if field is empty try without the placeholder
		if(!currField) currField = document.getElementById( fields[ i ] );
		if( currField && (
		(type == 'notempty' && ( currField.value == "" || currField.value <= 0 )) ||
		(type == 'numeric' && !Validator.IsNumeric(currField.value)) ||
		(type == 'email' && !Validator.IsValidEmail(currField.value)) ||
		(type == 'phone' && !Validator.IsValidPhone(currField.value))))		
		{
		    // if first field is set then we do not set the next one.
		    firstFieldMissing = (firstFieldMissing ? firstFieldMissing : currField);
			Validator.SetErrorValues( currField );
			errors++;		
		}	
	}
	
	if(errors > 0) isValid = false;
    if(!alertShadow && !isValid) Validator.CreateAlert( firstFieldMissing, alertText );
    if(alertShadow) return errors;
    else return isValid;
}

Validator.ValidateCheckbox = function( elem, alertText )
{
    var errors = 0;
    var isValid = true;
    if(!elem.checked)
    {
			Validator.SetErrorValues( elem );
			errors++;		
	}
	
    if(errors > 0) isValid = false;
    if(!alertShadow && !isValid) Validator.CreateAlert( elem, alertText );
    if(alertShadow) return errors;
    else return isValid;
}

// Elem is the field that should be highlighted in case of error
Validator.ValidateDate = function( day, month, year, elem, alertText )
{   
    var errors = 0;
    var isValid = true;
    
    if((day < 1 || day > 31) || (month < 1 || month > 12))
    {
        Validator.SetErrorValues( elem );
        errors++;
    }
    
    if(errors > 0) isValid = false;
    if(!alertShadow && !isValid) Validator.CreateAlert( elem, alertText );
    if(alertShadow) return errors;
    else return isValid;
    
    var daysInFeb = Validator.DaysInFebruary(year);
    if(isValid && (month == 2 && day > daysInFeb) )
    {
        Validator.SetErrorValues( elem );
        errors++;
    }
    
    if(errors > 0) isValid = false;
    if(!alertShadow && !isValid) Validator.CreateNoSelectAlert( elem, alertText );
    if(alertShadow) return errors;
    else return isValid;
}

// --------------------------------------------------------------------------------
// Generic functions
// --------------------------------------------------------------------------------

Validator.AlertShadow = function( errors, alertDivName, shadowDivName, placename)
{
    var alertDiv, shadowDiv;
    if( errors > 0 )
    {
        alertDiv = (document.getElementById(alertDivName) ? document.getElementById(alertDivName) : document.getElementById(placename + alertDivName));
        shadowDiv = (document.getElementById(shadowDivName) ? document.getElementById(shadowDivName) : document.getElementById(placename + shadowDivName));
        
        if(!alertDiv || !alertShadow)
        {
            alert("Error: " + alertDivName + " or " + shadowDivName + " could not be found.");
            return false;
        }
        
        alertDiv.style.display = 'block';
        shadowDiv.style.display = 'block';
        return false;
    }

    return true;
}

Validator.SetErrorValues = function(elem)
{
    elem.style.backgroundColor = "#fcffcd";
    elem.onkeydown = function(){elem.style.backgroundColor = '';elem.onkeydown = null;}
	elem.onchange = function(){elem.style.backgroundColor = '';elem.onchange = null;}
}

Validator.IsValidEmail = function( email )
{
	return regEmail.test( email );
}

Validator.IsValidPhone = function( phone )
{
    return regPhone.test( phone );
}

Validator.CreateAlert = function( elem, alertText )
{
    elem.select();
    Validator.Alerting( alertText );
}

Validator.CreateNoSelectAlert = function( elem, alertText )
{
    elem.focus();
    Validator.Alerting( alertText );
}

Validator.Alerting = function( alertText )
{
    alert( alertText );
}

// ===========================================================================================
// Validator.IsNumeric( input ).
// ===========================================================================================

Validator.IsNumeric = function( validateMe )
{
	var validChars = "0123456789";
	var isNumber = true;
	var currChar;
	
	for ( i = 0; i < validateMe.length && isNumber == true; i++) 
	{ 
		currChar = validateMe.charAt(i); 
		if ( validChars.indexOf( currChar ) == -1) 
		isNumber = false;
	}
	return isNumber;  
}

Validator.DaysInFebruary = function(year)
{
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
