// JavaScript Document
jQuery.validator.addMethod("barcode", function(value, element, param) {
	// convert passed barcode to an array
	var bc = (''+value).split('');
	// if a single (enc)oding type passed (in a string) then convert to an array, else copy the param to an (enc)oding array
	if (param.constructor == String) {
		var enc=[]; enc[0] = param;
	} else {
		var enc = param;
	}
	//determine barcode type depending on type allowed in validation and length of code
	for (var i=0; i<enc.length; i++) {
		var ean13 = (enc[i] == 'ean-13' && bc.length == 13) || ean13 ? true : false;
		var upca = (enc[i] == 'upc-a' && bc.length == 12) || upca ? true : false;
	}
	// loop through bar code, less last checksum character
	for (var i=0, cs=0, len=bc.length-1; i<len; ++i){
		if (ean13) {
			// EAN-13 format, if char mod 2 is zero, then add odd value to checksum, else add even value times three to checksum
			cs += (i%2==0)? + bc[i] : bc[i]*3;
		} else if (upca) {
			// UPC-A format, if char mod 2 is zero, then add odd value times three to checksum, else add even value to checksum
			cs += (i%2==0)? bc[i]*3 : + bc[i];
		} else {
			// format not recognised, or length is too short for format
			return this.optional(element);
			cs=-1;
		}
	}
	// mod checksum value with 10
	cs = cs%10;
	// if checksum does not equal zero checksum is ten minus checksum
	cs = (cs!=0)? 10-cs : cs;
	// return true if checksum equals last character in barcode (array), or return element for error
	return (cs==(bc[bc.length-1])) ? true : this.optional(element);
}, "Please enter a valid barcode.");

jQuery.validator.addMethod("postcode", function(value, element) {
	// Permitted letters depend upon their position in the postcode.
	var alpha1 = "[abcdefghijklmnoprstuwyz]";                       // Character 1
	var alpha2 = "[abcdefghklmnopqrstuvwxy]";                       // Character 2
	var alpha3 = "[abcdefghjkstuw]";                                // Character 3
	var alpha4 = "[abehmnprvwxy]";                                  // Character 4
	var alpha5 = "[abdefghjlnpqrstuwxyz]";                          // Character 5
	// Array holds the regular expressions for the valid postcodes
	var pcexp = new Array ();
	// Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
	pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1,2})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
	// Expression for postcodes: ANA NAA
	pcexp.push (new RegExp ("^(" + alpha1 + "{1}[0-9]{1}" + alpha3 + "{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
	// Expression for postcodes: AANA  NAA
	pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1}" + alpha4 +"{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
	// Exception for the special postcode GIR 0AA
	pcexp.push (/^(GIR)(\s*)(0AA)$/i);
	// Standard BFPO numbers
	pcexp.push (/^(bfpo)(\s*)([0-9]{1,4})$/i);
	// c/o BFPO numbers
	pcexp.push (/^(bfpo)(\s*)(c\/o\s*[0-9]{1,3})$/i);
	// Load up the string to check and trim it
	var postCode = value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
	// Assume we're not going to find a valid postcode
	var valid = false;
	// Check the string against the types of post codes
	for ( var i=0; i<pcexp.length; i++) {
		if (pcexp[i].test(postCode)) {
			// The post code is valid - split the post code into component parts
			pcexp[i].exec(postCode);
			// Copy it back into the original string, converting it to uppercase and
			// inserting a space between the inward and outward codes
			postCode = RegExp.$1.toUpperCase() + " " + RegExp.$3.toUpperCase();
			// If it is a BFPO c/o type postcode, tidy up the "c/o" part
			postCode = postCode.replace (/C\/O\s*/,"c/o ");
			// Load new postcode back into the form element
			valid = true;
			// Remember that we have found that the code is valid and break from loop
			break;
		}
	}
	// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
	return this.optional(element) || valid;
}, "Please enter a valid UK postcode.");