/*
  Plugin for the tabbed component to add controls (Play,Pause,Stop,Prev,Next,Show) and auto-play functions.

  // Example Usage:
  jQuery(function($){ 

    $('#my_tab_id').autoplay({
      activeClass : 'selected',   // The class name to use when a control is selected.
      autoScrollSpeed : 5500,     // The number of seconds between transitions.
      addControls : true,         // Set to true to add "Play" and "Pause" buttons.
      loop : true,                // Set to true to keep cycling when you reach the end, false to end at the last item.
      maxCycles: null,            // Maximum number of times to cycle through, or null to repeat forever.
      autoPause: true             // Set to true to pause the player when a user selects a specific image to view.
    });

  });

  // You can also call methods on the tab container, such as:
  var player = $('#my_tab_id').autoplay();      // Get the player object
  player.play();                  // Set the player to auto-play
  player.pause();                 // Stop the player if it's playing, or Start the player if it's paused.
  player.stop();                  // Stop the player from auto-playing.
  player.next();                  // Advance to the next tab.
  player.prev();                  // Show the previous tab.
  player.show(index);             // Show the tab at the passed index, starting at 0 (index = 0 to show the first tab)
  var size = player.size();       // Get the total number of tabs.
  
 
  @author Ben Barber (bbarber@i2rd.com)
  @require jquery.js, cms-tabcontainer.js
 */
(function($){
$.fn.autoplay = function(conf) {
  var opts = {
    activeClass : 'selected',
    addControls : true,
    autoScrollSpeed : 5000,
    play : '.play',
    pause : '.pause',
    useNumbers : false,
    loop : true,
    maxCycles : null,
    autoPause : true,
    stop : '.stop',
    next : '.next',
    prev : '.prev'
// These options aren't enabled.
//    navItems : '',
//    transitionSpeed : 3600,
//    effect : null
  };

  $.extend(opts, conf);

  if (opts.effect != null) {
     if(typeof opts.effect == 'string') {
       $.extend(cms.TabContainer.prototype, cms.TabContainer.Effects[opts.effect]);
     } else {
       $.extend(cms.TabContainer.prototype, opts.effect); 
     }
  }

  var api;
  this.each(function() {

    api = $.data(this, "autoplay");
    if (api) return;
    var cycles = 0;
    var tabComponent = null;
    for (var i in cms.tabcontainers) {
      if (this === cms.tabcontainers[i].container) {
        tabComponent = cms.tabcontainers[i];
        break;
      }
    }
    if (tabComponent == null) return;
    if (tabComponent.tabs.length < 2) return;

    var container = $(tabComponent.container); 
    if (opts.addControls) {
       container.prepend('<div class="tab-controls"><div class="play">Play</div><div class="pause">Pause</div></div>');
    }
    if (opts.useNumbers) {
      container.find(".tab-items span.label").each(function(i){
        $(this).text(i + 1);
      }); 
    }

    var paused = true;
    var ap = null;

    var autoPlay = function() {
      window.clearTimeout(ap);
      if (!paused) {
        _next();
        cont();
      }
    };
    var current = function() {
      var items =  container.find(".tab-items li");
      var selected =  container.find("li.tab-selected");
      var idx = items.index(selected);
      return idx;
    };
    var size = function() {
      return tabComponent.tabs.length;
    };
    var show = function(idx) {
      stop();
      _show(idx);
      if (!opts.autoPause)
        autoPlay();
    };
    var _show = function(idx) {
      idx = Math.max(0, Math.min(idx, tabComponent.tabs.length - 1));
      tabComponent.setActiveTab_(idx);
    };
    var next = function() {
      stop();
      _next(); 
    };
    var _next = function() {
      var mx = tabComponent.tabs.length - 1; 
      var cur = current();
      var isLast = (++cur > mx);
      if (isLast && paused === false)
        cycles++;
      if (isLast && opts.maxCycles !== null && opts.maxCycles <= cycles)
        stop();
      if (!isLast || opts.loop === true)
        tabComponent.setActiveTab_(isLast ? 0 : cur);
    };
    var prev = function() {
      stop();
      _prev();
    };
    var _prev = function() {
      var mx = tabComponent.tabs.length - 1;
      var cur = current();
      tabComponent.setActiveTab_((--cur < 0) ? mx : cur);
    };
    var cont = function() {
      ap = window.setTimeout(autoPlay, opts.autoScrollSpeed);
    };
    var start = function() {
      paused = false;
      container.find(opts.play).addClass(opts.activeClass);
      cont();
    };
    var stop = function() {
      paused = true;
      container.find(opts.pause).addClass(opts.activeClass);
      container.find(opts.play).removeClass(opts.activeClass);
    };
    var play = function() {
      if (paused) {
        container.find(opts.play).addClass(opts.activeClass);
        container.find(opts.pause).removeClass(opts.activeClass);
        paused = false;
        autoPlay();
      }
    };
    var pause = function() {
      if (paused) {
        play();
      } else {
        stop();
      }
    };

    container.find(opts.play).click(play);
    container.find(opts.pause).click(pause);
    container.find(opts.next).click(next);
    container.find(opts.prev).click(prev);
    container.find(opts.stop).click(stop);

    // Expose functions to public API
    api = {
      play : play,
      pause : pause,
      stop : stop,
      prev : prev,
      next : next,
      show : show,
      size : size
    };
    // Attach API to element
    tabComponent.AutoPlay = api;
    $.data(this, "autoplay", api);

    start();
  });

  // This is only the controls for the last object.
  return api;

};

// I really don't like this, but i don't know how else to pause
// the auto-play when a specific item is clicked.
cms.TabContainer.prototype.showTab = function(evt){
  var selectedTabItem = this.getEventSource(evt, "li");
  this.setActiveTab($(selectedTabItem).parent().find('li').index(selectedTabItem));
}; 
cms.TabContainer.prototype.setActiveTab_ = cms.TabContainer.prototype.setActiveTab;
cms.TabContainer.prototype.setActiveTab = function(idx, persist) {
  // Route through auto-play's API
  if (this.hasOwnProperty("AutoPlay")) {
    this.AutoPlay.show(idx);
  } else {
    this.setActiveTab_(idx, persist);
  }
};

})(jQuery);

/**
 * cms-tab-effects.js
 * 
 * Provides custom effects for the Tab Component's show/hide functions
 * Usage: 
 *
 *   jQuery.extend(cms.TabContainer.prototype, cms.TabContainer.Effects.VerticalSlide);
 *
 * @author Ben Barber (bbarber@i2rd.com)
 * @require cms-tabcontainer.js, jquery.js
 */
(function($){

  cms.TabContainer.Effects = {
    VerticalSlide : {
      showElement: function(el) {
        $(el).slideDown("slow");
      },
      hideElement: function(el) {
        $(el).slideUp("slow");
      }
    },
  
    /**
     * Requires that the tab-content be absolutely positioned, since both shown and hidden tabs
     * visible in the DOM at the same time.
     */ 
    FadeBlend: {
      showElement: function(el) {
        if (!el.__tabInitted) {
          el.style.display = "block";
          el.__tabInitted = true;
        } else {
            $(el).css("display", "block").animate({opacity: "1"}, "slow");
        }
      },
      hideElement: function(el) {
        if (!el.__tabInitted) {
          el.style.display = "none";
          $(el).css('opacity', 0);
          el.__tabInitted = true;
        } else {
          $(el).animate({opacity: "0"}, "slow", function(){
              $(el).css("display", "none");
          });
        } 
      }
    },

    // Requires that the tab-content be absolutely positioned, since both shown and hidden tabs
    // visible in the DOM at the same time.
    Fade: {
      showElement: function(el) {
        if (!el.__tabInitted) {
          el.style.display = "block";
          el.__tabInitted = true;
        } else {
          cms.TabContainer.Effects.__queue.push(function(){
            $(el).css("display", "block").animate({opacity: "1"}, "slow");
          });
        }
      },
      hideElement: function(el) {
        if (!el.__tabInitted) {
          el.style.display = "none";
          $(el).css('opacity', 0);
          el.__tabInitted = true;
        } else {
          $(el).animate({opacity: "0"}, "slow", function(){
              $(el).css("display", "none");
              cms.TabContainer.Effects.__processQueue();
          });
        } 
      }
    },

    VerticalShade : {
      showElement: function(el) {
        if (!el.__tabInitted) {
          el.style.display = "block";
          el.__tabInitted = true;
        } else {
          cms.TabContainer.Effects.__queue.push(function(){
            $(el).slideDown("slow");
          });
        }
      },
      hideElement: function(el) {
        if (!el.__tabInitted) {
          el.style.display = "none";
          el.__tabInitted = true;
        } else {
          $(el).slideUp("medium", function(){
            window.setTimeout(cms.TabContainer.Effects.__processQueue, 600);
          });
        }
      }
    },
    __queue : [],
    __processQueue : function() {
      if (cms.TabContainer.Effects.__queue.length > 0) {
        var queued;
        while((queued = cms.TabContainer.Effects.__queue.pop()))
          queued.call();
      }
    }
  };

})(jQuery);

