﻿(function ($) {

  /**
  * Simple Slideshow Object and Methods
  */
  $.jqSimpleSlideshow = {
    defaults: {
      instanceId: null,
      width: 300,
      height: 300,
      items: 'li',
      delay: 4000,
      fade: 1800,
      curLayer: 0,
      zIndex: 1,
      shownum: false
    },

    // Set Slideshow Object Options
    setOptions: function (options) {
      var opts = this.defaults;
      for (var x in options) {
        if (typeof opts[x] === 'undefined') alert('Invalid option ' + x);
        else opts[x] = (opts[x] != null && opts[x].constructor == Object) ? this.setOptions(options[x], opts[x]) : options[x];
      }
      return opts;
    },

    // Init Slideshow
    initSlideshow: function (obj) {
      var self = this, o = obj.options;
      // Wrap Slideshow and setup css
      $(obj.element).wrap($('<div class="jqSimpleSlideshowWrap" />').css({ width: o.width + 'px', height: o.height + 'px', position: 'relative', overflow: 'hidden' }));
      $(obj.element).css({ width: o.width + 'px', height: o.height + 'px', display: 'block', position: 'absolute', top: 0, left: 0, margin: 0, padding: 0 });
      $('img, a', obj.element).css({ display: 'block', position: 'absolute', top: 0, left: 0, margin: 0, padding: 0 });
      if (o.instanceId != null) $(obj.element).parent().attr('id', o.instanceId);
      // if delay is in seconds convert to millseconds
      if (o.delay < 100) obj.options.delay = o.delay * 1000;
      // Get childNode elements to be cycled though. Initialize with lowest zindex and 0 opacity.
      obj.layers = $(obj.element).children(o.items).each(function (i, item) {
        $(this).css({ zIndex: o.zIndex - 1, opacity: 0, position: 'absolute', top: 0, left: 0, margin: 0, padding: 0 });
        if (this.tagName.toLowerCase != 'img') $(this).css({ width: o.width + 'px', height: o.height + 'px' });
      });
      // Setup starting layer index
      obj.activeIndex = obj.curLayer = o.curLayer == 'rand' ? Math.floor(Math.random() * obj.layers.length) : parseInt(o.curLayer);
      // Start the cycle layer process.
      if (obj.layers.length > 1) self.fadeInLayer(obj, obj.curLayer, 100); else obj.layers.css('opacity', 1);
      // Show Slideshow numbers
      if (o.shownum && obj.layers.length > 1) self.initSlideshowNumbers(obj);
    },

    // Add Slideshow numbers elements
    initSlideshowNumbers: function (obj) {
      var self = this, o = obj.options;
      nums = $('<div class="slideshownumbers"/>').appendTo($(obj.element).parent());
      nums.css({ position: 'absolute', zIndex: obj.layers.length + o.zIndex });
      obj.layers.each(function (i, item) {
        var num = $('<span/>').appendTo(nums).html(i + 1);
        num.bind('click', function () {
          if (obj.activeIndex == i) return;
          clearTimeout(obj.timer);
          obj.layers.css({ 'opacity': 0, zIndex: o.zIndex - 1 });
          obj.curLayer = obj.activeIndex = i;
          self.fadeInLayer(obj, i, 900);
        });
      });
      obj.icons = $('span', nums);
      $(obj.icons[obj.activeIndex]).addClass('active');
    },

    // Fade In Slideshow
    fadeInLayer: function (obj, i, speed) {
      var self = this, o = obj.options;
      var speed = speed || obj.options.fade;
      clearTimeout(obj.timer);
      obj.activeIndex = i;
      if (obj.curLayer != i) $(obj.layers[obj.curLayer]).animate({ 'opacity': 0 }, (speed + 100));
      $(obj.layers[i]).css({ zIndex: o.zIndex + 1 }).animate({ 'opacity': 1 }, speed, function () { self.cycleLayers(obj); });
      if (o.shownum && obj.layers.length > 1) {
        $(obj.icons).removeClass('active');
        $(obj.icons[obj.activeIndex]).addClass('active');
      }
    },

    // Calculate next image, current image and previous image and layer zindex and opacity accordingly
    cycleLayers: function (obj) {
      var self = this, o = obj.options, l = obj.layers.length, c = obj.curLayer;
      $(obj.layers[c <= 0 ? l - 1 : c - 1]).css({ 'opacity': 0, zIndex: o.zIndex - 1 });
      $(obj.layers[c = obj.curLayer = c >= l ? 0 : c]).css({ 'opacity': 1, zIndex: o.zIndex });
      obj.timer = setTimeout(function () { self.fadeInLayer(obj, (c + 1) == l ? 0 : c + 1); ++obj.curLayer; }, o.delay);
    }

  }// end slideshow object


  /**
  * Simple Slideshow jQuery function
  */
  $.fn.jqSimpleSlideshow = function (options) {
    return this.each(function (i) {
      var slideshow = {
        element: $(this),
        options: $.jqSimpleSlideshow.setOptions(options),
        activeIndex: 0,
        curLayer: 0,
        timer: null,
        layers: [],
        icons: []
      }
      $.jqSimpleSlideshow.initSlideshow(slideshow);
    });
  }

})(jQuery);
