/* -------------------------------------------------------------------------- */
/** 
 *    @fileoverview
 *       Tab View Control
 *
 *    @version rev003.2007-07-06
 *    @requires common.js
 *    @requires rollover.js (when using tab images)
 *    @requires tabView.css
 */
/* -------------------------------------------------------------------------- */


var BA_TABVIEW_AUTOSETUP_INSTANCES = [];



/* -------------------- Settings for BATabViewAutoSetup -------------------- */

var BA_TABVIEW_AUTOSETUP_ENABLED            = true;
var BA_TABVIEW_AUTOSETUP_ADJUST_HEIGHT      = true;
var BA_TABVIEW_AUTOSETUP_HIDE_SINGLED_TAB   = true;
var BA_TABVIEW_AUTOSETUP_BASENODE_NODENAME  = 'div';
var BA_TABVIEW_AUTOSETUP_BASENODE_CLASSNAME = 'BATabView';



/* -------------------- Settings for BATabView -------------------- */

var BA_TABVIEW_TABIMAGE_STATUSSET = {
	'stay'   : '_s' ,
	'hover'  : '_o' ,
	'normal' : ''
};
var BA_TABVIEW_TABNODES_CLASSNAME         = 'tab-ll';
var BA_TABVIEW_BASENODE_ENABLED_CLASSNAME = 'pseudo-enabled';
var BA_TABVIEW_CURRENTPANE_CLASSNAME      = 'pseudo-current';
var BA_TABVIEW_IS_SINGLE_PANE_CLASSNAME   = 'has-single-nnew';



/* -------------------- Constructor : BATabView -------------------- */

function BATabView(node, adjustHeight) {
	this.node         = node;
	this.nnews        = [];
	this.nnewHeight   = 0;
	this.adjustHeight = adjustHeight;

	if (arguments.length) this.init();
}

BATabView.prototype = {
	init : function() {
		if (!this.node) {
			throw 'BATabView.init: base element node is not specified.';
		} else {
			var nodes = this.node.getElementsByClassNameBA(BA_TABVIEW_TABNODES_CLASSNAME);
			nodes.forEach(function(node) {
				new BATabViewPane(node, this);
			}, this);
			if (this.nnews.every(function(nnew) { return !nnew.isCurrent })) {
				this.switchTo(this.nnews[0]);
			}
			if (this.nnews.length == 1) {
				this.node.appendClassNameBA(BA_TABVIEW_IS_SINGLE_PANE_CLASSNAME);
			}
//			tabBlock.normalizeTextNodeBA(true); // measuring to MacIE, but this crashes MacIE...
		}
	},

	addPane : function(nnew) {
		if (this.nnews.indexOf(nnew) < 0) {
			this.nnews.push(nnew);
			this.adjustPaneHeight();
			this.node.appendClassNameBA(BA_TABVIEW_BASENODE_ENABLED_CLASSNAME);
		}
	},

	getPaneHeight : function() {
		this.nnewHeight = 0;
		this.nnews.forEach(function(nnew) { this.nnewHeight = Math.max(this.nnewHeight, nnew.getHeight()) }, this);
		return this.nnewHeight;
	},
	
	setPaneHeight : function(height) {
		if (typeof height != 'number' || height < 0) {
			throw 'BATabView.setPaneHeight: first argument must be a positive integer or 0.';
		} else {
			this.nnews.forEach(function(nnew) { nnew.setHeight(height) });
			this.nnewHeight = height;
		}
	},

	adjustPaneHeight : function() {
		if (this.adjustHeight) {
			this.setPaneHeight(this.getPaneHeight());
		}
	},

	switchTo : function(nnew) {
		var idx = this.nnews.indexOf(nnew);
		if (idx != -1) {
			this.nnews.forEach(function(_nnew) { _nnew.hide() });
			this.nnews[idx].visible();
		}
	}
}



/* -------------------- Constructor : BATabViewPane -------------------- */

function BATabViewPane(tabNode, parentView) {
	this.node       = {
		tab  : tabNode,
		nnew : null
	};
	this.parentView = parentView;
	this.tabImage   = null;
	this.isCurrent  = false;
	this.nnewHeight = 0;

	if (arguments.length) this.init();
}

BATabViewPane.prototype = {
	init : function() {
		if (this.node.tab) {
			var anchor = (this.node.tab.nodeName.toLowerCase() == 'a') ?
			             	this.node.tab :
			             	this.node.tab.getElementsByTagNameBA('a')[0];
			if (anchor) {
				this.node.nnew = document.getElementByIdBA(anchor.getAttributeBA('href').split('#')[1]);
				if (this.node.nnew) {
					this.isCurrent = (this.node.tab .hasClassNameBA(BA_TABVIEW_CURRENTPANE_CLASSNAME) &&
					                  this.node.nnew.hasClassNameBA(BA_TABVIEW_CURRENTPANE_CLASSNAME));
					this.initTabImage(anchor.getElementsByTagNameBA('img')[0]);
					this.parentView.addPane(this);
					anchor.addEventListenerBA('click', this.tabClicked, this);
					
					// aware of a behavior of BASmoothScroll.
					if (typeof BASmoothScroll == 'function' && typeof BA_SMOOTHSCROLL_IGNORE_NODE_CNAME == 'string') {
						anchor.appendClassNameBA(BA_SMOOTHSCROLL_IGNORE_NODE_CNAME);
					}
				}
			}
		}
	},

	initTabImage : function(imgNode) {
		if (imgNode) {
			if (typeof BARollover == 'function') {
				if (typeof BA_TABVIEW_TABIMAGE_STATUSSET.hover != 'string') {
					BA_TABVIEW_TABIMAGE_STATUSSET.hover = BA_TABVIEW_TABIMAGE_STATUSSET.normal;
				}
				if (typeof BA_TABVIEW_TABIMAGE_STATUSSET.stay_hover != 'string') {
					BA_TABVIEW_TABIMAGE_STATUSSET.stay_hover = BA_TABVIEW_TABIMAGE_STATUSSET.stay;
				}
				this.tabImage = new BARollover(imgNode, BA_TABVIEW_TABIMAGE_STATUSSET);
				imgNode.addEventListenerBA('mouseover', this.setTabImageToHover  , this);
				imgNode.addEventListenerBA('mouseout' , this.setTabImageToDefault, this);
				if (this.isCurrent) {
					this.setTabImageToStay();
				}
			}
		}
	},

	tabClicked : function(e) {
		this.parentView.switchTo(this);
//		e.currentTarget.blur();
		e.preventDefault();
	},

	setTabImageToDefault : function() {
		if (this.tabImage) {
			this.tabImage.setStatus(this.isCurrent ? 'stay' : 'normal');
		}
	},

	setTabImageToHover : function() {
		if (this.tabImage) {
			this.tabImage.setStatus(this.isCurrent ? 'stay_hover' : 'hover');
		}
	},

	setTabImageToStay : function() {
		if (this.tabImage && this.isCurrent) {
			this.tabImage.setStatus('stay');
		}
	},

	getHeight : function() {
		this.node.nnew.appendClassNameBA(BA_TABVIEW_CURRENTPANE_CLASSNAME);
		this.node.nnew.style.height = 'auto';
		var height = this.node.nnew.offsetHeight / BAGetZoomRatio();
		this.setHeight(this.nnewHeight);
		if (!this.isCurrent) {
			this.node.nnew.removeClassNameBA(BA_TABVIEW_CURRENTPANE_CLASSNAME);
		}
		return height;
	},
	
	setHeight : function(height) {
		if (typeof height != 'number' || height < 0) {
			throw 'BATabViewPane.setHeight: first argument must be a positive integer or 0.';
		} else {
			var ptn   = /px$/;
			var props = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
			var node  = this.node.nnew;
			if (props.every(function(prop) { return ptn.test(node.getCurrentStyleBA(prop)) })) {
				props.forEach(function(prop) { height -= parseInt(node.getCurrentStyleBA(prop)) });
			}
			if (height > 0) {
				this.node.nnew.style.height = height + 'px';
				this.nnewHeight = height;
			}
		}
	},
	
	visible : function() {
		if (this.node.tab && this.node.nnew) {
			this.isCurrent = true;
			this.node.tab .appendClassNameBA(BA_TABVIEW_CURRENTPANE_CLASSNAME);
			this.node.nnew.appendClassNameBA(BA_TABVIEW_CURRENTPANE_CLASSNAME);
			this.setTabImageToStay();
		}
	},

	hide : function() {
		if (this.node.tab && this.node.nnew) {
			this.isCurrent = false;
			this.node.tab .removeClassNameBA(BA_TABVIEW_CURRENTPANE_CLASSNAME);
			this.node.nnew.removeClassNameBA(BA_TABVIEW_CURRENTPANE_CLASSNAME);
			this.setTabImageToDefault();
		}
	}
}






/* -------------------- Function : BATabViewAutoSetupPrepare -------------------- */

function BATabViewAutoSetupPrepare() {
	if (BA.ua.isOpera) return;

	var sheet  = document.styleSheets[0];
	var seltxt = [BA_TABVIEW_AUTOSETUP_BASENODE_NODENAME, BA_TABVIEW_AUTOSETUP_BASENODE_CLASSNAME].join('.');
	var rule   = '{ display: none }';

	if (BA.ua.isSafari) {
		// Safari
		var style  = new BATag('style', { type : 'text/css' });
		style.appendChildBA(seltxt + rule);
		document.write(style.toString());
	} else if (sheet.insertRule) {
		// Std DOM. (opera causes crash)
		sheet.insertRule(seltxt + rule, sheet.cssRules.length);
	} else if (sheet.addRule) {
		// IE
		sheet.addRule(seltxt, rule);
	}
}



/* -------------------- Function : BATabViewAutoSetup -------------------- */

function BATabViewAutoSetup() {
	if (BA_TABVIEW_AUTOSETUP_ENABLED && !BAAlreadyApplied(arguments.callee)) {
		var nodes = document.getElementsByClassNameBA(BA_TABVIEW_AUTOSETUP_BASENODE_CLASSNAME, BA_TABVIEW_AUTOSETUP_BASENODE_NODENAME);
		nodes.forEach(function(node) {
			BA_TABVIEW_AUTOSETUP_INSTANCES.push(new BATabView(node, BA_TABVIEW_AUTOSETUP_ADJUST_HEIGHT));
		});
		if (BA.ua.isGecko) {
			window.addEventListenerBA('load', function() {
				BA_TABVIEW_AUTOSETUP_INSTANCES.forEach(function(tabView) { tabView.adjustPaneHeight() });
			});
		}
	}
}






/* -------------------- Main : register start-up -------------------- */

if (typeof BA == 'object' && BA.ua.DOMok) {
	BATabViewAutoSetupPrepare();
	BAAddOnload(BATabViewAutoSetup);
}
