/* 
*  Sliced Image Slider
*  Date - 8/23/2009
*  http://calyan.co.cc/
*  http://rampgroup.com/
*
*  Make sure that number of slices should be a number which divides image/wrapper width excatly for 'topDown' and 'bottomUp' directions.
*  For 'leftRight' and 'rightLeft' directions number of slices should divide image/wrapper height excatly.
*
*
*/

(function($) {

  $.fn.slicer = function(options) {
    var defaults = {
      autoPlay: true,
      numberOfSlices: 5,
      slideInterval: 5000,
      direction: 'bottomUp',
      duration: 1500,
      sliceDelay: 100,
      removeSliceDirection: 'fade',
      removeSliceDuration: 1500,
      removeSliceDelay: 100,
      removeFadeDuration: 2000
    };

    var options = $.extend(defaults, options);
    var element = $(this).attr("id");
    var elementWidth = $(this).width();
    var elementHeight = $(this).height();

    var slice = new Object();
    slice.Name = element + "_slice";
    slice.Height = null;
    slice.Width = null;
    slice.InitialLeft = null;
    slice.InitialTop = null;
    slice.LeftLimit = null;
    slice.TopLimit = null;
    slice.nextNumber = 1;

    var currentImage = 0;
    var no_of_images = $("#" + element + " ul").children().size();
    var slicesGenerated = null;
    var nextImgSrc = null;

    switch (options.direction) {
      case "bottomUp":
        slice.Width = elementWidth / options.numberOfSlices;
        slice.Height = elementHeight;
        slice.InitialLeft = 0;
        slice.InitialTop = elementHeight;
        slice.TopLimit = 0;
        slice.LeftLimit = null;
        break;
      case "topDown":
        slice.Width = elementWidth / options.numberOfSlices;
        slice.Height = elementHeight;
        slice.InitialLeft = 0;
        slice.InitialTop = -(elementHeight);
        slice.TopLimit = 0;
        slice.LeftLimit = null;
        break;
      case "leftRight":
        slice.Height = elementHeight / options.numberOfSlices;
        slice.Width = elementWidth;
        slice.InitialLeft = -(elementWidth);
        slice.InitialTop = 0;
        slice.LeftLimit = 0;
        slice.TopLimit = null;
        break;
      case "rightLeft":
        slice.Height = elementHeight / options.numberOfSlices;
        slice.Width = elementWidth;
        slice.InitialLeft = elementWidth;
        slice.InitialTop = 0;
        slice.LeftLimit = 0;
        slice.TopLimit = null;
        break;
    }

    // Initialization ---------------------------------------------------------
    $("#" + element + " ul li:first").nextAll().css('display', 'none'); // Hide all but the first image
    if (options.autoPlay) {
      var firstTime = true;
      setInterval(function() {
        if (firstTime) {
          firstTime = false;
          $("#masthead_" + currentImage).show().fadeOut(options.removeFadeDuration);
        } else {
          if (options.removeSliceDirection == 'fade') $("#masthead_" + currentImage).show().fadeOut(options.removeFadeDuration);
        }

        currentImage = (currentImage + 1) % no_of_images;
        nextImgSrc = $("#" + element + " ul").children().eq(currentImage).children().eq(0).attr("src");

        garbageCollectGeneratedSlices(slicesGenerated, slice, options.removeSliceDirection, options.removeSliceDuration, options.removeSliceDelay);
        slicesGenerated = createSlices(element, options.numberOfSlices, slice, nextImgSrc);
        animateSlices(slicesGenerated, slice.LeftLimit, slice.TopLimit, options.duration, options.sliceDelay, false);
      }, options.slideInterval);
    }
  };

  // Following are the utility functions used to get the effects. You can customize them as per your requirement.
  function garbageCollectGeneratedSlices(slices, slice, direction, removeDuration, removeDelay) {
    if (slices != null) {
      switch (direction) {
        case "bottomUp":
          animateSlices(slices, null, (-slice.Height), removeDuration, removeDelay, true);
          break;
        case "topDown":
          animateSlices(slices, null, slice.Height, removeDuration, removeDelay, true);
          break;
        case "leftRight":
          animateSlices(slices, slice.Width, null, removeDuration, removeDelay, true);
          break;
        case "rightLeft":
          animateSlices(slices, (-slice.Width), null, removeDuration, removeDelay, true);
          break;
        default:
          for (var i = 0; i < slices.length; i++) {
            $("#" + slices[i]).remove();
          }
          break;
      }
    }
  }

  function createSlices(parent, no_of_slices, slice, nextImgSrc) {
    var Left = slice.InitialLeft;
    var Top = slice.InitialTop;
    var slices = new Array(no_of_slices);

    for (var i = 0; i < slices.length; i++) {
      slices[i] = slice.Name + slice.nextNumber;
      var ele = document.createElement('div');
      ele.setAttribute("id", slices[i]);
      ele.style.position = "absolute";
      ele.style.overflow = "hidden";
      ele.style.width = slice.Width + "px";
      ele.style.height = slice.Height + "px";
      ele.style.left = Left + "px";
      ele.style.top = Top + "px";

      if (slice.InitialLeft == 0) {
        ele.style.backgroundImage = "url(" + nextImgSrc + ")";
        ele.style.backgroundPosition = (-Left) + "px 0px";
        ele.style.backgroundRepeat = "no-repeat";
        Left = Left + slice.Width;
      } else {
        ele.style.backgroundImage = "url(" + nextImgSrc + ")";
        ele.style.backgroundPosition = "0px " + (-Top) + "px";
        ele.style.backgroundRepeat = "no-repeat";
        Top = Top + slice.Height;
      }
      document.getElementById(parent).appendChild(ele);
      ++(slice.nextNumber);
    }
    return (slices);
  }

  function animateSlices(slices, leftLimit, topLimit, duration, delay, removeSlicesAfterAnimation) {
    var timing = 1;
    var currentElement = null;
    for (var i = 0; i < slices.length; i++) {
      currentElement = $("#" + slices[i]);
      animator.move(currentElement, leftLimit, topLimit, duration, timing, removeSlicesAfterAnimation);
      timing = timing + delay;
    }
    return true;
  }

  var animator = new Object();
  animator.move = function(ele, leftLimit, topLimit, duration, delay, remove) {
    setTimeout(function() {
      if (leftLimit == null) {
        if (remove) {
          ele.animate({ top: topLimit }, duration, null, function() { $(this).remove(); });
        } else {
          ele.animate({ top: topLimit }, duration);
        }
      } else {
        if (remove) {
          ele.animate({ left: leftLimit }, duration, null, function() { $(this).remove(); });
        } else {
          ele.animate({ left: leftLimit }, duration);
        }
      }
    }, delay);
  }

})(jQuery);

