/*!
 * SexySlider v1.0 - for jQuery 1.3+
 * http://codecanyon.net/item/sexy-slider/87148
 *
 * Copyright 2010, Eduardo Daniel Sada
 * Restrictive licensed
 * http://codecanyon.net/wiki/buying/howto-buying/licensing/
 *
 * Date: Feb 13 2010
 
 * SexySlider is a JQuery plugin that lets you easily
 * create powerful javascript Sliders with very nice
 * transition effects. Inspirated in jqFancyTransitions.
 * Developed in OOP.
 */

(function($) {
  
  var ie6 = (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) < 7 && parseInt(jQuery.browser.version, 10) > 4);

  if (ie6) {
    try { document.execCommand("BackgroundImageCache", false, true); } catch(err) {}
  };

  $.bind = function(object, method) {
    var args = Array.prototype.slice.call(arguments, 2);
    return function() {
      var args2 = [this].concat(args, $.makeArray( arguments ));
      return method.apply(object, args2);
    };
  };

  var SSPrototype = function() { };

  $.extend(SSPrototype.prototype, {
  
  init: function(el, options) {
    var defaults = {
      navigation      : '',
      control         : '',
      width           : 500,
      height          : 375,
      strips          : 20,
      auto            : true,
      delay           : 3000, // in ms
      stripSpeed      : 400,  // in ms
      titleOpacity    : 0.7,
      titleSpeed      : 1000, // in ms
      direction       : 'alternate', // left, right, alternate, random
      effect          : 'random' // curtain, zipper, wave, fountain, cascade, random
    };

    this.dom    = {};
    this.img    = [];
    this.titles = [];
    this.imgInc = 0;
    this.imgInterval = 0;
    this.inc    = 0;
    this.order  = [];
    this.controls = [];
    this.direction = 0;

    this.options = $.extend({}, defaults, options);
    this.element = el;

    var params = this.options;
    var self   = this;

		$('img', el).each(function(i) {
      var item       = $(this);
      self.img[i]    = item.attr('src');
      self.titles[i] = item.attr('alt') ? item.attr('alt') : (item.attr('title') ? item.attr('title') : '');
      
      if (self.options.control) {
        self.controls[i] = $('<a href="#" class="sexyslider-control" rel="'+i+'"><span>'+(i+1)+'</span></a>');
        $(self.options.control).append(self.controls[i]);
        
        if (i==0) {
          self.controls[i].addClass('active');
        }

        self.controls[i].click(function(event) {
          self.transition($(this).attr('rel'));
          event.preventDefault();
        });
      };
      
      item.hide();
		});

		$(this.element).css({
			'background-image'    : 'url('+this.img[0]+')',
			'background-position' : 'top left',
			'position'  : 'relative',
			'overflow'  : 'hidden',
			'width'     : params.width,
			'height'    : params.height
    });

    this.dom.title = $("<div class='sexyslider-title'>"+this.titles[0]+"</div>");

    $(this.dom.title).css({
      'background-color' : '#000000',
      'color'     : '#FFFFFF',
      'position'  : 'absolute',
      'bottom'    : 0,
      'left'      : 0,
      'width'     : params.width - 10,
      'padding'   : 5,
      'z-index'   : 1000
    });

    $(this.element).append(this.dom.title);

    if (this.titles[this.imgInc]) {
      $(this.dom.title).css({
        'opacity' : params.titleOpacity
      });
    } else {
      $(this.dom.title).css({
        'opacity' : 0
      });
    };

		var stripWidth  = parseInt(params.width / params.strips);
		var gap         = params.width - stripWidth * params.strips; // number of pixels
		var stripLeft   = 0;
    var odd         = 1;
    
    //this.dom.strip  = {};
    this.dom.strip  = [];

		// creating bars
		for (i=0; i < params.strips; i++) {

			if ( gap > 0) {
				tstripWidth = stripWidth + 1;
				gap--;
			} else {
				tstripWidth = stripWidth;
			}
			
      var pete = $("<div class='strip-"+this.element.id+"'></div>").get(0);
			$(pete).css({
				'background-position': -stripLeft +'px top',
        'width'   : tstripWidth + "px",
        'height'  : params.height + "px",
        'float'   : 'left',
        'position': 'absolute',
				'left'    : stripLeft
			});
      
			//this.dom.strip[i] = $("<div class='strip-"+this.element.id+"'></div>").get(0);
			//$(this.dom.strip[i]).css({
			//	'background-position': -stripLeft +'px top',
      //  'width'   : tstripWidth + "px",
      //  'height'  : params.height + "px",
      //  'float'   : 'left',
      //  'position': 'absolute',
			//	'left'    : stripLeft
			//});
			//$(this.element).append(this.dom.strip[i]); // Optimizar, se accede al DOM dentro del bucle estoy es muy lento.
                                                  // La idea es guardar todo en una variable e insertarlo todo junto fuera del bucle.

      this.dom.strip.push ( pete );

			stripLeft += tstripWidth;

      this.order[i] = i;

		}; // end for
		
		$(this.element).append(this.dom.strip);

    // add events
    if (params.navigation) {
      var prev = $('<a href="#" class="sexyslider-prev"><span>Prev</span></a>');
      var next = $('<a href="#" class="sexyslider-next"><span>Next</span></a>');

      prev.click(function(event) { self.transition("prev"); event.preventDefault(); });
      next.click(function(event) { self.transition("next"); event.preventDefault(); });

      $(params.navigation).append(prev, next);
    }

    $.each(this.dom.strip, function(i, strip) {
      $(strip).bind('mouseover', $.bind(self, function() { this.setpause(true) }));
      $(strip).bind('mouseout',  $.bind(self, function() { this.setpause(false) }));
    });

    $(this.dom.title).bind('mouseover', $.bind(this, function() { this.setpause(true) }));
    $(this.dom.title).bind('mouseout',  $.bind(this, function() { this.setpause(false)}));


		if (params.auto) {
      clearInterval(this.imgInterval);
      this.imgInterval = setInterval($.bind(this, function() {this.transition();} ), params.delay+((this.options.stripSpeed / 6)*params.strips)+params.stripSpeed);
    }

    return this;
  },

  setpause: function(val) {
    this.pause = val;
  },

  transition: function(dir) {
    if (this.pause == true || dir == this.imgInc) {
      return false;
    };
    
    this.pause = true;
    this.stripInterval = setInterval($.bind(this, function() { this.strips(this.order[this.inc]); }), this.options.stripSpeed / 6);

    $(this.element).css({
      'background-image' : 'url('+this.img[this.imgInc]+')'
    });

    switch (dir) {
      case "next":
        this.imgInc = (this.imgInc+1 >= this.img.length) ? 0 : this.imgInc+1;
        clearInterval(this.imgInterval);
        break;
      case "prev":
        this.imgInc = (this.imgInc-1 < 0) ? this.img.length-1 : this.imgInc-1;
        clearInterval(this.imgInterval);
        break;
      case "first":
        this.imgInc = 0;
        clearInterval(this.imgInterval);
        break;
      case "last":
        this.imgInc = this.img.length-1;
        clearInterval(this.imgInterval);
        break;
      default:
        if (!isNaN(parseFloat(dir)) && isFinite(dir)) { //is numeric
          this.imgInc = dir;
          clearInterval(this.imgInterval);
        } else {
          // for auto
          this.imgInc = (this.imgInc+1 >= this.img.length) ? 0 : this.imgInc+1;
        };
        break;
    };

    if (this.titles[this.imgInc]!='') {
      $(this.dom.title).html(this.titles[this.imgInc]);
      opacity = this.options.titleOpacity;
    } else {
      opacity = 0;
    };

    $(this.dom.title).animate({ 'opacity' : opacity }, this.options.titleSpeed);
    
    if (this.options.control) {
      $.each(this.controls, function(i, el) {
        $(el).removeClass('active');
      });
      $(this.controls[this.imgInc]).addClass('active');
    }

    this.inc = 0;

    switch (this.options.effect) {
      case 'fountain':
        $.bind(this, this.effects.fountain)();
        break;
      case 'wave':
        $.bind(this, this.effects.wave)();
        break;
      case 'zipper':
        $.bind(this, this.effects.zipper)();
        break;
      case 'curtain':
        $.bind(this, this.effects.curtain)();
        break;
      case 'cascade':
        $.bind(this, this.effects.cascade)();
        break;
      case 'random':
        $.bind(this, this.effects.random)();
        break;
    };

    // left, right, alternate, random
    if ((this.options.direction == 'right' && this.order[0] == 1)) {
      this.order.reverse();
      this.direction = 1;
    } else if (this.options.direction == 'random') {
      this.order = this.shuffle(this.order);
    } else if (this.options.direction == 'alternate') {
      if (!this.direction) {
        this.order.reverse();
        this.direction = 1;
      } else {
        this.direction = 0;
      }
    } else {
      this.direction = 0;
    }
  },

  shuffle: function(arr) {
    for(
      var j, x, i = arr.length; i;
      j = parseInt(Math.random() * i),
      x = arr[--i], arr[i] = arr[j], arr[j] = x
    );
    return arr;
  },
  
  effects: {
    cascade: function() {
      var odd   = 1;
      var total = this.order.length;
      var mitad = parseInt(this.options.strips/2);
      for (i=0; i < total; i++) {
          $(this.dom.strip[i]).css( 'bottom', 'auto' );
        this.order[i] = mitad - (parseInt((i+1)/2)*odd);
        odd *= -1;
      };
      this.order[this.options.strips-1] = 0;
    },
    
    curtain: function() {
      // void
    },
    
    wave: function() {
      for (i=0; i < this.order.length; i++) {
          $(this.dom.strip[i]).css( 'bottom', 'auto' );
          this.order[i] = i;
      };
    },
    
    zipper: function() {
      for (i=0; i < this.order.length; i++) {
        if (i%2 == 0) {
          $(this.dom.strip[i]).css( 'bottom', 0 );
        } else {
          $(this.dom.strip[i]).css( 'bottom', 'auto' );
        };
      };
    },
    
    fountain: function() {
      var odd   = 1;
      var total = this.order.length;
      var mitad = parseInt(this.options.strips/2);

      for (i=0; i < total; i++) {
        $(this.dom.strip[i]).css( 'bottom', 0 );
        this.order[i] = mitad - (parseInt((i+1)/2)*odd);
        //this.order[this.options.strips-1] = this.options.strips;
        odd *= -1;
      };
      this.order[this.options.strips-1] = 0;
    },
    
    random: function() {
      var i = parseInt(Math.random() * 4);
      switch (i) {
        case 0:
          $.bind(this, this.effects.fountain)();
          this.options.usewidth = false;
          break;
        case 1:
          $.bind(this, this.effects.wave)();
          this.options.usewidth = false;
          break;
        case 2:
          $.bind(this, this.effects.fountain)();
          $.bind(this, this.effects.wave)();
          $.bind(this, this.effects.zipper)();
          this.options.usewidth = false;
          break;
        case 3:
          $.bind(this, this.effects.wave)();
          $.bind(this, this.effects.curtain)();
          this.options.usewidth = true;
          break;
        case 4:
          $.bind(this, this.effects.cascade)();
          this.options.usewidth = false;
          break;
      }
    }
  },
  
  strips: function(itemId) {
    if (this.inc == this.options.strips) {
      // end animation
      clearInterval(this.stripInterval);
      
      setTimeout($.bind(this, function() {this.pause = false;} ), this.options.stripSpeed);
      //this.pause = false;
      return false;
    };
    
    this.pause = true;
    
    var strip = $(this.dom.strip[itemId]);
    
    if (!ie6) {
      strip.css({ 'opacity' : 0 });
    };

    if (this.options.effect == 'curtain' || this.options.usewidth == true) {
      currWidth = strip.width();
      
      strip.css({
        'width'   : 0,
        'background-image' : 'url('+this.img[this.imgInc]+')'
      });
      
      strip.animate({
        'width'   : currWidth,
        'opacity' : 1
      }, this.options.stripSpeed);

    } else {

      strip.css({
        'height'  : 0,
        'background-image' : 'url('+this.img[this.imgInc]+')'
      });

      strip.animate({
        'height'  : this.options.height,
        'opacity' : 1
      }, this.options.stripSpeed);
      
    }

    this.inc++;
  }

	});


	$.fn.SexySlider = function(options) {
    this.each(function() {
      if (!this.SSObject) {
        this.SSObject = new SSPrototype().init(this, options);
      };
      return this.SSObject;
    });
  };

})(jQuery);