/**
 * jQuery ImagePreloader plugin
 * This jQuery plugin was inspired by the Lightbox plugin by Leandro Vieira Pinho (http://leandrovieira.com/projects/jquery/lightbox/)
 * for the preloading system. Big thanks to him.
 * Licensed under the MIT license:
 * @see LICENSE.txt
 * @name jquery-jImagePreloader-0.2.js
 * @author Heudiard Eric
 * @version 0.3
 * @date July 28, 2009
 * @category jQuery plugin
 * @copyright (c) 2009 Eric Heudiard (heudiard.net)
 * @example Visit http://dev.heudiard.net/jImagePreloader/ for more informations about this jQuery plugin
 *
 * I apologize for my english, .... I'm a poor french guy ;)
 */

 // Please do not modify these variables.
 var imageCount = 0, errorCount = 0, succeedCount = 0, splash = false;

;(function($) {
	/**
	 * $ is an alias to jQuery object
	 *
	 */
	$.fn.jImagePreloader = function(settings) {

        // Settings to configure the jQuery ImagePreloader plugin how you like
		settings = jQuery.extend(true, {
            defaultWidth  :  100,                            // (int) Default width if no width was set in attributes or CSS.
            defaultHeight :  100,                            // (int) Default height if no height was set in attributes or CSS.
            defaultTimer  :  1000,                           // (int) Default timer for the end fade in.
            imageClass    :  null,                           // (string) If set, will select only the images with this class.
            pluginPath    :  '/assets/Uploads',   // (string) Path to this plugin.
			imageLoading  :  'loader.gif',		             // (string) Name of the loading icon (32x32) which is into 'img' folder in the plugin path.
            imageError    :  'error.gif',                    // (string) Name of the error icon (32x32) which is into 'img' folder in the plugin path.
            textError     :  'Seems this link is broken!',   // (string)
            splashScreen  :  {                               // (array) Default configuration of the splashscreen
                                show          : false,                                      // (boolean) When true, show a splashscreen
                                type          : 'basic',                                    // (string) Type of the splashscreen (default, advanced, custom)
                                customID      : null,                                       // (string or null) ID of a custom DIV which will be shown as the splashscreen
                                onError       : null,                                       // (function or null) Custom function that will be fired when image loads errored. Only for custom splashscreen.
                                onSuccess     : null,                                       // (function or null) Custom function that will be fired when image loads successfully. Only for custom splashscreen.
                                title         : 'Images are loading, please be patient...', // (string) Title of the splashscreen
                                textOf        : ' out of ',                                 // (string) \
                                textSucceeded : ' succeeded, ',                             // (string)  |=> Text shown in the splashcreen of type advanced
                                textErrored   : ' errored.',                                // (string) /
                                image         : 'loadingAnimation.gif'                      // (string) Name of the loading animation image
                             }
        },settings);

		// Caching the jQuery object with all elements matched
		var jQueryMatchedObj = null, imgSplash = null, imgLoading = null, imgError = null;
        if(settings.imageClass) jQueryMatchedObj = $(this).find('img.'+settings.imageClass);
        else jQueryMatchedObj = $(this).find('img');

        //Add this image count to the pool
        imageCount += jQueryMatchedObj.length;

        //And the race begin, go go go
        _start();

		/**
		 * Start the jQuery ImagePreloader plugin
		 *
		 */
		function _start() {
            // Tag each image with its source attribute
            jQueryMatchedObj.each(function(){
                $(this).data('src', $(this).attr('src'));
            });
			// Call the function to create the markup structure; style some elements.
			_set_interface();
		}

		/**
		 * Create the jQuery imagePreloader plugin interface
		 *
		 * The HTML markup will be like that:
			<div class="jquery-image-preloader">
				<img src="path/to/image/XX.jpg" alt="" />
				<div class="image-preloader-loading">
				    <img src="path/to/loader.gif" alt="" />
				</div>
			</div>
		 *
		 */
		function _set_interface() {
            //Show the splashscreen if set
            if(settings.splashScreen.show == true){
                if(splash == false){
                    splash = true;
                    imgSplash = new Image;
                    imgSplash.onload = function(){
                        _show_splashScreen();
                        imgSplash.onload = function(){};
                    };
                    imgSplash.src = settings.pluginPath+'/img/'+settings.splashScreen.image;
                }
            }

            // We hide all matched images then we do some modifications to each of them
            jQueryMatchedObj.hide().each(function(){
                // Wrap the HTML markup around each img tag in our selector
                $(this).wrap('<div class="jquery-image-preloader"></div>');
                $(this).parent().append('<div class="image-preloader-loading"><img class="image-preloader-loading-img" src="'+settings.pluginPath+"/img/"+settings.imageLoading+'" alt="" /></div>');

                //Get image CSS configuration and apply it to the wrapping DIV
                var cssImg = __getCssFromImage($(this));
                var newCss = __clearCssFromImage($(this));
                //Clear image CSS configuration
                $(this).css(newCss).removeAttr("src");
                $(this).next('.image-preloader-loading').css(newCss);
                $(this).next('.image-preloader-error').css(newCss);

                //Give parent's image its CSS configuration
                $(this).parent().css(cssImg);
            });

            //Preload the image preloader.
            imgLoading = new Image;
            imgLoading.onload = function(){
                // Call the function that prepares image exibition
			    _set_images_to_view();
                imgLoading.onload = function(){};
            };
            imgLoading.src = settings.pluginPath+"/img/"+settings.imageLoading;
            //Preload the image error
            imgError = new Image;
            imgError.src = settings.pluginPath+"/img/"+settings.imageError;
		}

		/**
		 * Show the loading and preload the images in the background.
		 *
		 */
		function _set_images_to_view() {
			// Show the loading for each image
			$('.image-preloader-loading').show();

			// Images preload process
            jQueryMatchedObj.each(function(){
                var imgObj = $(this);

                var objImagePreloader = new Image();
                //Fired when the image is entirely preloaded
    			objImagePreloader.onload = function() {
    			    //We reassign the source to the image
    			    imgObj.attr('src', imgObj.data('src'));
                    //And we show it
                    _show_image(imgObj);
    				//Clear onLoad, IE behaves irratically with animated gifs otherwise
    				objImagePreloader.onload=function(){};
    			};
                //Fired if an error occured while the image is preloading, like a broken link
                objImagePreloader.onerror = function(){
                    //We show the error DIV
                    _show_error(imgObj);
                };
			    objImagePreloader.src = imgObj.data('src');
            });
		};

		/**
		 * Show the loaded image
		 *
		 */
		function _show_image(imgObj) {
		    setTimeout(function(){
		        //We hide and remove the preload DIV
                imgObj.parent().find('.image-preloader-loading').hide().remove();
                //And we fade to the preloaded image
                imgObj.fadeIn(settings.defaultTimer,
                    function(){
                        succeedCount++;
                        if(splash == true){
                            if(settings.splashScreen.type == 'advanced') _update_splashScreen();
                            if(errorCount + succeedCount == imageCount) _finish();
                        }
                    });
            }, 1000);
		};

        /**
		 * Show the error DIV
		 *
		 */
        function _show_error(imgObj){
            setTimeout(function(){
		        //We hide and remove the preload DIV
                imgObj.parent().find('.image-preloader-loading').hide().remove();
                //We add the error DIV to the DOM
                imgObj.parent().append('<div class="image-preloader-error"><img class="image-preloader-error-img" src="'+settings.pluginPath+"/img/"+settings.imageError+'" alt="" /><p>'+settings.textError+'</p><p>'+imgObj.data('src')+'</p></div>');
                imgObj.parent().find('.image-preloader-error').css(__clearCssFromImage(imgObj));
                //And we fade to it
                imgObj.parent().find('.image-preloader-error').fadeIn(settings.defaultTimer,
                    function(){
                        errorCount++;
                        if(splash == true){
                            if(settings.splashScreen.type == 'advanced') _update_splashScreen();
                            if(errorCount + succeedCount == imageCount) _finish();
                        }
                    });
            }, 1000);
        }

        /**
		 * Show a splashScreen while images are uploading.
		 *
		 */
        function _show_splashScreen(){
            var options = settings.splashScreen, html = '';

            switch(options.type){

                case 'advanced':
                    html = '<div id="image-preloader-splashscreen"><p id="image-preloader-splashscreen-title">'+options.title+'</p><p id="image-preloader-splashscreen-text">0'+options.textOf+imageCount+'</p><p id="image-preloader-splashscreen-text2">'+succeedCount+options.textSucceeded+errorCount+options.textErrored+'</p><div id="image-preloader-splashscreen-img"><div id="image-preloader-splashscreen-hidder"><img src="'+settings.pluginPath+'/img/'+options.image+'" alt="" /></div></div></div>';
                    break;
                case 'custom':
                    id = options.customID;
                    break;
                case 'basic':
                default:
                    html = '<div id="image-preloader-splashscreen"><p id="image-preloader-splashscreen-title">'+options.title+'</p><img src="'+settings.pluginPath+'/img/'+options.image+'" alt="" /></div>';
                    break;
            }
            if(options.type != 'custom'){
                $('body').append(html);
            }else $('#'+id).show();

            /*$(window).scroll(function(){
                alert('je scroll a donf');
            });   */
        }
        /**
		 * Update the splashscreen content.
		 *
		 */
        function _update_splashScreen(){
            var options = settings.splashScreen;
            var widthPerImage = $('#image-preloader-splashscreen img').width() / imageCount;
            $('#image-preloader-splashscreen-text').text((succeedCount + errorCount)+options.textOf+imageCount);
            $('#image-preloader-splashscreen-text2').text(succeedCount+options.textSucceeded+errorCount+options.textErrored);
            $('#image-preloader-splashscreen-hidder').width(widthPerImage*(succeedCount + errorCount));
        }

        /**
		 * Hide the splashScreen and remove it from the DOM.
		 *
		 */
        function _finish(){
            var tempo = 1000;
            if(settings.splashScreen.type == 'advanced') tempo = 3000;

            setTimeout(function(){
                var div;
                if(settings.splashScreen.type != 'custom'){
                    div = $('#image-preloader-splashscreen');
                }else div = $('#'+settings.splashScreen.customID);
		        //We hide and remove the splashScreen
                div.fadeOut(2000).remove();
            }, tempo);

            delete imageCount;
            delete errorCount;
            delete succeedCount;
            delete splash;
            delete imgSplash;
            delete imgLoading;
            delete imgError;
            delete jQueryMatchedObj;
        }


        /*******************************************************************************/
        /*                             OTHER FUNCTIONS                                 */
        /*******************************************************************************/

        /**
		 * Get CSS configuration from selected image
		 *
		 */
        function __getCssFromImage(imgObj){

            // we set the width and height of the image
            var dimensions = __getDimensions(imgObj);

            // we set the border configuration of the image
            var bt = __getBorder(imgObj, "top");
            var br = __getBorder(imgObj, "right");
            var bb = __getBorder(imgObj, "bottom");
            var bl = __getBorder(imgObj, "left");

            return {
                float : imgObj.css("float"),
                marginLeft : imgObj.css("margin-left"),
                marginRight : imgObj.css("margin-right"),
                marginBottom : imgObj.css("margin-bottom"),
                marginTop : imgObj.css("margin-top"),
                paddingLeft : imgObj.css("padding-left"),
                paddingRight : imgObj.css("padding-right"),
                paddingBottom : imgObj.css("padding-bottom"),
                paddingTop : imgObj.css("padding-top"),
                borderTop : bt,
                borderRight : br,
                borderBottom : bb,
                borderLeft : bl,
                width : dimensions.width,
                height : dimensions.height,
                position : imgObj.css("position"),
                top : imgObj.css("top"),
                left : imgObj.css("left"),
                bottom : imgObj.css("bottom"),
                right : imgObj.css("right"),
                zIndex : imgObj.css("z-index"),
                cursor : imgObj.css("cursor"),
                visibility : imgObj.css("visibility")
            };
        };

        /**
		 * Return a default CSS configuration
		 *
		 */
        function __clearCssFromImage(imgObj){

            // we set the width and height of the image
            var dimensions = __getDimensions(imgObj);

            return {
                margin : 0,
                padding : 0,
                border : 0,
                position : "relative",
                left : 0,
                top : 0,
                right : 0,
                bottom : 0,
                width : dimensions.width,
                height : dimensions.height
            };
        };

        /**
		 * Return the dimensions of a selected image
		 *
		 */
        function __getDimensions(imgObj){
            var w = settings.defaultWidth + "px", h = settings.defaultHeight + "px";
            if(imgObj.css("width") != "auto")
                if(imgObj.css("width") != "0px" || imgObj.attr("width") != 0)
                    w = imgObj.width() + "px";
            if(imgObj.css("height") != "auto")
                if(imgObj.css("height") != "0px" || imgObj.attr("height") != 0)
                    h = imgObj.height() + "px";
            return {width:w, height:h};
        }

        /**
		 * Return the border configuration of a selected image
		 *
		 */
        function __getBorder(imgObj, side){
            return imgObj.css("border-"+side+"-color") + " " +
                   imgObj.css("border-"+side+"-style") + " " +
                   //Because of firefox we have to use the ceil value
                   Math.ceil(imgObj.css("border-"+side+"-width").replace("px", "")) + "px";
        }
		// Return the jQuery object for chaining.
		return this;
	};
})(jQuery); // Call and execute the function immediately passing the jQuery object
