/**
 * jKenBurnsEffect - jQuery plugin
 * @requires jQuery v1.1.3.1
 *
 * http://www.gasteroprod.com/projets/jkenburnseffect/
 *
 * Copyright (c) 2007 Nicolas Hoizey
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Version: 1.0.0
 */

/**
 * Creates a Ken Burns effects like slideshow widget for images from a simple HTML markup.
 * See http://en.wikipedia.org/wiki/Ken_Burns_Effect
 * 
 * The HTML markup that is used to build the slideshow can be as simple as:
 *
 * <div class="slideshow">
 *   <dl>
 *     <dt><img src="image/1.jpg" alt="1"></dt>
 *     <dd>First image</dd>
 *     <dt><img src="image/2.jpg" alt="2"></dt>
 *     <dd>Second image</dd>
 *     <dt><img src="image/3.jpg" alt="3"></dt>
 *     <dd>Third image</dd>
 *   </dl>
 * </div>
 *
 * This snippet is nothing but a simple div containing an ordered list of images.
 * 
 * Now, all you need to do is call the slideshow component on the div element that represents it :
 *
 * @example
 * $(".slideshow").jKenBurnsEffect();
 * @desc Easy launch with default settings
 * @example
 * $('.slideshow').jKenBurnsEffect({
 *   speed: 1000
 * });
 * @desc Specifying a speed will slow-down or speed-up the sliding speed of your slideshow. Try it out with
 * different speeds like 800, 600, 1500 etc.
 *
 * @param	  Object	settings	  (optional) Customize your slideshow
 * @option	Number	speed	      Item animation duration - 5000 is the default
 * @option	Boolean fitShrink	  Shrink images larger than the viewport
 * @option	Boolean fitEnlarge	Enlarge images smaller than the viewport
 *
 * @name jKenBurnsEffect
 * @type jQuery
 * @cat Plugins/Image Gallery
 * @author Nicolas Hoizey (http://www.gasteroprod.com/)
 */
(function($) {
  $.fn.jKenBurnsEffect = function(settings) {
    settings = $.extend({
        speed: 5000,
        fitShrink: true,
        fitEnlarge: false
    }, settings || {});
  
    return this.each(function() {
      var div = $(this);
      var dl = div.find('>dl');
      var photos = dl.find('dt img');
      var dd = dl.find('>dd');
      var legend = $('<div class="legend"></div>').appendTo(div);

      var number = photos.size();
      var photoIndex = 0;

      var viewportWidth = dl.width();
      var viewportHeight = dl.height();
      var viewportHidden = Math.ceil(viewportWidth / 10);

      photos.hide();
      dl.css({ visibility: 'visible', overflow: 'hidden', position: 'relative' });
      dd.css({ position: 'absolute', left: viewportWidth });

      function go() {
        legend.html(dd.eq(photoIndex).html());

        item = photos.eq(photoIndex);
        itemRealWidth = item.width();
        itemRealHeight = item.height();

        // Default size to real one
        itemWidth = itemRealWidth;
        itemHeight = itemRealHeight;

        // Best fit to viewport
        factor = 1;
        if (settings.fitEnlarge) {
          if (itemWidth < viewportWidth + viewportHidden) {
            if (itemHeight < viewportHeight + viewportHidden) {
              factor = Math.max((viewportHeight + viewportHidden) / itemHeight, (viewportWidth + viewportHidden) / itemWidth);
            } else {
              factor = (viewportWidth + viewportHidden) / itemWidth;
            }
          } else if (itemHeight < viewportHeight + viewportHidden) {
            factor = (viewportHeight + viewportHidden) / itemHeight;
          }
        }
        if (settings.fitShrink && factor == 1) {
          if (itemWidth > viewportWidth + viewportHidden) {
            if (itemHeight > viewportHeight + viewportHidden) {
              factor = Math.max((viewportHeight + viewportHidden) / itemHeight, (viewportWidth + viewportHidden) / itemWidth);
            } else {
              factor = (viewportWidth + viewportHidden) / itemWidth;
            }
          } else if (itemHeight > viewportHeight + viewportHidden) {
            factor = (viewportHeight + viewportHidden) / itemHeight;
          }
        }

        itemWidth *= factor;
        itemHeight *= factor;
        
        // Horizontal position
        if (Math.random() > 0.5) {
          startLeft = -viewportHidden;
          endLeft = viewportWidth - itemWidth + viewportHidden;
        } else {
          startLeft = viewportWidth - itemWidth + viewportHidden;
          endLeft = -viewportHidden;
        }
        // Vertical position
        if (Math.random() > 0.5) {
          startTop = -viewportHidden;
          endTop = viewportHeight - itemHeight + viewportHidden;
        } else {
          startTop = viewportHeight - itemHeight + viewportHidden;
          endTop = -viewportHidden;
        }
        // Zoom
        if (Math.random() > 0.5) {
          startWidth = itemWidth * 1.2;
          endWidth = itemWidth;
          startHeight = itemHeight * 1.2;
          endHeight = itemHeight;
        } else {
          startWidth = itemWidth;
          endWidth = itemWidth * 1.2;
          startHeight = itemHeight;
          endHeight = itemHeight * 1.2;
        }
        
        // Middle position
        middleLeft = startLeft + (endLeft - startLeft) / 2;
        middleTop = startTop + (endTop - startTop) / 2;
        middleWidth = startWidth + (endWidth - startWidth) / 2;
        middleHeight = startHeight + (endHeight - startHeight) / 2;

        // Animation launch
        item.css({ opacity: 'hide' })
          .css({ position: 'absolute', left: startLeft, top: startTop, width: startWidth, height: startHeight })
          .animate({ opacity: 'show', left: middleLeft, top: middleTop, width: middleWidth, height: middleHeight }, settings.speed * 3 / 4)
          .animate({ opacity: 'hide', left: endLeft, top: endTop, width: endWidth, height: endHeight }, settings.speed * 3 / 4)
          .css({ width: itemRealWidth, height: itemRealHeight });

        photoIndex = photoIndex + 1;
        if(photoIndex == number) {
            photoIndex = 0; 
        }
        return false;
      };

      setInterval(function() {
        go();
      }, settings.speed);
      go();
    });
  };
})(jQuery);
