/*
 * File: topdeals.js
 * Description: Top deals slider behaviors
 */

/*
 * Usage:
 * topdeals.init([params]);
 *
 * Examples:
 * topdeals.init(); -- Use all defaults
 * topdeals.init({autoPlay: false}); -- Start without autoplay
 * topdeals.init({randomInitItem: true, autoPlay: false}); -- Start on a random image and without autoplay
 */

topdeals = new function() {
  
  /* Self reference for closures */
  var self = this;

  /* Configuration properties */
  this.initItemIdx = 1;
  this.randomInitItem = false;
  this.autoPlay = true; 
  this.speed = 400;
  this.autoPlayInterval = "5000";
  this.autoPlayPauseInterval = "5000";
  this.dealsSel = "#topDealsList li";
  this.dealsListSel = "#topDealsList ul";
  this.dealsSliderSel = "#dealsSlider ul";
  this.dealsSliderPrevBtnSel = "#dealsSlider .prevBtn";
  this.dealsSliderNextBtnSel = "#dealsSlider .nextBtn";

  /* Additional object members */
  this.currentDealIdx = null;
  this.currentSliderIdx = null;
  this.dealsListItems = [];
  this.dealsCarousel = null;
  this.autoPlayTimer = null;
  this.isInit = false;
  this.carouselOptions = {};
  

  /* 
   * Initializes object 
   */
  this.init = function(params) {
    /* Set passed paramters */
    if(params){
      for(key in params){
        this[key] = params[key];
      }
    }
    /* Only allow initialization once */
    if(!this.isInit){
      this.isInit = true;
      if($(this.dealsSel).length){
        this.hideDeals();
        this.truncateDealDescriptions();
        this.getItems();
        this.setStartItem();
        this.setCarouselOptions();
        $(this.dealsSliderSel).jcarousel(this.carouselOptions);
        this.setActiveDeal(this.initItemIdx);
        this.attachPrevNextBtnActions();
        if (this.autoPlay) {
          this.startAutoPlay();        
        }
      }
    }
  };


  /* 
   * Hides all deals
   */
  this.hideDeals = function() {
    $(this.dealsSel).hide();
  };

  /*
   * Trunctate the deal descriptions
   */
  this.truncateDealDescriptions = function() {
    var dealsElems = $(this.dealsSel);
    for (var i=0; i < dealsElems.length; i++) {
      var linkHref = $(dealsElems[i]).find(".title a").attr("href");

		var t = $(dealsElems[i]).find(".description p").html();
		var len = 180;
		if (t.length > len) {
			t = t.substring(0, len).replace(/\w+$/, '') + "... <a href='"+linkHref+"' class='more'>(see more)</a>";
			$(dealsElems[i]).find(".description p").html(t);
		}
    }
  };

  /* 
   * Gets the array of deal items
   */
  this.getItems = function() {
    var dealsElems = $(this.dealsSel);
    var item = null;
    for (var i=0; i < dealsElems.length; i++) {
      item = {idx: null, elm: null, thumbSrc: "", txt: ""}; /* Reset */
      item.idx = i;
      item.elm = dealsElems[i];
      item.thumbSrc = $(dealsElems[i]).find(".thumbnail").attr("src");
      item.txt = $(dealsElems[i]).find(".title").text();
      this.dealsListItems.push(item);
    }
    item = null;
  };

  /* 
   * Sets the initial start item
   */
  this.setStartItem = function(){
    if(this.initItemIdx === null || this.initItemIdx === undefined) {
      this.initItemIdx = 1;
    }
    if(this.randomInitItem && this.dealsListItems && this.dealsListItems.length) {
      this.initItemIdx = Math.floor(Math.random()*this.dealsListItems.length+1);
    }
  };

  /*
   * Sets jCarousel options.
   */
  this.setCarouselOptions = function() {
    this.carouselOptions = {
      scroll: 1,
      animation: self.speed,
      start: self.initItemIdx,
      initCallback: self.carousel_initCallback,
      itemVisibleInCallback: {onBeforeAnimation: self.carousel_itemVisibleInCallback},
      itemVisibleOutCallback: {onAfterAnimation: self.carousel_itemVisibleOutCallback},
      buttonNextHTML: null,
      buttonPrevHTML: null,
      wrap: "circular"
    };
  };

  /* 
   * Attaches the onclick behaviors to the previous and next buttons
   */
  this.attachPrevNextBtnActions = function() {
    $(this.dealsSliderPrevBtnSel).click(function () {
      topdeals.advance(-1, true);
    });
    $(this.dealsSliderNextBtnSel).click(function () {
      topdeals.advance(1, true);
    });
  };

  /* 
   * Starts the autoplay functionality
   */
  this.startAutoPlay = function() {
    if(this.autoPlay) {
      clearInterval(this.autoPlayTimer);
      this.autoPlayTimer = setInterval("topdeals.advance(1)", this.autoPlayInterval);      
    }
  };

  /* 
   * Pauses the autoplay functionality
   */
  this.pauseAutoPlay = function() {
    if(this.autoPlay) {
      clearInterval(this.autoPlayTimer);
      this.autoPlayTimer = setTimeout("topdeals.startAutoPlay()", this.autoPlayPauseInterval);      
    }
  };
  

  /* 
   * Sets the active deal and positions slider. If the "manual" parameter 
   * is true then autoplay will be paused.
   */
  this.setActiveDeal = function(sliderIdx, manual) {
    if(manual && this.autoPlay){
      this.pauseAutoPlay();
    }
    if(this.currentSliderIdx != sliderIdx) {
      var dealIdx = this.dealsCarousel.index(sliderIdx, this.dealsListItems.length)-1;
      var hideSlideDir = "left";
      var showSlideDir = "right";
      var firstRun = false;
      
      /* Determine if this is the first tiem it's being run */
      if(this.currentDealIdx === null) {
        firstRun = true;
      }
      
      /* Reverse slide directions for moving backwards */
      if(sliderIdx < this.currentSliderIdx) {
        hideSlideDir = "right";
        showSlideDir = "left";        
      }

      /* Hide active deal */
      if(this.currentDealIdx !== null) {
        $(this.dealsListItems[this.currentDealIdx].elm).stop(true, true).hide("slide", {direction: hideSlideDir}, this.speed);
      }

      /* Show new deal */
      if(!firstRun) {
        $(this.dealsListItems[dealIdx].elm).stop(true, true).show("slide", {direction: showSlideDir}, this.speed);
      } else {
        $(this.dealsListItems[dealIdx].elm).stop(true, true).show();        
      }

      /* Scroll to new deal */
      if(!firstRun) {
        $(this.dealsSliderSel+" .jcarousel-item-"+this.currentSliderIdx).removeClass("active");
        if(this.dealsCarousel.animating) {
          this.dealsCarousel.list.stop(true, true);
        }
        this.dealsCarousel.scroll(sliderIdx);
      }

      /* Attach hover and active states */
      $(this.dealsSliderSel+" .jcarousel-item").hover(function(){$(this).addClass("hover");},function(){$(this).removeClass("hover");});
      $(this.dealsSliderSel+" .jcarousel-item-"+sliderIdx).addClass("active");

      /* Update active indexes */
      this.currentDealIdx = dealIdx;
      this.currentSliderIdx = sliderIdx;

	  if (manual) {
		  this.pauseAutoPlay();
	  }
    }
  };

  /* 
   * Advances the slider by the specified distance. If the "manual" parameter 
   * is true then autoplay will be paused.
   */
  this.advance = function(dist, manual) {
    if(this.currentSliderIdx !== null){
      this.setActiveDeal(this.currentSliderIdx+dist, manual);      
    }
  };


  /* 
   * Callback methods
   */

  /*
   * Called before a new slider item is made visible. This function adds the content
   * to the new item for the dealsListItems array.
   */
  this.carousel_itemVisibleInCallback = function(carousel, item, i, state, evt) {
    // The index() method calculates the index from a
    // given index who is out of the actual item range.
    var idx = carousel.index(i, self.dealsListItems.length);
    carousel.add(i, self.carousel_getItemHTML(self.dealsListItems[idx - 1], i));
  };

  /*
   * Called after a slider item is made no longer visible. This function removes the 
   * content of the item.
   */
  this.carousel_itemVisibleOutCallback = function(carousel, item, i, state, evt) {
      carousel.remove(i);
  };

  /*
   * Called when the carousel is initialized. It is used to set a reference to
   * the carousel object for later use.
   */
  this.carousel_initCallback = function(carousel) {
    self.dealsCarousel = carousel;
  };


  /*
   * Item html creation helper.
   */
  this.carousel_getItemHTML = function(item, sliderIdx) {
    var output = '<table cellspacing="0" onclick="topdeals.setActiveDeal('+sliderIdx+', true)"><tr><td class="thumbnail"><img src="'+item.thumbSrc+'" alt="thumb" /></td><td class="text">'+item.txt+'</td></tr></table>';
    return output;
  };
  
};

