;
(function($){
  $.fn.bannerSlider=function(params){
    var params=$.extend({
      direction:"horizontal",
      loop:false,
      dispItems:1,
      pagination:false,
      minPages: 0,
      paginationPosition:"inside",
      nextBtn:'<a role="button">&nbsp;</a>',
      prevBtn:'<a role="button">&nbsp;</a>',
      btnsPosition:"inside",
      nextBtnInsert:"appendTo",
      prevBtnInsert:"prependTo",
      nextBtnInsertFn:false,
      prevBtnInsertFn:false,
      autoSlide:false,
      autoSlideInterval:3000,
      delayAutoSlide:false,
      combinedClasses:false,
      effect:"slide",
      slideEasing:"swing",
      animSpeed:"normal",
      equalWidths:"true",
      verticalMargin:0,
      callback:function(){},
      useAddress:false,
      adressIdentifier:"slider",
      tabLabel:function(tabNum){
        return tabNum;
      }
    },params);
    if(params.btnsPosition=="outside"){
      params.prevBtnInsert="insertBefore";
      params.nextBtnInsert="insertAfter";
    }
    params.delayAutoSlide=params.delayAutoSlide||params.autoSlideInterval;
    return this.each(function(){
      var env={
        $elts:{},
        params:params,
        launchOnLoad:[]
      };

      env.$elts.slider=$(this).addClass("js");
      env.$elts.content=$(this).children().css({
        position:"absolute",
        "top":0
      });
      env.$elts.wrap=env.$elts.content.wrap('<div class="slider-wrap"></div>').parent().css({
        overflow:"hidden",
        position:"relative"
      });
      env.steps={
        first:0,
        count:env.$elts.content.children().length
      };

      env.steps.last=env.steps.count-1;
      if($.isFunction(env.params.prevBtnInsertFn)){
        env.$elts.prevBtn=env.params.prevBtnInsertFn(env.$elts);
      }else{
        env.$elts.prevBtn=$(params.prevBtn)[params.prevBtnInsert](env.$elts.slider);
      }
      if($.isFunction(env.params.nextBtnInsertFn)){
        env.$elts.nextBtn=env.params.nextBtnInsertFn(env.$elts);
      }else{
        env.$elts.nextBtn=$(params.nextBtn)[params.nextBtnInsert](env.$elts.slider);
      }
      env.$elts.nextBtn.addClass("slider-control next slider-next");
      env.$elts.prevBtn.addClass("slider-control previous slider-previous");
      env.$elts.content.find("li").css('display','block');
      initButtonsEvents(env);
      if(env.params.pagination){
        initPagination(env);
      }
      initAddress(env);
      $(function(){
        var $items=env.$elts.content.children();
        var $maxHeight=0;
        $items.each(function(){
          $item=$(this);
          $itemHeight=$item.outerHeight();
          if($itemHeight>$maxHeight){
            $maxHeight=$itemHeight;
          }
        });
        if(env.params.verticalMargin>0){
          $maxHeight=$maxHeight+env.params.verticalMargin;
        }
        $items.height($maxHeight);
        var $firstItem=env.$elts.content.children(":first");
        env.itemWidth=$firstItem.outerWidth();
        if(params.direction=="vertical"){
          env.contentWidth=env.itemWidth;
        }else{
          if(params.equalWidths){
            env.contentWidth=env.itemWidth*env.steps.count;
          }else{
            env.contentWidth=(function(){
              var totalWidth=0;
              env.$elts.content.children().each(function(){
                totalWidth+=$(this).outerWidth();
              });
              return totalWidth;
            })();
          }
        }
        env.$elts.content.width(env.contentWidth);
        env.itemHeight=$maxHeight;
        if(params.direction=="vertical"){
          env.$elts.content.css({
            height:env.itemHeight*env.steps.count+"px"
          });
          env.$elts.content.parent().css({
            height:env.itemHeight*env.params.dispItems+"px"
          });
        }else{
          env.$elts.content.parent().css({
            height:env.itemHeight+"px"
          });
        }
        updateButtonsState(env);
        $.each(env.launchOnLoad,function(i,fn){
          fn();
        });
        if(env.params.autoSlide){
          window.setTimeout(function(){
            env.autoSlideInterval=window.setInterval(function(){
              goToStep(env,getRelativeStep(env,"next"));
            },env.params.autoSlideInterval);
          },env.params.delayAutoSlide);
        }
      });
    });
  };

  function initButtonsEvents(env){
    env.$elts.nextBtn.add(env.$elts.prevBtn).bind("enable",function(){
      var $this=$(this).unbind("click").bind("click",function(){
        goToStep(env,getRelativeStep(env,($this.is(".next")?"next":"prev")));
        stopAutoSlide(env);
      }).removeClass("disabled");
      if(env.params.combinedClasses){
        $this.removeClass("next-disabled previous-disabled");
      }
    }).bind("disable",function(){
      var $this=$(this).unbind("click").addClass("disabled");
      if(env.params.combinedClasses){
        if($this.is(".next")){
          $this.addClass("next-disabled");
        }else if($this.is(".previous")){
          $this.addClass("previous-disabled");
        }
      }
    }).hover(function(){
      $(this).toggleClass("hover");
    });
  };

  function initPagination(env){
    env.$elts.pagination=$('<div class="pagination-wrap"><div class="slider-pagination"><p></p></div></div>')[((env.params.paginationPosition=="outside")?"insertAfter":"appendTo")](env.$elts.slider).find("p");
    env.$elts.paginationBtns=$([]);
    var items = env.$elts.content.find("li");

    if (!(env.params.minPages > 0 && items.length >= env.params.minPages)) {
      env.$elts.pagination.closest('div.pagination-wrap').hide();
      return;
    }
    
    env.$elts.content.find("li").each(function(idx){
      env.$elts.paginationBtns=env.$elts.paginationBtns.add($('<a role="button"><span class="numbers">'+env.params.tabLabel(idx + 1)+'</span></a>').data("firstStep",idx + 1));
    });
    
    env.$elts.paginationBtns=env.$elts.paginationBtns.add(env.$elts.nextBtn.show());
    env.$elts.paginationBtns=$([]).add(env.$elts.prevBtn.show()).add(env.$elts.paginationBtns);
    
    env.$elts.paginationBtns.each(function(){
      $(this).appendTo(env.$elts.pagination);
    });

    env.launchOnLoad.push(function(){
      env.$elts.paginationBtns.click(function(e){
        var i = $(this).data("firstStep") - 1;
        goToStep(env,i);
        stopAutoSlide(env);
      });
    });
  };

  function initAddress(env){
    if(env.params.useAddress&&$.isFunction($.fn.address)){
      $.address.init(function(e){
        var pathNames=$.address.pathNames();
        if(pathNames[0]===env.params.adressIdentifier&&!!pathNames[1]){
          goToStep(env,pathNames[1]-1);
        }else{
          $.address.value('/'+env.params.adressIdentifier+'/1');
        }
      }).change(function(e){
        var pathNames=$.address.pathNames();
        if(pathNames[0]===env.params.adressIdentifier&&!!pathNames[1]){
          goToStep(env,pathNames[1]-1);
        }
      });
    }else{
      env.params.useAddress=false;
    }
  };

  function goToStep(env,step){
    if(env.steps.count==1)
    {
      stopAutoSlide(env);
      return false;
    }
    env.params.callback(step);
    transition(env,step);
    env.steps.first=step;
    updateButtonsState(env);
    if(env.params.useAddress){
      $.address.value('/'+env.params.adressIdentifier+'/'+(step));
    }
  };

  function getRelativeStep(env,position){
    if(position=="prev"){
      if((env.steps.first-env.params.dispItems)>=0){
        return env.steps.first-env.params.dispItems;
      }else{
        return((env.params.loop)?(env.steps.count-env.params.dispItems):false);
      }
    }else if(position=="next"){
      if((env.steps.first+env.params.dispItems)<env.steps.count){
        return env.steps.first+env.params.dispItems;
      }else{
        return((env.params.loop)?0:false);
      }
    }
  };

  function transition(env,step){
    switch(env.params.effect){
      case"no":
        if(env.params.direction=="vertical"){
          env.$elts.content.css("top",-(env.itemHeight*step)+"px");
        }else{
          env.$elts.content.css("left",-(env.itemWidth*step)+"px");
        }
        break;
      case"fade":
        if(env.params.direction=="vertical"){
          env.$elts.content.hide().css("top",-(env.itemHeight*step)+"px").fadeIn(env.params.animSpeed);
        }else{
          env.$elts.content.hide().css("left",-(env.itemWidth*step)+"px").fadeIn(env.params.animSpeed);
        }
        break;
      default:
        if(env.params.direction=="vertical"){
          env.$elts.content.stop().animate({
            top:-(env.itemHeight*step)+"px"
          },env.params.animSpeed,env.params.slideEasing);
        }else{
          env.$elts.content.stop().animate({
            left:-(env.itemWidth*step)+"px"
          },env.params.animSpeed,env.params.slideEasing);
        }
        break;
    }
  };

  function updateButtonsState(env){    
    if(getRelativeStep(env,"prev")!==false){
      env.$elts.prevBtn.trigger("enable");
    }else{
      env.$elts.prevBtn.trigger("disable");
    }
    if(getRelativeStep(env,"next")!==false){
      env.$elts.nextBtn.trigger("enable");
    }else{
      env.$elts.nextBtn.trigger("disable");
    }
    if(env.params.pagination){
      env.$elts.paginationBtns.removeClass("active", env.params.animSpeed).filter(function(){
        return($(this).data("firstStep")==env.steps.first + 1)
      }).addClass("active", env.params.animSpeed);
    }
  };

  function stopAutoSlide(env){
    if(!!env.autoSlideInterval){
      window.clearInterval(env.autoSlideInterval);
    }
  };

})(jQuery);