/* * 
 * TAB
 * Author: Deo 2010.01.06
 * Param: 
 *	1. [title box id] > [children tagName and (optioins:'.' or '!' or '.'and'!' Element className)]
 *	eg: 
 *		a. [id] > a 
 *		b. [id] > a.test 
 *		c. [id] > a.test!test1
 *	2. [tagName].[content className] eg: div.demoContent
 *	3. [clicked title class]
 *	4. [index - number or 'prev' , 'next' - string]
 *	5. callback, back current index and length - options
 *  6. mouseEvent - Default is click event
 */

function tab( config ) {
	var _settings = {
		title	: '',
		content	: '',
		mouseEvent		: 'click',
		success			: function() {},
		clickedClass	: '',
		showIndex		: 0
	};
	extend( _settings, config );
	
	var titleTag = null, titleClass = null, noTitleClass = null;
	var matchT 		= /(\w+)\s*>\s*(.+)/.exec( _settings.title ), 
		matchC 		= /(\w+)\.(\w+)/.exec( _settings.content ),
		matchTE 	= /(\w+)\.(\w+)/.exec( matchT[2] ), 
		noMatchTE 	= /(\w+)\!(\w+)/.exec( matchT[2] );
	
	if (!matchTE && !noMatchTE) {
		titleTag = matchT[2];
	} else {
		titleTag 	= matchTE? matchTE[1]: noMatchTE[1];
		titleClass 	= matchTE? matchTE[2]: noMatchTE[2];
		noTitleClass= matchTE && noMatchTE? noMatchTE[2]: null;
	}
	
	var	titleList = [], conList = [],
		titleElemList = $( matchT[1] ).getElementsByTagName( titleTag ),
		contElemList  = document.getElementsByTagName( matchC[1] );
	
	// Put into a array
	for (var i = 0; i < titleElemList.length; i ++) {
		var matchTC 	= matchClassName(titleElemList[ i ].className, titleClass),
			noMatchTC 	= matchClassName(titleElemList[ i ].className, noTitleClass);
		
		if ((!matchTE && !noMatchTE) || (matchTE && !noMatchTE && matchTC) || (!matchTE && noMatchTE && !matchTC) || (matchTE && noMatchTE && matchTC && !noMatchTC)) {
			titleList.push( titleElemList[ i ] );
		}
	}
	for(var i = 0; i < contElemList.length; i ++) {
		if ( matchClassName(contElemList[ i ].className, matchC[2]) ) {
			conList.push( contElemList[ i ] );
			hide( contElemList[ i ] );
		}
	}
	
	var totalLen = titleList.length == conList.length? titleList.length: null;
	if (totalLen == null) {  } 
	// If showIndex is string
	if (typeof _settings.showIndex == 'string') {
		for(var i = 0; i < titleList.length; i ++) {
			if(titleList[ i ].className == _settings.clickedClass) break;
		}
		
		if (_settings.showIndex == 'prev') _settings.showIndex = -- i < 0? 0: i;
		if (_settings.showIndex == 'next') _settings.showIndex = ++ i > totalLen? totalLen: i;
	}
	
	// Display the instance element
	resetAll();
	show( conList[ _settings.showIndex ] );
	classEvent(titleList[ _settings.showIndex ], _settings.clickedClass, 'add');
	
	// Click Event of Elements
	each(titleList, function(t, c, i){
		t[ 'on'+ _settings.mouseEvent ] = function(){
			resetAll();
			classEvent(t, _settings.clickedClass, 'add');
			show( c );
			_settings.success(i, totalLen);
		}
	});
	
	function extend( destination, source ) {
		for( var property in source )
			destination[ property ] = source[ property ];
	}
	
	function each(arr, func) { 
		for (var i = 0; i < arr.length; i ++)
			func(titleList[i], conList[i], i);
	}
		
	function show( elem ) { elem.style.display = 'block'; };
	function hide( elem ) { elem.style.display = 'none'; };
	function $( id ) { return document.getElementById( id ); }
		
	// Reset all elements className and style
	function resetAll() {
		for(var i = 0; i < conList.length; i ++) { 
			classEvent(titleList[i], _settings.clickedClass, 'remove');
			hide( conList[ i ] );
		}
	}
	
	function matchClassName(str, matcher) {
		var strArr = str.split(/\s+/);
		for (var i = 0; i < strArr.length; i ++)
			if (strArr[i] == matcher) return true;
		return false;
	}
	
	// Element className event
	function classEvent(elem, className, type) {
		var arr = [], map = {}, isClass = false, hasClass = elem.className.split(" ");
		for (var i = 0; i < hasClass.length; i ++) {
			if (hasClass[i] != className) { map[ hasClass[i] ] = hasClass[i]; }
			else { isClass = true; }
			arr.push( hasClass[i] );
		}
		if (type == 'add' && !isClass) 	{ arr.push( className ); }
		if (type == 'remove') 			{ arr = []; for (var key in map) { arr.push( key ); } }
		elem.className = arr.join(" ").replace(/^\s*|\s*$/g,'');
	}
	
	_settings.success(_settings.showIndex, totalLen);
}
