// ConditionalImages module for Slider Pro.
// 
// Adds the possibility to specify multiple sources for each image and
// load the image that's the most appropriate for the size of the slider.
// For example, instead of loading a large image even if the slider will be small
// you can specify a smaller image that will be loaded instead.
;(function( window, $ ) {

	"use strict";

	var NS = 'ConditionalImages.' + $.SliderPro.namespace;

	var ConditionalImages = {

		// Reference to the previous size
		previousImageSize: null,

		// Reference to the current size
		currentImageSize: null,

		// Indicates if the current display supports high PPI
		isRetinaScreen: false,

		initConditionalImages: function() {
			this.currentImageSize = this.previousImageSize = 'default';
			this.isRetinaScreen = ( typeof this._isRetina !== 'undefined' ) && ( this._isRetina() === true );

			this.on( 'update.' + NS, $.proxy( this._conditionalImagesOnUpdate, this ) );
			this.on( 'sliderResize.' + NS, $.proxy( this._conditionalImagesOnResize, this ) );
		},

		// Loop through all the existing images and specify the original path of the image
		// inside the 'data-default' attribute.
		_conditionalImagesOnUpdate: function() {
			$.each( this.slides, function( index, element ) {
				var $slide = element.$slide;

				$slide.find( 'img:not([ data-default ])' ).each(function() {
					var $image = $( this );

					if ( typeof $image.attr( 'data-src' ) !== 'undefined' ) {
						$image.attr( 'data-default', $image.attr( 'data-src' ) );
					} else {
						$image.attr( 'data-default', $image.attr( 'src' ) );
					}
				});
			});
		},

		// When the window resizes, identify the applyable image size based on the current size of the slider
		// and apply it to all images that have a version of the image specified for this size.
		_conditionalImagesOnResize: function() {
			if ( this.slideWidth <= this.settings.smallSize ) {
				this.currentImageSize = 'small';
			} else if ( this.slideWidth <= this.settings.mediumSize ) {
				this.currentImageSize = 'medium';
			} else if ( this.slideWidth <= this.settings.largeSize ) {
				this.currentImageSize = 'large';
			} else {
				this.currentImageSize = 'default';
			}

			if ( this.previousImageSize !== this.currentImageSize ) {
				var that = this;

				$.each( this.slides, function( index, element ) {
					var $slide = element.$slide;

					$slide.find( 'img' ).each(function() {
						var $image = $( this ),
							imageSource = '';

						// Check if the current display supports high PPI and if a retina version of the current size was specified
						if ( that.isRetinaScreen === true && typeof $image.attr( 'data-retina' + that.currentImageSize ) !== 'undefined' ) {
							imageSource = $image.attr( 'data-retina' + that.currentImageSize );

							// If the retina image was not loaded yet, replace the default image source with the one
							// that corresponds to the current slider size
							if ( typeof $image.attr( 'data-retina' ) !== 'undefined' && $image.attr( 'data-retina' ) !== imageSource ) {
								$image.attr( 'data-retina', imageSource );
							}
						} else if ( ( that.isRetinaScreen === false || that.isRetinaScreen === true && typeof $image.attr( 'data-retina' ) === 'undefined' ) && typeof $image.attr( 'data-' + that.currentImageSize ) !== 'undefined' ) {
							imageSource = $image.attr( 'data-' + that.currentImageSize );

							// If the image is set to lazy load, replace the image source with the one
							// that corresponds to the current slider size
							if ( typeof $image.attr( 'data-src' ) !== 'undefined' && $image.attr( 'data-src' ) !== imageSource ) {
								$image.attr( 'data-src', imageSource );
							}
						}

						// If a new image was found
						if ( imageSource !== '' ) {

							// The existence of the 'data-src' attribute indicates that the image
							// will be lazy loaded, so don't load the new image yet
							if ( typeof $image.attr( 'data-src' ) === 'undefined' && $image.attr( 'src' ) !== imageSource  ) {
								that._loadConditionalImage( $image, imageSource, function( newImage ) {
									if ( newImage.hasClass( 'sp-image' ) ) {
										element.$mainImage = newImage;
										element.resizeMainImage( true );
									}
								});
							}
						}
					});
				});

				this.previousImageSize = this.currentImageSize;
			}
		},

		// Replace the target image with a new image
		_loadConditionalImage: function( image, source, callback ) {

			// Create a new image element
			var newImage = $( new Image() );

			// Copy the class(es) and inline style
			newImage.attr( 'class', image.attr( 'class' ) );
			newImage.attr( 'style', image.attr( 'style' ) );

			// Copy the data attributes
			$.each( image.data(), function( name, value ) {
				newImage.attr( 'data-' + name, value );
			});

			// Copy the width and height attributes if they exist
			if ( typeof image.attr( 'width' ) !== 'undefined') {
				newImage.attr( 'width', image.attr( 'width' ) );
			}

			if ( typeof image.attr( 'height' ) !== 'undefined') {
				newImage.attr( 'height', image.attr( 'height' ) );
			}

			if ( typeof image.attr( 'alt' ) !== 'undefined' ) {
				newImage.attr( 'alt', image.attr( 'alt' ) );
			}

			if ( typeof image.attr( 'title' ) !== 'undefined' ) {
				newImage.attr( 'title', image.attr( 'title' ) );
			}

			newImage.attr( 'src', source );

			// Add the new image in the same container and remove the older image
			newImage.insertAfter( image );
			image.remove();
			image = null;
				
			if ( typeof callback === 'function' ) {
				callback( newImage );
			}
		},

		// Destroy the module
		destroyConditionalImages: function() {
			this.off( 'update.' + NS );
			this.off( 'sliderResize.' + NS );
		},

		conditionalImagesDefaults: {

			// If the slider size is below this size, the small version of the images will be used
			smallSize: 480,

			// If the slider size is below this size, the small version of the images will be used
			mediumSize: 768,

			// If the slider size is below this size, the small version of the images will be used
			largeSize: 1024
		}
	};

	$.SliderPro.addModule( 'ConditionalImages', ConditionalImages );

})( window, jQuery );