/* -------------------------------------------------------------------------- */
/** 
 *    @fileoverview
 *       Tab View Control
 *
 *    @version rev001.2009-01-24
 *    @requires common.js
 *    @requires rollover.js (when using tab images)
 *    @requires tabView.css
 */
/* -------------------------------------------------------------------------- */


var CWJ_TABVIEW_AUTOSETUP_INSTANCES = [];



/* -------------------- Settings for CWJTabViewAutoSetup -------------------- */

var CWJ_TABVIEW_AUTOSETUP_ENABLED            = true;
var CWJ_TABVIEW_AUTOSETUP_ADJUST_HEIGHT      = true;
var CWJ_TABVIEW_AUTOSETUP_HIDE_SINGLED_TAB   = true;
var CWJ_TABVIEW_AUTOSETUP_CWJSENODE_NODENAME  = 'div';
var CWJ_TABVIEW_AUTOSETUP_CWJSENODE_CLASSNAME = 'tabView';



/* -------------------- Settings for CWJTabView -------------------- */

var CWJ_TABVIEW_TABIMAGE_STATUSSET = {
	'stay'   : '_s' ,
	'hover'  : '_o' ,
	'normal' : ''
};
var CWJ_TABVIEW_TABNODES_CLASSNAME         = 'tabView-tab';
var CWJ_TABVIEW_CWJSENODE_ENABLED_CLASSNAME = 'pseudo-enabled';
var CWJ_TABVIEW_CURRENTPANE_CLASSNAME      = 'pseudo-current';
var CWJ_TABVIEW_IS_SINGLE_PANE_CLASSNAME   = 'has-single-pane';



/* -------------------- Constructor : CWJTabView -------------------- */

function CWJTabView(node, adjustHeight) {
	this.node         = node;
	this.panes        = [];
	this.paneHeight   = 0;
	this.adjustHeight = adjustHeight;

	if (arguments.length) this.init();
}

CWJTabView.prototype = {
	init : function() {
		if (!this.node) {
			throw 'CWJTabView.init: base element node is not specified.';
		} else {
			var nodes = this.node.getElementsByClassNameCWJ(CWJ_TABVIEW_TABNODES_CLASSNAME);
			nodes.forEach(function(node) {
				new CWJTabViewPane(node, this);
			}, this);
			if (this.panes.every(function(pane) { return !pane.isCurrent })) {
				this.switchTo(this.panes[0]);
			}
			if (this.panes.length == 1) {
				this.node.appendClassNameCWJ(CWJ_TABVIEW_IS_SINGLE_PANE_CLASSNAME);
			}
//			tabBlock.normalizeTextNodeCWJ(true); // measuring to MacIE, but this crashes MacIE...
		}
	},

	addPane : function(pane) {
		if (this.panes.indexOf(pane) < 0) {
			this.panes.push(pane);
			this.adjustPaneHeight();
			this.node.appendClassNameCWJ(CWJ_TABVIEW_CWJSENODE_ENABLED_CLASSNAME);
		}
	},

	getPaneHeight : function() {
		this.paneHeight = 0;
		this.panes.forEach(function(pane) { this.paneHeight = Math.max(this.paneHeight, pane.getHeight()) }, this);
		return this.paneHeight;
	},
	
	setPaneHeight : function(height) {
		if (typeof height != 'number' || height < 0) {
			throw 'CWJTabView.setPaneHeight: first argument must be a positive integer or 0.';
		} else {
			this.panes.forEach(function(pane) { pane.setHeight(height) });
			this.paneHeight = height;
		}
	},

	adjustPaneHeight : function() {
		if (this.adjustHeight) {
			this.setPaneHeight(this.getPaneHeight());
		}
	},

	switchTo : function(pane) {
		var idx = this.panes.indexOf(pane);
		if (idx != -1) {
			this.panes.forEach(function(_pane) { _pane.hide() });
			this.panes[idx].visible();
		}
	}
}



/* -------------------- Constructor : CWJTabViewPane -------------------- */

function CWJTabViewPane(tabNode, parentView) {
	this.node       = {
		tab  : tabNode,
		pane : null
	};
	this.parentView = parentView;
	this.tabImage   = null;
	this.isCurrent  = false;
	this.paneHeight = 0;

	if (arguments.length) this.init();
}

CWJTabViewPane.prototype = {
	init : function() {
		if (this.node.tab) {
			var anchor = (this.node.tab.nodeName.toLowerCase() == 'a') ?
			             	this.node.tab :
			             	this.node.tab.getElementsByTagNameCWJ('a')[0];
			if (anchor) {
				this.node.pane = document.getElementByIdCWJ(anchor.getAttributeCWJ('href').split('#')[1]);
				if (this.node.pane) {
					this.isCurrent = (this.node.tab .hasClassNameCWJ(CWJ_TABVIEW_CURRENTPANE_CLASSNAME) &&
					                  this.node.pane.hasClassNameCWJ(CWJ_TABVIEW_CURRENTPANE_CLASSNAME));
					this.initTabImage(anchor.getElementsByTagNameCWJ('img')[0]);
					this.parentView.addPane(this);
					anchor.addEventListenerCWJ('click', this.tabClicked, this);
					
					// aware of a behavior of CWJSmoothScroll.
					if (typeof CWJSmoothScroll == 'function' && typeof CWJ_SMOOTHSCROLL_IGNORE_NODE_CNAME == 'string') {
						anchor.appendClassNameCWJ(CWJ_SMOOTHSCROLL_IGNORE_NODE_CNAME);
					}
				}
			}
		}
	},

	initTabImage : function(imgNode) {
		if (imgNode) {
			if (typeof CWJRollover == 'function') {
				if (typeof CWJ_TABVIEW_TABIMAGE_STATUSSET.hover != 'string') {
					CWJ_TABVIEW_TABIMAGE_STATUSSET.hover = CWJ_TABVIEW_TABIMAGE_STATUSSET.normal;
				}
				if (typeof CWJ_TABVIEW_TABIMAGE_STATUSSET.stay_hover != 'string') {
					CWJ_TABVIEW_TABIMAGE_STATUSSET.stay_hover = CWJ_TABVIEW_TABIMAGE_STATUSSET.stay;
				}
				this.tabImage = new CWJRollover(imgNode, CWJ_TABVIEW_TABIMAGE_STATUSSET);
				imgNode.addEventListenerCWJ('mouseover', this.setTabImageToHover  , this);
				imgNode.addEventListenerCWJ('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.pane.appendClassNameCWJ(CWJ_TABVIEW_CURRENTPANE_CLASSNAME);
		this.node.pane.style.height = 'auto';
		var height = this.node.pane.offsetHeight / 1;
		this.setHeight(this.paneHeight);
		if (!this.isCurrent) {
			this.node.pane.removeClassNameCWJ(CWJ_TABVIEW_CURRENTPANE_CLASSNAME);
		}
		return height;
	},
	
	setHeight : function(height) {
		if (typeof height != 'number' || height < 0) {
			throw 'CWJTabViewPane.setHeight: first argument must be a positive integer or 0.';
		} else {
			var ptn   = /px$/;
			var props = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
			var node  = this.node.pane;
			if (props.every(function(prop) { return ptn.test(node.getCurrentStyleCWJ(prop)) })) {
				props.forEach(function(prop) { height -= parseInt(node.getCurrentStyleCWJ(prop)) });
			}
			if (height > 0) {
				this.node.pane.style.height = height + 'px';
				this.paneHeight = height;
			}
		}
	},
	
	visible : function() {
		if (this.node.tab && this.node.pane) {
			this.isCurrent = true;
			this.node.tab .appendClassNameCWJ(CWJ_TABVIEW_CURRENTPANE_CLASSNAME);
			this.node.pane.appendClassNameCWJ(CWJ_TABVIEW_CURRENTPANE_CLASSNAME);
			this.setTabImageToStay();
		}
	},

	hide : function() {
		if (this.node.tab && this.node.pane) {
			this.isCurrent = false;
			this.node.tab .removeClassNameCWJ(CWJ_TABVIEW_CURRENTPANE_CLASSNAME);
			this.node.pane.removeClassNameCWJ(CWJ_TABVIEW_CURRENTPANE_CLASSNAME);
			this.setTabImageToDefault();
		}
	}
}






/* -------------------- Function : CWJTabViewAutoSetupPrepare -------------------- */

function CWJTabViewAutoSetupPrepare() {
	if (CWJ.ua.isOpera) return;

	var sheet  = document.styleSheets[0];
	var seltxt = [CWJ_TABVIEW_AUTOSETUP_CWJSENODE_NODENAME, CWJ_TABVIEW_AUTOSETUP_CWJSENODE_CLASSNAME].join('.');
	var rule   = '{ display: none }';

	if (CWJ.ua.isSafari) {
		// Safari
		var style  = new CWJTag('style', { type : 'text/css' });
		style.appendChildCWJ(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 : CWJTabViewAutoSetup -------------------- */

function CWJTabViewAutoSetup() {
	if (CWJ_TABVIEW_AUTOSETUP_ENABLED && !CWJAlreadyApplied(arguments.callee)) {
		var nodes = document.getElementsByClassNameCWJ(CWJ_TABVIEW_AUTOSETUP_CWJSENODE_CLASSNAME, CWJ_TABVIEW_AUTOSETUP_CWJSENODE_NODENAME);
		nodes.forEach(function(node) {
			CWJ_TABVIEW_AUTOSETUP_INSTANCES.push(new CWJTabView(node, CWJ_TABVIEW_AUTOSETUP_ADJUST_HEIGHT));
		});
		if (CWJ.ua.isGecko) {
			window.addEventListenerCWJ('load', function() {
				CWJ_TABVIEW_AUTOSETUP_INSTANCES.forEach(function(tabView) { tabView.adjustPaneHeight() });
			});
		}
	}
}






/* -------------------- Main : register start-up -------------------- */

if (typeof CWJ == 'object' && CWJ.ua.isDOMReady) {
	CWJTabViewAutoSetupPrepare();
	CWJAddOnload(CWJTabViewAutoSetup);
}