function getPreviousLabel(node)
{
    var result = node.previousSibling;
    while (result != null &&
           result.tagName != "LABEL" &&
           result.tagName != "SPAN")
    {
        result = result.previousSibling;
    }
    return result;
}

var RegularExpression = {
    LATIN_1 : /^[\u0000-\u00ff]+$/,

    TEXT : /[A-Za-z0-9\-\_\ \.\,\(\)\[\]\+"']+/,

    NAME : /^[a-zA-Z '-]+$/,

    EMAIL : /^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/,

    POST_CODE : /^[a-zA-Z0-9 \-]+$/,

    ALPHA : /^[a-zA-Z ]+$/,

    ALPHANUMERIC : /^[-a-zA-Z0-9_ \-]+$/,

    PHONE : /^[0-9-() +]+$/,

    NUMBER : /(^\s*$|^\s*-?\s*\d+\s*$)/,

    POSITIVE: /^[0-9]*$/,
    
    CARD_NUMBER: /^\**[0-9]*$/,

    PASSWORD: /^[0-9a-zA-Z_]+$/,

    PROMOCODE: /^[A-Za-z0-9\-]+$/
};


var Validators = {

    CustomerInfo : {
        REQUIRED_FIELDS :
        {
            firstName:       true,
            lastName:         true,
            address1:        true,
            town:             true,
            postcode:         true,
            countryCode:     true,
            email:             true,
            phone:             true
        },

        MAX_LENGTH_FIELDS :
        {
            title:           64,
            firstName:         128,
            lastName:        128,
            address1:        255,
            address2:         255,
            town:             128,
            county:             50,
            countryCode:     32,
            postcode:         16,
            email:             255,
            phone:             50,
            fax:             50,
            company:         255
        },

        MIN_LENGTH_FIELDS :
        {
        },

        REGEXP_FIELDS :
        {
            email:             RegularExpression.EMAIL,
            phone:             RegularExpression.PHONE,
            firstName:       RegularExpression.LATIN_1,
            lastName:        RegularExpression.LATIN_1,
            title:           RegularExpression.LATIN_1,
            postcode:        RegularExpression.POST_CODE,
            address1:        RegularExpression.LATIN_1,
            address2:        RegularExpression.LATIN_1
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : false
        }
    },

    CreditCardDetails : {

        REQUIRED_FIELDS :
        {
            creditCardType:        true,
            cardNumber:            true,
            expireMonth:        true,
            expireYear:         true,
            securityCode:       true
        },

        MAX_LENGTH_FIELDS :
        {
            cardNumber: 19,
            securityCode: 3
        },

        MIN_LENGTH_FIELDS :
        {
            securityCode: 3
        },

        REGEXP_FIELDS :
        {
            cardNumber: RegularExpression.CARD_NUMBER,
            securityCode: RegularExpression.POSITIVE
        },

        CONFIRM_FILEDS:
        {
        },

        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
                cardNumber : getMessageByKey("requiredCardNumber"),
                expireMonth : getMessageByKey("requiredExpireMonth"),
                expireYear : getMessageByKey("requiredExpireYear"),
                creditCardType: getMessageByKey("requiredCreditCardType"),
                securityCode: getMessageByKey("requiredSecurityCode")
            },
            MAX_LENGTH :
            {
                cardNumber: getMessageByKey("maxLenCardNumber"),
                securityCode:getMessageByKey("maxlenSecurityCode")
            },
            MIN_LENGTH :
            {
                securityCode:getMessageByKey("minLenSecurityCode")
            },
            INVALID :
            {
                cardNumber: getMessageByKey("invalidCardNumber"),
                securityCode:getMessageByKey("invalidSecurityCode")
            },
            CONFIRMATION :
            {
            }
        }
    },

    CustomerRegistration : {
        NO_TRIM:
        {
            password: true,
            confirmPassword: true
        },

        REQUIRED_FIELDS :
        {
            userName:           true,
            password:            true,
            confirmPassword:    true,
            firstName:          true,
            lastName:           true,
            address1:           true,
            town:               true,
            postcode:            true,
            countryCode:        true,
            email:                true,
            confirmEmail:        true,
            phone:                true
            //			,confirmationCode:true
        },

        CONFIRM_FILEDS:
        {
            password: "confirmPassword",
            email : "confirmEmail"
        },

        MAX_LENGTH_FIELDS :
        {
            userName:        16,
            password:        32,
            confirmPassword:32,
            title:            64,
            firstName:        128,
            lastName:        128,
            company:    255,
            address1:     255,
            address2:     255,
            town:            128,
            county:            50,
            countryCode:    32,
            postcode:        16,
            email:            255,
            phone:             50,
            contactPhone:     50,
            fax:            50
            //			,confirmationCode:50
        },

        MIN_LENGTH_FIELDS :
        {
            userName: 3,
            password : 7
        },

        REGEXP_FIELDS :
        {
            email:             RegularExpression.EMAIL,
            phone:             RegularExpression.PHONE,
            firstName:       RegularExpression.LATIN_1,
            lastName:        RegularExpression.LATIN_1,
            title:           RegularExpression.LATIN_1,
            postcode:        RegularExpression.POST_CODE,
            userName:        RegularExpression.PASSWORD,
            password:        RegularExpression.PASSWORD,
            address1:        RegularExpression.LATIN_1,
            address2:        RegularExpression.LATIN_1,
            company:         RegularExpression.LATIN_1
        },

        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
            },
            MAX_LENGTH :
            {
            	password: getMessageByKey("maxLenPassword")
            },
            MIN_LENGTH :
            {
            	password: getMessageByKey("minLenPassword")
            },
            INVALID :
            {
            	password: getMessageByKey("ivalidPassword")
            },
            CONFIRMATION :
            {
            }
        }
    },

    CustomerLogin : {
        NO_TRIM:
        {
            password: true
        },

        REQUIRED_FIELDS :
        {
            userName:        true,
            password:        true
        },

        MAX_LENGTH_FIELDS :
        {
            userName:        16,
            password:        32
        },

        MIN_LENGTH_FIELDS :
        {
            userName:        3,
            password:        7
        },

        REGEXP_FIELDS :
        {
            password: RegularExpression.PASSWORD,
            username: RegularExpression.PASSWORD
        }
        ,
        CONFIRM_FILEDS:
        {
        },

        ERROR_MESSAGES :
        {
            customized : false
        }
    },

    CustomerChangePassword : {
        NO_TRIM:
        {
            currentPassword:    true,
            password: 			true,
            confirmPassword: 	true
        },

        REQUIRED_FIELDS :
        {
            currentPassword:    true,
            password:           true,
            confirmPassword:    true
        },

        MAX_LENGTH_FIELDS :
        {
            currentPassword:    32,
            password:           32,
            confirmPassword:    32
        },

        MIN_LENGTH_FIELDS :
        {
            password:           7
        },

        REGEXP_FIELDS :
        {
            password:           RegularExpression.PASSWORD
        },

        CONFIRM_FILEDS:
        {
        	 password: "confirmPassword"
        },

        ERROR_MESSAGES :
        {
            customized : true,
            
            REQUIRED :
            {
            },
            MAX_LENGTH :
            {
            	password: getMessageByKey("maxLenPassword")
            },
            MIN_LENGTH :
            {
            	password: getMessageByKey("minLenPassword")
            },
            INVALID :
            {
            	password: getMessageByKey("ivalidPassword")
            },
            CONFIRMATION :
            {
            }
        }
    },

    CustomerRemindPassword : {
        REQUIRED_FIELDS :
        {
            email: true,
            confirmationCode: true
        },

        MAX_LENGTH_FIELDS :
        {
            email: 255,
            confirmationCode: 50
        },

        MIN_LENGTH_FIELDS :
        {
        },

        REGEXP_FIELDS :
        {
            email:             RegularExpression.EMAIL
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : false
        }
    },

    Enquiry : {
        REQUIRED_FIELDS :
        {
            name:        true,
            email:        true,
            confirmationCode: true
        },

        MAX_LENGTH_FIELDS :
        {
            title:          64,
            name:           128,
            note:           2048,
            phone:          50,
            email:            255
        },

        MIN_LENGTH_FIELDS :
        {
        },

        REGEXP_FIELDS :
        {
            name:           RegularExpression.LATIN_1,
            phone:          RegularExpression.PHONE,
            email:            RegularExpression.EMAIL
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : false
        }
    },

    SearchProducts: {
        REQUIRED_FIELDS :
        {
        },

        MAX_LENGTH_FIELDS :
        {
            ssv:    255
        },

        MIN_LENGTH_FIELDS :
        {
            ssv:    2
        },

        REGEXP_FIELDS :
        {
            ssv: RegularExpression.LATIN_1
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
            },
            MAX_LENGTH :
            {
                ssv: getMessageByKey("maxLenSsv")
            },
            MIN_LENGTH :
            {
                ssv: getMessageByKey("minLenSsv")
            },
            INVALID :
            {
                ssv: getMessageByKey("invalidSsv")
            },
            CONFIRMATION :
            {
            }
        }
    },

    PromoCode : {
        REQUIRED_FIELDS :
        {
            promoCode:       true
        },

        MAX_LENGTH_FIELDS :
        {
            promoCode:       32
        },

        MIN_LENGTH_FIELDS :
        {
        },

        REGEXP_FIELDS :
        {
            promoCode: RegularExpression.PROMOCODE
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
                promoCode:getMessageByKey("requiredPromoCode")
            },
            MAX_LENGTH :
            {
                promoCode: getMessageByKey("maxLenPromoCode")
            },
            MIN_LENGTH :
            {
            },
            INVALID :
            {
                promoCode: getMessageByKey("invalidPromoCode")
            },
            CONFIRMATION :
            {
            }
        }
    }
};


function needToBeTrimmed(validationDesc, element)
{
    if (validationDesc.NO_TRIM != null && validationDesc.NO_TRIM != undefined)
    {
        if (validationDesc.NO_TRIM[element.name] != null && validationDesc.NO_TRIM[element.name] != undefined)
        {
            if (validationDesc.NO_TRIM[element.name])
            {
                return false;
            }
        }
    }

    return true;
}

function trimIfNecessary(validationDesc, element)
{
    if (needToBeTrimmed(validationDesc, element))
    {
        element.value = $.trim(element.value);
    }
}

function validateForm(form, validationDesc, errorOutput)
{
    var isValid = true;
    var errorMessage = '';

    for (var i = 0; i < form.elements.length; i++)
    {
        var element = form.elements[i];
        if (element.tagName != "INPUT" &&
            element.tagName != "SELECT" &&
            element.tagName != "TEXTAREA")
        {
            continue;
        }

        var fieldLabel = '';
        var isRequired = validationDesc.REQUIRED_FIELDS[element.name];
        var maxLength = validationDesc.MAX_LENGTH_FIELDS[element.name];
        var minLength = validationDesc.MIN_LENGTH_FIELDS[element.name];
        var regExp = validationDesc.REGEXP_FIELDS[element.name];
        var confirmFields = validationDesc.CONFIRM_FILEDS[element.name];
        var customMessage = validationDesc.ERROR_MESSAGES.customized;

        trimIfNecessary(validationDesc, element);

        var prevLabel = getPreviousLabel(element);
        if (prevLabel != null)
        {
            fieldLabel = prevLabel.innerHTML;
        }

        if (isRequired && element.value == '')
        {
            isValid = false;
            if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.REQUIRED[element.name]))
            {
                errorMessage = validationDesc.ERROR_MESSAGES.REQUIRED[element.name];
            }
            else
            {
                errorMessage = getMessageByKey("isRequired",new Array(fieldLabel));
            }
            break;
        }
        if (maxLength != null && isValid)
        {
            if (element.value.length > maxLength)
            {
                isValid = false;
                if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.MAX_LENGTH[element.name]))
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.MAX_LENGTH[element.name];
                }
                else
                {
                    errorMessage = getMessageByKey("shouldNotExceed", new Array(fieldLabel, maxLength));
                }


                break;
            }
        }
        if (minLength != null && isValid)
        {
            if (element.value.length < minLength)
            {
                isValid = false;
                if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.MIN_LENGTH[element.name]))
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.MIN_LENGTH[element.name];
                }
                else
                {
                    errorMessage = getMessageByKey("shouldBeAtLeast", new Array(fieldLabel, minLength));
                }
                break;
            }
        }
        if (regExp != null && isValid)
        {
            if (element.value == null || element.value == '')
                continue;

            var match = element.value.match(regExp);
            if (! match)
            {
                isValid = false;
                if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.INVALID[element.name]) )
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.INVALID[element.name];
                }
                else
                {
                    errorMessage = getMessageByKey("isInvalid", new Array(fieldLabel));
                }
                break;
            }
        }
        if (confirmFields != null && isValid)
        {
            var confirmField = document.getElementsByName(confirmFields)[0];
            if (needToBeTrimmed(validationDesc, element))
            {
                confirmField.value = $.trim(confirmField.value);
            }

            if (element.value != confirmField.value)
            {
                isValid = false;
                var confirmationLabel = getPreviousLabel(confirmField).innerHTML;
                if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.CONFIRMATION['all']) )
                {
                    errorMessage = getMessage(validationDesc.ERROR_MESSAGES.CONFIRMATION['all'],
                            new Array(fieldLabel, confirmationLabel));
                }
                else
                {
                    errorMessage = getMessageByKey("doNotMatch", new Array(fieldLabel, confirmationLabel));
                }

                break;
            }
        }
    }
    if (! isValid)
    {
        errorOutput.innerHTML = '<p class="error">' + errorMessage + '</p>';
    }
    return isValid;
}

