/*
The qslider plugin
© Teemu Alapoikela 2010
MIT License (http://jquery.org/license)
*/
(function($){
  //Creates the slider for each of the matched elements
  $.fn.qslider = function(o){
    return this.each(function(){
      new $qs(this,o);
    });
  };
  
  //Defines the default values
  var defaults = {
    duration: 500,
    vertical: "no",
    slideName: ".qslider-slide",
    useQcordion: false,
    useQnote: false,
    useNumIndicator: false,
    useNavigation: false,
    naviPrevHtml: "<a rel='Edellinen kuva' href='javascript:void(0)'>Edellinen</a>",
    naviNextHtml: "<a rel='Seuraava kuva' href='javascript:void(0)'>Seuraava</a>",
    autoPlay: true,
    autoDelay: 4000,
    align: "horizontal",
    transition: "slide"
  };
  
  //Creates the qslider object
  $.qslider = function(e,o){
    this.options = $.extend({}, defaults, o || {});
    
    this.container = $(e);
    this.slide = $("ul",this.container);
    this.naviPrev = null;
    this.naviNext = null;
    this.numIndicator = null;
    this.navi = null;
    this.naviTrigger = null;
    this.childCount = $("li", this.slide).size();
    this.childWidth = this.slide.find("li:first").width();
    this.childHeight = this.slide.find("li:first").height();
    this.slideWidth = this.childCount * this.childWidth;
    this.minPosition = 0;
    this.maxPosition = (this.slideWidth - this.childWidth) * -1;
    this.currentPosition = 0;
    this.targetPosition = 0;
    this.currentIndex = 1;
    this.currentElement = null;
    this.fadeMaxPos = this.childCount -1;
    this.fadeMinPos = 0;
    this.fadeIndex = 0;
    
    this.setup();
  };
  
  //Variable
  var $qs = $.qslider;
  
  $qs.fn = $qs.prototype = {
      qslider: "0.1"
  };
  
  $qs.fn.extend = $qs.extend = $.extend;
  
  $qs.fn.extend({
  //Setups the qslider
    setup: function(){
      if (this.options.transition == "fade") {
        this.slide.css({
          position: "relative",
          width: this.options.slideWidth,
          height: this.options.slideHeight
        });
        this.slide.find("li").css({
          position: "absolute",
          left: "0px",
          top: "0px"
        });
        this.autoPlay();
      } else {
        if (this.options.useNavigation == true) {
          this.createNavi();
        }
        if (this.options.align == "vertical") {
          this.slide.css("width",this.childWidth+"px");
        } else {
          this.slide.css("width", this.slideWidth+"px");
        }
        this.slide.find("li").css("float","left");
        if (this.options.autoPlay == true) {
          this.autoPlay();
        }
      }
    },
  //Animates the slider
    anim: function(i){
      if (this.options.transition == "fade") {
        this.currentElement.fadeOut(this.options.duration);
      } else {
        this.slide.animate({
          marginLeft: i
        }, this.options.duration);
      }
    },
  //Autoplay
    autoPlay: function() {
      var self = this;
      setTimeout(function(){
        self.nextSlide("auto");
      }, this.options.autoDelay);
    },
    fadeReset: function() {
      this.fadeIndex = this.fadeMaxPos;
      this.currentElement = null;
      this.autoPlay();
    },
  //Previous slide
    prevSlide: function(auto) {
      this.targetPosition = this.currentPosition + this.childWidth;
      if (this.targetPosition > this.minPosition) {
        this.targetPosition = this.minPosition;
      } else {
        this.naviNext.removeClass("qslider-navi-disabled");
        this.toggleNavi();
      }
      if (this.currentPosition != this.minPosition) {
        this.anim(this.targetPosition);
        this.currentPosition = this.targetPosition;
        if (this.currentPosition == this.minPosition) {
          this.naviPrev.addClass("qslider-navi-disabled");
          this.toggleNavi();
        }
      }
      this.currentIndex--;
      if (this.currentIndex <= 1) this.currentIndex = 1;
      this.setNumIndicator("set");
    },
  //Next slide
    nextSlide: function(auto) {
      if (this.options.transition == "slide") {
        //If automatic play is on
        if (auto == "auto") {
          this.targetPosition = this.currentPosition - this.childWidth;
          if (this.targetPosition < this.maxPosition) {
            this.targetPosition = this.minPosition;
          }
          this.anim(this.targetPosition);
          this.currentPosition = this.targetPosition;
          this.currentIndex++;
          this.autoPlay();
        } else {
          this.targetPosition = this.currentPosition - this.childWidth;
          if (this.targetPosition < this.maxPosition) {
            this.targetPosition = this.maxPosition;
          } else {
            this.naviPrev.removeClass("qslider-navi-disabled");
            this.toggleNavi();
          }
          if (this.currentPosition != this.maxPosition) {
            this.anim(this.targetPosition);
            this.currentPosition = this.targetPosition;
            if (this.currentPosition == this.maxPosition) {
              this.naviNext.addClass("qslider-navi-disabled");
              this.toggleNavi();
            }
          }
          this.currentIndex++;
          if (this.currentIndex >= this.childCount) this.currentIndex = this.childCount;
          this.setNumIndicator("set");
        }
      } else { //transition was se to fade
        if (this.currentElement == null) {
          this.currentElement = this.slide.find("li:last");
          this.fadeIndex = this.fadeMaxPos;
        } else {
          if (this.fadeIndex == this.fadeMinPos) {
            var self = this;
            this.slide.find("li:last").fadeIn(this.options.duration, function(){
              self.slide.find("li").css({
                opacity: "1",
                visibility: "visible",
                display: "block"
              });
            });
            this.fadeReset();
          } else {
            this.currentElement = this.currentElement.prev();
          }
        }
        if (this.fadeIndex != this.fadeMinPos && this.currentElement != null) {
          this.anim();
          this.autoPlay();
          this.fadeIndex--;
        }
      }
    },
  //Creates the navigation buttons
    createNavi: function(){
      //The previous button
      //If already created, use the existing one
      this.naviPrev = this.container.find(".qslider-navi-prev");
      //If not, create a new one assuming that it's corresponding html has been defined
      if (this.naviPrev.size() == 0 && this.options.naviPrevHtml != null) {
        this.naviPrev = $(this.options.naviPrevHtml).appendTo(this.container).addClass("qslider-navi-prev qslider-navi qslider-navi-disabled").hide().bind("click", {elem:this}, function(e){
          e.data.elem.prevSlide();
        });
      }
      //The next button
      //If already created, use the existing one
      this.naviNext = this.container.find(".qslider-navi-next");
      //If not, create a new one assuming that it's corresponding html has been defined
      if (this.naviNext.size() == 0 && this.options.naviNextHtml != null) {
        this.naviNext = $(this.options.naviNextHtml).appendTo(this.container).addClass("qslider-navi-next qslider-navi").hide().bind("click", {elem:this}, function(e){
          e.data.elem.nextSlide();
        });
        if (this.minPosition == this.maxPosition ) {
          this.naviNext.addClass("qslider-navi-disabled");
        }
      }
      this.setNumIndicator();
      //Check if qcordion is in use. If so, assigns qcordion-content as the navigation trigger
      if (this.options.useQcordion == true) {
        this.naviTrigger = this.container.parents(".qcordion-content");
      } else {
        this.naviTrigger = this.container;
      }
      this.naviTrigger.bind('mouseenter', {element:this}, function(e){
        e.data.element.toggleNavi("show");
      }).bind('mouseleave', {element:this}, function(e){
        e.data.element.toggleNavi("hide");
      });
      this.navi = $(".qslider-navi");
      if (this.options.useQnote == true) this.navi.qnote();
      this.toggleNavi();
    },
  //Sets and updates the numIndicator
    setNumIndicator: function(setter) {
      this.currentIndex = (this.currentPosition / this.childWidth * -1) +1;
      if (setter) {
        this.numIndicator.html(this.currentIndex+" / "+this.childCount);        
      } 
      if (!setter) {
        this.numIndicator = this.container.find(".qslider-num-indicator");
      }
      if (this.numIndicator.size() == 0) {
        this.numIndicator = $("<span>"+this.currentIndex+" / "+this.childCount+"</span>").appendTo(this.container).addClass("qslider-num-indicator");
      }
    },
  //Either shows or hides the slider navigation
    toggleNavi: function(dir) {
      switch(dir) {
        case "show":
          $(".qslider-navi").each(function(){
            if ($(this).hasClass("qslider-navi-disabled") == false && $(this).is(":visible") == false) $(this).show();
          });
          break;
        case "hide":
          this.navi.hide();
          break;
        case undefined:
          this.navi.not(".qslider-navi-disabled").each(function(){
            $(this).fadeIn("fast");
          });
          $(".qslider-navi-disabled").stop(true,true).fadeOut("fast");
          break;
      }
    },
    reset: function(){
      if (this.navi != null) {
        this.navi.remove();
      }
    }
  });
  
})(jQuery);