
(function($) {
   /**
    * $ is an alias to jQuery object
    *
    */
   $.fn.ioGallery = function(settings) {
      // Settings to configure the jQuery ioGallery plugin how you like
      settings = jQuery.extend({
         // Configuration related to navigation
         fixedNavigation:      false,      // (boolean) Boolean that informs if the navigation (next and prev button) will be fixed or not in the interface.
         // Configuration related to images
         imageLoading:          'images/iogallery-ico-loading.gif',      // (string) Path and the name of the loading icon
         imageBtnPrev:          'images/iogallery-btn-prev.gif',         // (string) Path and the name of the prev button image
         imageBtnNext:          'images/iogallery-btn-next.gif',         // (string) Path and the name of the next button image
         imageBlank:            'images/iogallery-blank.gif',         // (string) Path and the name of a blank image (one pixel)
         // Configuration related to container image box
         containerBorderSize:     10,      // (integer) If you adjust the padding in the CSS for the container, #iogallery-container-image-box, you will need to update this value
         containerResizeSpeed:   400,      // (integer) Specify the resize duration of container image. These number are miliseconds. 400 is default.
         // Configuration related to texts in caption. For example: Image 2 of 8. You can alter either "Image" and "of" texts.
         txtImage:             'Image',   // (string) Specify text "Image"
         txtOf:                'of',      // (string) Specify text "of"
         // Donīt alter these variables in any way
         itemsArray:           [],
         activeImage:          0
      },settings);
      // Caching the jQuery object with all elements matched
      var jQueryMatchedObj = this; // This, in this context, refer to jQuery object

      function initialize() {
         start(this,jQueryMatchedObj);
      }

      function start( objClicked, jQueryMatchedObj ) {
         createInterface( jQueryMatchedObj );
         setImageToView();
      }

      function createInterface( jQueryMatchedObj ) {
         jQueryMatchedObj.append('<div id="jquery-iogallery"><div id="iogallery-container-image-box"><div id="iogallery-container-image"><img id="iogallery-image"><div style="" id="iogallery-nav"><a href="#" id="iogallery-nav-btnPrev"></a><a href="#" id="iogallery-nav-btnNext"></a></div><div id="iogallery-loading"><a href="#" id="iogallery-loading-link"><img src="' + settings.imageLoading + '"></a></div></div></div><div id="iogallery-container-image-data-box"><div id="iogallery-container-image-data"><div id="iogallery-image-details"><span id="iogallery-image-details-caption"></span><span id="iogallery-image-details-description"></span><span id="iogallery-image-details-currentNumber"></span></div></div></div></div>');   
      }

      function setImageToView() {
         // Show the loading
         $('#iogallery-loading').show();
         if ( settings.fixedNavigation ) {
            $('#iogallery-image').hide();
         } else {
            // Hide some elements
            $('#iogallery-image,#iogallery-nav,#iogallery-nav-btnPrev,#iogallery-nav-btnNext').hide();
         }
         // Image preload process
         var objImagePreloader = new Image();
         objImagePreloader.onload = function() {
            $('#iogallery-image').attr('src',settings.itemsArray[settings.activeImage].url);
            // Perfomance an effect in the image container resizing it
            resizeContainerImageBox(objImagePreloader.width,objImagePreloader.height);
            //   clear onLoad, IE behaves irratically with animated gifs otherwise
            objImagePreloader.onload=function(){};
         };
         objImagePreloader.src = settings.itemsArray[settings.activeImage].url;
      };

      function resizeContainerImageBox(intImageWidth,intImageHeight) {
         // Get current width and height
         var intCurrentWidth  = $('#iogallery-container-image-box').width();
         var intCurrentHeight = $('#iogallery-container-image-box').height();
         // Get the width and height of the selected image plus the padding
         var intWidth  = (intImageWidth  + (settings.containerBorderSize * 2)); // Plus the imageīs width and the left and right padding value
         var intHeight = (intImageHeight + (settings.containerBorderSize * 2)); // Plus the imageīs height and the left and right padding value
         // Diferences
         var intDiffW = intCurrentWidth  - intWidth;
         var intDiffH = intCurrentHeight - intHeight;
         // Perfomance the effect
         $('#iogallery-container-image-box').animate({ width: intWidth, height: intHeight },settings.containerResizeSpeed,function() { showImage(); });
         if ( ( intDiffW == 0 ) && ( intDiffH == 0 ) ) {
            if ( $.browser.msie ) {
               ___pause(250);
            } else {
               ___pause(100);   
            }
         } 
         $('#iogallery-container-image-data-box').css({ width: intImageWidth });
         $('#iogallery-nav-btnPrev,#iogallery-nav-btnNext').css({ height: intImageHeight + (settings.containerBorderSize * 2) });
      };

      function showImage() {
         $('#iogallery-loading').hide();
         $('#iogallery-image').fadeIn(function() {
            showImageData();
            setNavigation();
         });
         preloadNeighborImages();
      };

      function showImageData() {
         $('#iogallery-container-image-data-box').slideDown('fast');
         $('#iogallery-image-details-caption').hide();
         $('#iogallery-image-details-description').hide();
         if ( settings.itemsArray[settings.activeImage].title ) {
            $('#iogallery-image-details-caption').html(settings.itemsArray[settings.activeImage].title).show();
         }
         if ( settings.itemsArray[settings.activeImage].description ) {
            $('#iogallery-image-details-description').html(settings.itemsArray[settings.activeImage].description).show();
         }
         // If we have a image set, display 'Image X of X'
         if ( settings.itemsArray.length > 1 ) {
            $('#iogallery-image-details-currentNumber').html(settings.txtImage + ' ' + ( settings.activeImage + 1 ) + ' ' + settings.txtOf + ' ' + settings.itemsArray.length).show();
         }      
      }

      function setNavigation() {

         $('#iogallery-nav').show();

         $('#iogallery-nav-btnPrev,#iogallery-nav-btnNext').css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });

         $('#iogallery-nav-btnPrev,#iogallery-nav-btnNext').hide();

         // Instead to define this configuration in CSS file, we define here. And itīs need to IE. Just.
         $('#iogallery-nav-btnPrev,#iogallery-nav-btnNext').css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
         
         // Show the prev button, if not the first image in set
         if ( settings.activeImage != 0 ) {
            $('#iogallery-nav-btnPrev').show();
            if ( settings.fixedNavigation ) {
               $('#iogallery-nav-btnPrev').css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 15% no-repeat' })
                  .unbind()
                  .bind('click',function() {
                     settings.activeImage = settings.activeImage - 1;
                     setImageToView();
                     return false;
                  });
            } else {
               // Show the images button for Next buttons
               $('#iogallery-nav-btnPrev').unbind().hover(function() {
                  $(this).css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 15% no-repeat' });
               },function() {
                  $(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
               }).show().bind('click',function() {
                  settings.activeImage = settings.activeImage - 1;
                  setImageToView();
                  return false;
               });
            }
         }
         
         // Show the next button, if not the last image in set
         if ( settings.activeImage != ( settings.itemsArray.length -1 ) ) {
            $('#iogallery-nav-btnNext').show();
            if ( settings.fixedNavigation ) {
               $('#iogallery-nav-btnNext').css({ 'background' : 'url(' + settings.imageBtnNext + ') right 15% no-repeat' })
                  .unbind()
                  .bind('click',function() {
                     settings.activeImage = settings.activeImage + 1;
                     setImageToView();
                     return false;
                  });
            } else {
               // Show the images button for Next buttons
               $('#iogallery-nav-btnNext').unbind().hover(function() {
                  $(this).css({ 'background' : 'url(' + settings.imageBtnNext + ') right 15% no-repeat' });
               },function() {
                  $(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
               }).show().bind('click',function() {
                  settings.activeImage = settings.activeImage + 1;
                  setImageToView();
                  return false;
               });
            }
         }
      }

      function preloadNeighborImages() {
         if ( (settings.itemsArray.length -1) > settings.activeImage ) {
            objNext = new Image();
            objNext.src = settings.itemsArray[settings.activeImage + 1].url;
         }
         if ( settings.activeImage > 0 ) {
            objPrev = new Image();
            objPrev.src = settings.itemsArray[settings.activeImage -1].url;
         }
      }

      function ___pause(ms) {
         var date = new Date(); 
         curDate = null;
         do { var curDate = new Date(); }
         while ( curDate - date < ms);
      };
     
      initialize();
   };
})(jQuery); // Call and execute the function immediately passing the jQuery object

