/**
 * @fileOverview tab widget
 * 通用tab切换代码，不依赖于HTML结构
 * 原理：一个tab对象分为控制部分(trigger)，内容部分(sheet)。当trigger被触发时，显示对应的sheet。
 * 使用：
 * <ul id="t">
 *  <li id="t1"></li>
 *  <li id="t2"></li>
 * </ul>
 * <div id="s">
 *  <div id="s1"></div>
 *　<div id="s2"></div>
 * </div>
 * 编码
 * 示例1 var tab = new Tab($D.get('t').getElementsByTagName('li'),$D.get('s').getElementsByTagName('div'));
 * 示例2 var tab = new Tab(['t1','t2'],['s1','s2']);
 * 示例3 var tab = new Tab(['t1','t2'],['s1','s2'],{ triggerEvent:'mouseover',slideEnabled:true});
 * 扩展：已经实现自动切换功能(默认关闭)，另外可以通过onShow自定义事件扩展。
 */

var Tab;

(function(){
var $D = YAHOO.util.Dom;
var	$E = YAHOO.util.Event;
var	$CE = YAHOO.util.CustomEvent;
												
Tab = function(triggers,sheets,config){
	this.tabs = [];             //tab的集合
	this.currentTab = null;     //当前tab
	this.config = {
		defaultIndex : 0,       //默认的tab索引
		triggerEvent : 'click', //默认的触发事件
		slideEnabled : false,   //是否自动切换
		slideInterval : 3000,   //切换时间间隔
		slideDelay : 300,       //鼠标离开tab继续切换的延时
		autoInit : true,        //是否自动初始化
		onShow:function(){ }    //默认的onShow事件处理函数
	};

	this.setConfig(config);

	this.onShow = new $CE('onShow', this);//切换完成的自定义事件
	this.onShow.subscribe(this.config['onShow']);

	if(triggers && sheets) {
		this.addRange(triggers,sheets);
		if(this.config.autoInit) this.init();
	}
};

Tab.prototype = {
	/**
	 * 设置config
	 * @param {object} config 配置项如{'slideEnabled':true,'defaultIndex':0,'autoInit':false}
	 */
	setConfig:function(config){
		if(!config) return;
		for(var i in config){
			this.config[i] = config[i];
		}
	},
	/**
	 * 增加tab
	 * @param {string|HTMLElement} trigger
	 * @param {string|HTMLElement} sheet
	 * */
	add:function(trigger,sheet){
		trigger = $D.get(trigger);
		sheet = $D.get(sheet);
		if(trigger && sheet) {
			this.tabs.push({'trigger' : trigger, 'sheet' : sheet});
		}
	},
	/**
	 * 增加tab数组
	 * @param {array} triggers HTMLElement数组
	 * @param {array} sheets HTMLElement数组
	 * */
	addRange:function(triggers, sheets){
		if(!triggers||!sheets) return;
		if(triggers.length && sheets.length && triggers.length == sheets.length){
			for(var i = 0, len = triggers.length; i < len; i++){
				this.add(triggers[i],sheets[i]);
			}
		}
	},
	/**
	 * 设置tab为当前tab并显示
	 * @param {object} tab  tab对象 {trigger:HTMLElement,sheet:HTMLElement}
	 * */
	select:function(tab){
		if(!tab || tab == this.currentTab) return;
		if(this.currentTab){
			$D.removeClass(this.currentTab.trigger, 'current');
			this.currentTab.sheet.style.display = 'none';
		}
		this.currentTab = tab;
		this.show();
	},
	/**
	 * 显示当前被选中的tab
	 * */
	show:function(){
		$D.addClass(this.currentTab.trigger, 'current');
		this.currentTab.sheet.style.display = 'block';
		this.onShow.fire(this.currentTab);
	},
	/**
	 * 自动切换
	 * */
	slide:function(){
		var	config = this.config,
			_this = this,
			intervalId,
			delayId;
		$D.batch(this.tabs, function(tab){
			$E.on([tab.trigger,tab.sheet], 'mouseover' , clear);
			$E.on([tab.trigger,tab.sheet], 'mouseout' , delay);
		});
		start();
		function start() {
			var i = _this.indexOf(_this.currentTab);
			if( i == -1 ) return;
			intervalId = window.setInterval(function(){
				var tab = _this.tabs[ ++i % _this.tabs.length ];
				if(tab){
					_this.select(tab);
				}
			},config['slideInterval']);
		}
		function clear() {
			window.clearTimeout(delayId);
			window.clearInterval(intervalId);	
		}
		function delay() {
			delayId = window.setTimeout(start,config['slideDelay']);
		}
	},
	/**
	 * 获取tab在tabs数组中的索引
	 * @param {object} tab  tab对象 {trigger:HTMLElement,sheet:HTMLElement}
	 * */
	indexOf:function(tab){
		for(var i = 0, len = this.tabs.length; i < len; i++){
			if(tab == this.tabs[i])
				return i;
		}
		return -1;
	},
	/**
	 * 初始化函数
	 * */
	init:function(){
		var config = this.config,
			_this = this;
		$D.batch(this.tabs,function(tab){
			$E.on(tab.trigger,config['triggerEvent'], function(){
				_this.select.call(_this,tab);
			});
			tab.sheet.style.display = 'none';
		});
		this.select(this.tabs[config['defaultIndex']]);
		if(config['slideEnabled']) this.slide();
	}
};

})();

