/**
 * Albertsons Core
 * Version 1.0.0 - 11/22/2008
 * @author Benjamin Truyman
 **/

/**
 * Albertsons namespace
 **/
var ABS = {};

ABS.Common = {
	initialize: function () {
		// Allows for targeting CSS selectors for users with JavaScript enabled
		$('body').addClass('has_script');
	}
};

// Helper namespace
ABS.Helpers = {};

// Form Validation helper
ABS.Helpers.FormValidator = function (params) {
	var that = this;

	// Check for required values
	if (typeof params.form === 'undefined') {
		throw new Error('Form element must be defined.');
	}
	
	// Regular expression patterns
	this.patterns = {
		email: /([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4})/,
		trim: /^[ \t]+|[ \t]+$/,
		zip: /^\d{5}([\-]\d{4})?$/
	};
	
	// Validators
	this.hasMinLength = function (str, length) {
		if (str.length >= length) {
			return true;
		}
		return false;
	};
	
	this.hasMaxLength = function (str, length) {
		if (str.length <= length) {
			return true;
		}
		return false;
	};
	
	this.isEmail = function (str) {
		if (str.match(this.email) !== null) {
			return true;
		}
		return false;
	};
	
	this.isEmpty = function (str) {
		str = str.replace(this.patterns.trim, '');
		if (str !== '') {
			return true;
		}
		return false;
	};
	
	this.isZIP = function (str) {
		if (str.match(this.patterns.zip) !== null) {
			return true;
		}
		return false;
	};
	
	this.validate = function (dom, options) {
		// Get elements value
		var value = $(dom).val();
		
		// Begin checking options
		if (
				(options.email === true && !this.isEmail(value)) ||
				(typeof options.minLength !== 'undefined' && !this.hasMinLength(value, options.minLength)) ||
				(typeof options.maxLength !== 'undefined' && !this.hasMaxLength(value, options.maxLength)) ||
				(options.required === true && !this.isEmpty(value)) ||
				(options.zip === true && !this.isZIP(value))
			) {
			return false;
		}
		
		return true;
	};
	
	// Return validator object
	return {
		form: params.form,
		elements: params.elements,
		run: function () {
			var self = this;
			var returns = {
				areValid: true,
				elements: {
					failed: [],
					passed: []
				}
			};
			$(this.elements).each(function () {
				// Create temporary variable for current form element
				var element = $(self.form).find('[name="' + this.name + '"]').get(0);
				
				// Validate current element
				if (that.validate(element, this.options) === true) {
					returns.elements.passed.push(element);
				} else {
					returns.elements.failed.push(element);
				}
			});
			
			// Set entire form validation status (convenience variable)
			returns.areValid = returns.elements.failed.length > 0 ? false : true;
			
			return returns;
		}
	};
};

// Utility namespace
ABS.Utils = {};

// Event Delegate
ABS.Utils.Delegate = {
	create: function (obj, func) {
		return function (e) {
			e = e || {};
			// Forces currentTarget property of the Event object for browsers that don't correctly support it
			e.currentTarget = this;
			// Call function within context of specified object
			func.apply(obj, [e]);
		};
	}
};

// Image Preloader
ABS.Utils.ImagePreloader = {
	paths: [],
	
	add: function (path) {
		var that = this;
		if (typeof path === 'String') {
			this.paths.push(path);
		} else if (typeof path === 'object'){
			$(path).each(function () {
				that.paths.push(this);
			});
		}
	},
	
	load: function () {
		// Load images into empty elements
		$(this.paths).each(function () {
			jQuery('<img>').attr('src', this);
		});
		
		// Clear out paths cache
		this.paths = [];
	}
};

// Dummy event handler that prevents default event behavior
ABS.Utils.dummyEventHandler = function (e) {
	e.preventDefault();
};

$(document).ready(function () {
	// Initialize common methods
	ABS.Common.initialize();
	
	// Preload images
	ABS.Utils.ImagePreloader.add([
		'/img/common/backgrounds/store-finder-popup.png',
		'/img/common/backgrounds/store-finder-popup.gif',
		'/img/common/backgrounds/callout-short.png',
		'/img/common/backgrounds/callout-short.gif'
	]);
	ABS.Utils.ImagePreloader.load();
});