Object.extend(Tapestry.Validator, {
    sameas: function(field, message, constraint) {
        field.addValidator(function(value)
        {
            var constraintField = $(constraint);

            if (constraintField == null) {
                console.error("No such field: " + constraint);
                return;
            } else if (value != constraintField.value) {
                throw message;
            }
        });
    },
    
    sameascaseinsensitive: function(field, message, constraint) {
        field.addValidator(function(value)
        {
            var constraintField = $(constraint);
            var lowerCaseValue = value.toLowerCase();
            var lowerCaseConstraint = constraintField.value.toLowerCase();

            if (constraintField == null) {
                console.error("No such field: " + constraint);
                return;
            } else if (lowerCaseValue != lowerCaseConstraint) {
                throw message;
            }
        });
    },

    notsameas: function(field, message, constraint) {
        field.addValidator(function(value)
        {
            var confirmationSourceField = $(constraint);
            if (confirmationSourceField == null) {
                console.error("No such field: " + constraint);
                return;
            } else if (value == confirmationSourceField.value) {
                throw message;
            }
        });
    },
    dob : function(field, message) {
    	field.addValidator(function(value)
    	{
            var dmy = value.split(/\//);

            var year = dmy[2];
            var day = dmy[0];
            var month = dmy[1];

            if(dmy.length != 3) {
                 throw message;
            } else {
	            if(day.length == 0 || month.length == 0 || year.length == 0) {
	                throw message;
	            }
            }

            var daysInMonth = new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
		    if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
			    daysInMonth[2] = 29;
            }

            if (day>daysInMonth[parseInt(month,10)]) {
                throw message;
            }
        });
    },
    checked: function(field, message) {
        $(field).getFieldEventManager().requiredCheck = function (value) {
            if (value != 'on') {
                $(field).showValidationMessage(message);
            }
        };
    },
    cardnumber : function(field, message) {
        field.addValidator(function(value) {
            var number = value.replace(/\D/g, '');

            // Set the string length and parity
            var number_length = number.length;
            var parity = number_length % 2;

            // Loop through each digit and do the maths
            var total = 0;
            
            if  (number_length < 13 || number_length > 23) {
            	//The control over the length as to throw a different message and hence will be passed to the next validator
            	return;
            }
            
            for (i = 0; i < number_length; i++) {
                var digit = number.charAt(i);
                // Multiply alternate digits by two
                if (i % 2 == parity) {
                    digit = digit * 2;
                    // If the sum is two digits, add them together (in effect)
                    if (digit > 9) {
                        digit = digit - 9;
                    }
                }
                // Total up the digits
                total = total + parseInt(digit);
            }

            // If the total mod 10 equals 0, the number is valid
            if (total % 10 != 0) {
                throw message;
            } 
        });
    },
    carddate : function(field, message, constraint) {
    	field.addValidator(function(value)
    	{
    		var month = $F('month');
    		var year = $F('year');
    		if(month == '' || year == '') {
    			throw message;
    		}
    	});
    },
    blacklistedcountry: function(field, message, constraint) {
        field.addValidator(function(value)
        {
			for (var blacklistedCountry in constraint) {
				if(value == constraint[blacklistedCountry]){
					throw message;
				}
			}
        });
    },
    
    referrername: function(field, message, constraint) {
    	field.addValidator(function(value)  {
    		var emailRegex = new RegExp(constraint[0]);
			var usernameRegex = new RegExp(constraint[1]);
			
			if(!emailRegex.test(value) && !usernameRegex.test(value)) {
				throw message;
			}
    		
    	});
    },

    optionalfield : function(field, message) {
        field.addValidator(function(value) {
            if (value === '') {
                throw message;
            }
        });
    }
});

