/*!
*  JqueryAsynchImageLoader (JAIL) : plugin for jQuery
*
* Developed by
* Sebastiano Armeli-Battana (@sebarmeli) - http://www.sebastianoarmelibattana.com
* Dual licensed under the MIT or GPL Version 3 licenses.
*/
/*
	Copyright (c) 2011 Sebastiano Armeli-Battana (http://www.sebastianoarmelibattana.com)

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * Code changed by isys marginally
 */

/*globals window,jQuery,setTimeout,clearTimeout */
(function($){
	var $window = $(window);

	$.fn.asynchImageLoader = $.fn.jail = function(options) {

		// Configuration
		options = $.extend({
			timeout : 10,
			effect : false,
			speed : 400,
			selector: null,
			offset : 0,
			event : 'load+scroll',
			callback : jQuery.noop,
			placeholder : false
		}, options);

		var images = this;

		// Store the selector into 'triggerEl' data for the images selected
		this.data('triggerEl', (options.selector) ? $(options.selector) : $window);

		// Use a placeholder in case it is specified
		if (options.placeholder !== false) {
			images.each(function(){
                var att = $(this).attr("longdesc");

                var atts = att.split("*");
                if(atts.length >= 3){
                    if(atts[1] >= 0){
//                        $(this).attr("width", atts[1]);
                    }
                    if(atts[2] >= 0){
//                        $(this).attr("height", atts[2]);
                    }
                }
                if(atts.length >= 4){
                   $(this).attr("src", atts[3]);
                }
                else{
                    $(this).attr("src", options.placeholder);
                }
            });
		}

		// When the event is not specified the images will be loaded with a delay
		if(/^load/.test(options.event)) {
			$.asynchImageLoader.later.call(this, options);
		} else {
			$.asynchImageLoader.onEvent.call(this, options, images);
		}

		return this;
	};

	// Methods cointaing the logic
	$.asynchImageLoader = {

		// Remove any elements that have been loaded from the jQuery stack.
		// This should speed up subsequent calls by not having to iterate over the loaded elements.
		_purgeStack : function(stack) {
			var i = 0;

			while(true) {
				if(i === stack.length) {
					break;
				} else {
					if(stack[i].getAttribute('longdesc')) {
						i++;
					} else {
						stack.splice(i, 1);
					}
				}
			}
		},

		// Load the image - after the event is triggered on the image itself - no need
		// to check for visibility
		_loadOnEvent : function(e) {
			var $img = $(this),
			options = e.data.options,
			images = e.data.images;

			// Load images
			$.asynchImageLoader._loadImage(options, $img);

			// Image has been loaded so there is no need to listen anymore
			$img.unbind( options.event, $.asynchImageLoader._loadOnEvent );

			//Callback call
			options.callback.call(this, options);

			$.asynchImageLoader._purgeStack( images );
		},

		// Load the image - after the event is triggered by a DOM element different
		// from the images (options.selector value) or the event is "scroll" -
		// visibility of the images is checked
		_bufferedEventListener : function(e) {
			var images = e.data.images,
			options = e.data.options,
			triggerEl = images.data('triggerEl');

			clearTimeout(images.data('poller'));
			images.data('poller', setTimeout(function() {
				images.each(function _imageLoader(){
					$.asynchImageLoader._loadImageIfVisible(options, this, triggerEl);
				});

				$.asynchImageLoader._purgeStack( images );

				options.callback.call(this, options, images);
			}, options.timeout));

			return false;
		},

		// Images loaded triggered by en event (event different from "load" or "load+scroll")
		onEvent : function(options, images) {
			images = images || this;

			if (options.event === 'scroll' || options.selector) {
				var triggerEl = images.data('triggerEl');

				if(images.length > 0) {

					// Bind the event to the selector specified in the config obj
					triggerEl.bind( options.event, { images:images, options:options }, $.asynchImageLoader._bufferedEventListener );

					if (options.event === 'scroll' || !options.selector) {
						$window.resize({ images:images, options:options }, $.asynchImageLoader._bufferedEventListener );
					}
				} else {

					// Unbind the event to the selector specified in the config obj since there is nothing left to do
					var initalTriggerEl = (options.selector) ? $(options.selector) : $window;
					initalTriggerEl.unbind( options.event, $.asynchImageLoader._bufferedEventListener );
				}
			} else {
				// Bind the event to the images
				images.bind(options.event, { options:options, images:images }, $.asynchImageLoader._loadOnEvent);
			}
		},

		// Method called when event : "load" or "load+scroll" (default)
		later : function(options) {
			var images = this;

			// If the 'load' event is specified, immediately load all the visible images and remove them from the stack
			if (options.event === 'load') {
				images.each(function(){
					$.asynchImageLoader._loadImageIfVisible(options, this, images.data('triggerEl'));
				});
			}
			$.asynchImageLoader._purgeStack( images );

			// After [timeout] has elapsed, load the remaining images if they are visible OR (if no event is specified)
			setTimeout(function() {

				if (options.event === 'load') {
					images.each(function(){
						$.asynchImageLoader._loadImage(options, $(this));
					});
				} else {
					// Method : "load+scroll"
					images.each(function(){
						$.asynchImageLoader._loadImageIfVisible(options, this, images.data('triggerEl'));
					});
				}

				$.asynchImageLoader._purgeStack( images );

				if (options.event === 'load+scroll') {
					options.event = 'scroll';
					$.asynchImageLoader.onEvent( options, images );
				}
			}, options.timeout);
		},

		// Function that checks if the images have been loaded
		_loadImageIfVisible : function(options, image, triggerEl) {
			var $img = $(image),
			container = (options.event === 'scroll' ? triggerEl : $window);

			if ($.asynchImageLoader._isInTheScreen (container, $img, options.offset)) {
				$.asynchImageLoader._loadImage(options, $img);
			}
		},

		// Function that returns true if the image is visible inside the "window" (or specified container element)
		_isInTheScreen : function($ct, $img, optionOffset) {
			var is_ct_window  = $ct[0] === window,
				ct_offset  = $ct.offset() || { top:0, left:0 },
				ct_top     = ct_offset.top + ( is_ct_window ? $ct.scrollTop() : 0),
				ct_left    = ct_offset.left + ( is_ct_window ? $ct.scrollLeft() : 0),
				ct_right   = ct_left + $ct.width(),
				ct_bottom  = ct_top + $ct.height(),
				img_offset = $img.offset(),
				img_width = $img.width(),
				img_height = $img.height();

			return (ct_top - optionOffset) <= (img_offset.top + img_height) &&
				(ct_bottom + optionOffset) >= img_offset.top &&
					(ct_left - optionOffset)<= (img_offset.left + img_width) &&
						(ct_right + optionOffset) >= img_offset.left;
		},

		// Main function --> Load the images copying the "longdesc" attribute into the "src" attribute
		_loadImage : function(options, $img) {

			$img.hide();

            var att = $img.attr("longdesc");
            var atts = att.split("*");

			$img.attr("src", atts[0]);
            if(atts.length == 3){
                if(atts[1] >= 0){
                    $img.attr("width",atts[1]);
                }
                if(atts[2] >= 0){
                    $img.attr("height",atts[2]);
                }
            }
			$img.removeAttr('longdesc');

			// Images loaded with some effect if existing
			if(options.effect) {
				if (options.speed) {
					$img[options.effect](options.speed);
				} else {
					$img[options.effect]();
				}
			} else {
				$img.show();
			}

		}
	};
}(jQuery));

 $(function() {
            $('img.lazy').asynchImageLoader({
                event: 'load',
                placeholder: '/images/leer.gif'
            });
        });

