/*
 * Lazy Load - jQuery plugin for lazy loading images
 *
 * Copyright (c) 2007-2009 Mika Tuupola
 *
 * Licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Project home:
 *   http://www.appelsiini.net/projects/lazyload
 *
 * Version:  1.4.0
 *
 */
(function($) {

	$.fn.lazyload = function(options) {
		var settings = {
			threshold : 0,
			failurelimit : 0,
			event : "scroll",
			effect : "show",
			container : window
		};

		if (options) {
			$.extend(settings, options);
		}

		/* Fire one scroll event per scroll. Not one scroll event per image. */
		var elements = this;
		if ("scroll" == settings.event) {
			$(settings.container).bind(
					"scroll",
					function(event) {
						var counter = 0;
						elements.each(function() {
							if (!$.belowthefold(this, settings)
									&& !$.rightoffold(this, settings)) {
								$(this).trigger("appear");
							} else {
								if (counter++ > settings.failurelimit) {
									return false;
								}
							}
						});
						/*
						 * Remove image from array so it is not looped next
						 * time.
						 */
						var temp = $.grep(elements, function(element) {
							return !element.loaded;
						});
						elements = $(temp);
					});
		}

		return this
				.each(function() {
					var self = this;
					/* TODO: use .data() instead of .attr() */
					$(self).attr("original", $(self).attr("src"));
					if ("scroll" != settings.event
							|| $.belowthefold(self, settings)
							|| $.rightoffold(self, settings)) {
						if (settings.placeholder) {
							$(self).attr("src", settings.placeholder);
						} else {
							$(self).removeAttr("src");
						}
						self.loaded = false;
					} else {
						self.loaded = true;
					}

					/* When appear is triggered load original image. */
					$(self)
							.one(
									"appear",
									function() {
										if (!this.loaded) {
											$("<img />")
													.bind(
															"load",
															function() {
																$(self)
																		.hide()
																		.attr(
																				"src",
																				$(
																						self)
																						.attr(
																								"original"))[settings.effect]
																		(settings.effectspeed);
																self.loaded = true;
															})
													.attr(
															"src",
															$(self).attr(
																	"original"));
										}
										;
									});

					/* When wanted event is triggered load original image */
					/* by triggering appear. */
					if ("scroll" != settings.event) {
						$(self).bind(settings.event, function(event) {
							if (!self.loaded) {
								$(self).trigger("appear");
							}
						});
					}
				});

	};

	/* Convenience methods in jQuery namespace. */
	/* Use as $.belowthefold(element, {threshold : 100, container : window}) */

	$.belowthefold = function(element, settings) {
		if (settings.container === undefined || settings.container === window) {
			var fold = $(window).height() + $(window).scrollTop();
		} else {
			var fold = $(settings.container).offset().top
					+ $(settings.container).height();
		}
		return fold <= $(element).offset().top - settings.threshold;
	};

	$.rightoffold = function(element, settings) {
		if (settings.container === undefined || settings.container === window) {
			var fold = $(window).width() + $(window).scrollLeft();
		} else {
			var fold = $(settings.container).offset().left
					+ $(settings.container).width();
		}
		return fold <= $(element).offset().left - settings.threshold;
	};

	/* Custom selectors for your convenience. */
	/* Use as $("img:below-the-fold").something() */

	$
			.extend(
					$.expr[':'],
					{
						"below-the-fold" : "$.belowthefold(a, {threshold : 0, container: window})",
						"above-the-fold" : "!$.belowthefold(a, {threshold : 0, container: window})",
						"right-of-fold" : "$.rightoffold(a, {threshold : 0, container: window})",
						"left-of-fold" : "!$.rightoffold(a, {threshold : 0, container: window})"
					});

})(jQuery);
