/*
/
/	Charming Charlie
/	abstracted utilities for site-wide reuse
/
/
 */

/*
 /	ImagePreloader
 /
 /	Accepts an array of any number of images to load into cache prior to callback execution. Sets an array of jquery-wrapped 
 /   img elements that can be read through the parameter of the callback or property of the instance of this, 
 /	and added to HTML easily by append(), etc...
 /
 /	
 / 	Constructor Params:
 /	imgPathArray		Array of image url strings to preload
 /	callBack			Function accepting the constructed instance as a parameter
 /	
 /   Public Properties:
 /	imageElements		Array of jquery-wrapped img elements respectively positioned to input array of paths
 /	
 /
 */

var ImagePreloader = function(imgPathArray, callBack) {
	var _this = this;
	var imagePaths = imgPathArray;
	var imageCount = 0;
	this.imagesLoaded = [];

	if (imagePaths.length > 0) {
		for (i = 0; i < imagePaths.length; i++) {
			this.imagesLoaded.push($('<img />').attr('src', imagePaths[i]));
			$('<img />').attr('src', imagePaths[i]).one('load', function() {
				imageCount++;
				checkLoad(imagePaths.length)
			}).each(function() {
				// ensures event will fire for cached images
				if (this.complete)
					$(this).load();
			});
		}
	} else {
		callBack([]);
	}

	function checkLoad(targetCount) {
		if (imageCount == targetCount) {
			callBack(_this);
		}
	}

}

/*
 * / GridRevealer / / Requires a jQuery object with references to image elements
 * to animate into view via a centered scale effect. / Requires a second jQuery
 * object that is the container of all of the grid layout elements / Has both
 * revealEm and hideEm methods to do exactly that. Fires a callback on
 * completion of the entire animation / of all images. / / Constructor Params: /
 * imgJObj jQuery object wrapping all the images elements find in the grid's
 * layout divs / gridJObj jQuery object wrapping the container div housing the
 * whole layout / / Public Methods: / revealEm(callBack) Executes callback on
 * animation completion / hideEm(callBack) Executes callback on animation
 * completion /
 */

var GridRevealer = function(imageJObj, gridJObj) {
	var _this = this;
	var _imageJObj = imageJObj;
	var _gridJObj = gridJObj;
	var animCompleteCount = 0;
	var revealParams = {
		percent : 100,
		easing : "easeOutQuart",
		origin : [ 'middle', 'center' ]
	};
	var hideParams = {
		percent : 0,
		easing : "easeInQuart",
		origin : [ 'middle', 'center' ]
	};

	_imageJObj.hide();

	this.revealEm = function(callBack) {
		delaytime = 0;
		_gridJObj.css('visibility', 'visible');
		_imageJObj.each(function() {
			$(this).delay(delaytime).show("scale", revealParams, 400,
					function() {
						completeHandler(callBack);
					});
			delaytime += 50;
		});
	}

	this.hideEm = function(callBack) {
		delaytime = 0;
		_imageJObj.each(function() {
			$(this).delay(delaytime).hide("scale", hideParams, 300, function() {
				completeHandler(callBack, true);
			});
			delaytime += 50;
		});
	}

	function completeHandler(callBack, hideCalled) {
		animCompleteCount++;
		if (animCompleteCount == _imageJObj.length) {
			animCompleteCount = 0;
			if (hideCalled)
				_gridJObj.css('visibility', 'hidden');
			callBack();
		}
	}

}

/*
 * / CartDisplay / / Simple tool to encapsulate functions around revealing the
 * footer mini-cart / / Constructor Params: / /
 */

var CartDisplay = function(cartPanelJObj, openButtonJObj, buttonViewedClass,
		cartClosedY, cartOpenY, cartReadyCallback) {
	var cartOpen = false;
	var _cartPanel = cartPanelJObj;
	var _openButton = openButtonJObj;
	var _buttonViewedClass = buttonViewedClass;
	var _cartClosedY = cartClosedY;
	var _cartOpenY = cartOpenY;

	_cartPanel.animate({
		bottom : _cartClosedY
	}, 400, "easeInOutQuart", function() {
		cartReadyCallback()
	});

	this.toggleCart = function(callBack) {
		if (cartOpen) {
			cartOpen = false;
			_openButton.removeClass(buttonViewedClass);
			_cartPanel.animate({
				bottom : _cartClosedY
			}, 400, "easeInOutQuart", function() {
				callBack();
			});
		} else {
			cartOpen = true;
			_openButton.addClass(buttonViewedClass);
			_cartPanel.animate({
				bottom : _cartOpenY
			}, 600, "easeInOutQuart", function() {
				callBack();
			});
		}
	}

	this.hideCart = function() {
		_cartPanel.animate({
			bottom : '-182px'
		}, 600, "easeInOutQuart", function() {
		});
	}

}

var KeyPressHandler = function() {
	function handleEnter(event, callBack) {
		if (event.keyCode == 13) {
			callBack();
			return false;
		}
		return true;
	}
	return {
		handleEnter : function(event, callBack) {
			return handleEnter(event, callBack);
		}
	}
}();
