
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]*$/,

    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,
            securityCode:       true,
            expireMonth:        true,
            expireYear:         true
        },

		MAX_LENGTH_FIELDS :
		{
            securityCode: 3
        },

		MIN_LENGTH_FIELDS :
		{
            securityCode: 3
        },

		REGEXP_FIELDS :
		{
			cardNumber: RegularExpression.POSITIVE,
            securityCode: RegularExpression.POSITIVE
        },

        CONFIRM_FILEDS:
		{
		},

        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
                cardNumber : "Please enter Card Number.",
                expireMonth : "Please enter Expiry Date.",
                expireYear : "Please enter Expiry Date.",
                creditCardType: "Please specify Card Type.",
                securityCode: "Please enter Security Code."
            },
            MAX_LENGTH :
            {
                securityCode: "Security Code must be 3 characters long and can contain only digits."
            },
            MIN_LENGTH :
            {
                securityCode: "Security Code must be 3 characters long and can contain only digits."
            },
            INVALID :
            {
                cardNumber: "Card Number is invalid. Only digits allowed, please remove any spaces if present.",
                securityCode: "Security Code must be 3 characters long and can contain only digits."
            },
            CONFIRMATION :
            {
            }
        }
    },

	CustomerRegistration : {
		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 : 6
		},

		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 : false,

            REQUIRED :
            {
            },
            MAX_LENGTH :
            {
            },
            MIN_LENGTH :
            {

            },
            INVALID :
            {

            },
            CONFIRMATION :
            {
            }
        }
    },

	CustomerLogin : {

		REQUIRED_FIELDS :
		{
			userName:		true,
			password:		true
		},

		MAX_LENGTH_FIELDS :
		{
			userName:		16,
			password:		32
		},

		MIN_LENGTH_FIELDS :
		{
            userName:		3,
			password:		6
        },

		REGEXP_FIELDS :
		{
            password: RegularExpression.PASSWORD,
            username: RegularExpression.PASSWORD
        }
		,
		CONFIRM_FILEDS:
		{
		},

        ERROR_MESSAGES :
        {
            customized : false
        }
    },

	CustomerChangePassword : {
		REQUIRED_FIELDS :
		{
			currentPassword:    true,
			password:			true,
			confirmPassword:    true
		},

		MAX_LENGTH_FIELDS :
		{
			currentPassword:    32,
			password:	    	32,
			confirmPassword:    32
		},

		MIN_LENGTH_FIELDS :
		{
            currentPassword:    6,
			password:	    	6,
			confirmPassword:    6
        },

		REGEXP_FIELDS :
		{
            currentPassword:    RegularExpression.PASSWORD,
			password:	    	RegularExpression.PASSWORD,
			confirmPassword:    RegularExpression.PASSWORD
        },

        CONFIRM_FILEDS:
		{
		},

        ERROR_MESSAGES :
        {
            customized : false
        }
    },

	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: "Search string should not exceed 255 characters."
            },
            MIN_LENGTH :
            {
                ssv: "Search string should be at least 2 characters long."
            },
            INVALID :
            {
                ssv: "Search string contains disallowed characters."
            },
            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: "Please enter Promo Code."
            },
            MAX_LENGTH :
            {
                promoCode: "Promo Code should not exceed 32 characters."
            },
            MIN_LENGTH :
            {
            },
            INVALID :
            {
                promoCode: "Promo Code is invalid."
            },
            CONFIRMATION :
            {
            }
        }
    }
};

function getMessage(message, values)
{
    for (var i = 0; i < values.length; i++)
    {
        var holder = '{' + i + '}';
        var value = values[i];

        message = message.replace(holder, value);
    }

    return message;
}

function validateForm(form, validationDesc, errorOutput)
{
	var isValidate = true;
	var errorMessage = '';

    // trim element values
    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;
		}
        // use jQuery trim
        element.value = $.trim(element.value);
    }

    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;

        var prevLabel = getPreviousLabel(element);
		if (prevLabel != null)
		{
			fieldLabel = prevLabel.innerHTML;
		}

		if (isRequired && element.value == '')
		{
			isValidate = false;
            if (customMessage)
            {
                errorMessage = validationDesc.ERROR_MESSAGES.REQUIRED[element.name];
            }
            else
            {
                errorMessage = fieldLabel + ' ' + " is required.";
            }
			break;
		}
		if (maxLength != null)
		{
			if (element.value.length > maxLength)
			{
				isValidate = false;
                if (customMessage)
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.MAX_LENGTH[element.name];
                }
                else
                {
                    errorMessage = fieldLabel + ' ' + " should not exceed " + ' ' + maxLength + " characters.";
                }


				break;
			}
		}
		if (minLength != null)
		{
			if (element.value.length < minLength)
			{
				isValidate = false;
                if (customMessage)
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.MIN_LENGTH[element.name];
                }
                else
                {
                    errorMessage = fieldLabel + ' ' + " should be at least " + ' ' + minLength + " characters long.";
                }
				break;
			}
		}
		if (regExp != null)
		{
			if (element.value == null || element.value == '')
				continue;

			var match = element.value.match(regExp);
			if (! match)
			{
				isValidate = false;
                if (customMessage)
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.INVALID[element.name];
                }
                else
                {
                    errorMessage = fieldLabel + ' ' + " field is invalid";
                }
                break;
			}
		}
		if(confirmFields != null)
		{
			var confirmField = document.getElementsByName(confirmFields)[0];
            if (element.value != confirmField.value)
            {
                isValidate = false;
                var confirmationLabel = getPreviousLabel(confirmField).innerHTML;
                if (customMessage)
                {
                   errorMessage = getMessage(validationDesc.ERROR_MESSAGES.CONFIRMATION['all'],
                                             new Array(fieldLabel, confirmationLabel));
                }
                else
                {
                    errorMessage = fieldLabel + ' and ' + confirmationLabel + ' do not match.';
                }

                break;
            }
		}
	}
    if (! isValidate)
	{
		errorOutput.innerHTML = '<p class="error">' + errorMessage + '</p>';
	}
	return isValidate;
}
