/* Copyright (c) 2006 Patrick Fitzgerald */
/* http://www.barelyfitz.com/projects/tabber/index.php */

/* 
	modifications 
	- 	no manual <br /> tags. this script will detect the length of the tab texts
		and insert <br /> dynamically
	-	depending on the total number of <br />'s in on tab will set a class name on the
		container
*/

function tabberObj(argsObj) {
    var arg;
    this.div = null;
	this.disableActions = false;
	this.maxTabsStrMaxLength = "100";	
    this.classMain = "tabber";
    this.classMainLive = "tabberlive";
    this.classTab = "tabbertab";
    this.classTabDefault = "tabbertabdefault";
    this.classNav = "tabbernav clearfix";
	this.classNavDbl = "dbl";
    this.classTabHide = "tabbertabhide";
    this.classNavActive = "active";
	this.classNavAfterActive = "after-active";
	this.classNavBeforeActive = "before-active";
	this.classNavFirst = "first";
	this.classNavLast = "last";
    this.titleElements = ['h2', 'h3', 'h4', 'h5', 'h6'];
    this.titleElementsStripHTML = true;
    this.removeTitle = true;
    this.addLinkId = false;
    this.linkIdFormat = '<tabberid>nav<tabnumberone>';
    for (arg in argsObj) {
        this[arg] = argsObj[arg];
    }
    this.REclassMain = new RegExp('\\b' + this.classMain + '\\b', 'gi');
    this.REclassMainLive = new RegExp('\\b' + this.classMainLive + '\\b', 'gi');
    this.REclassTab = new RegExp('\\b' + this.classTab + '\\b', 'gi');
    this.REclassTabDefault = new RegExp('\\b' + this.classTabDefault + '\\b', 'gi');
    this.REclassTabHide = new RegExp('\\b' + this.classTabHide + '\\b', 'gi');
    this.tabs = new Array();
	this.tabsbr = new Array();
    if (this.div) {
		this.init(this.div);
        this.div = null;
    }
}
tabberObj.prototype.init = function(e) {
    var childNodes,
    i,
    i2,
    t,
    defaultTab = 0,
    DOM_ul,
    DOM_li,
    DOM_a,
    aId,
    headingElement;
    if ( ! document.getElementsByTagName) {
        return false;
    }
    if (e.id) {
        this.id = e.id;
    }
    
	if (this.div.className.match(this.REclassMainLive)) {
		this.disableActions = true;
	}
	
	this.tabs.length = 0;
    if (!this.disableActions) {
		childNodes = e.childNodes;  
		for (i = 0; i < childNodes.length; i ++ ) {
			if (childNodes[i].className && childNodes[i].className.match(this.REclassTab)) {
				t = new Object();
				t.div = childNodes[i];
				this.tabs[this.tabs.length] = t;
				if (childNodes[i].className.match(this.REclassTabDefault)) {
					defaultTab = this.tabs.length - 1;
				}
			}
		}
	} else {
		childNodes = e.getElementsByTagName('SPAN');
		for (i = 0; i < childNodes.length; i ++ ) {
			t = new Object();
			t.div = childNodes[i];
			this.tabs[this.tabs.length] = t;
		}
	}
	
    DOM_ul = document.createElement("ul");
    DOM_ul.className = this.classNav;
	// for compatability
	DOM_ul.id = 'page-nav';
	// end compat change
	/*
		preliminary loop to check length of all tabs text
	*/
	tabs_str_len = 0;
	tab_len_ar = new Array();
	
	
	for (i = 0; i < this.tabs.length; i ++ ) {
		
		t = this.tabs[i];
        
		if (!this.disableActions) {
			t.headingText = t.div.title;
		} else {
			t.headingText = t.div.innerHTML;
		}
		
		tab_len_ar.push(t.headingText.length);
		tabs_str_len += t.headingText.length;
	}
	
	/* 
		while the length is greater than max length
		adjust the array by finding which elem is the longest and
		then inserting a <br> in it to chop the length, then return the longest of pre_br<br />post_br 
		in the array... then test the array again.
	*/
	
	this.br_ified = new Array();
	
	while (tabs_str_len > this.maxTabsStrMaxLength) {
		
		/* adjust array func */
		tabs_str_len = this.adjustArray(tab_len_ar, tabs_str_len);
	}
	
	
    for (i = 0; i < this.tabs.length; i ++ ) {
        t = this.tabs[i];
		
		if (!this.disableActions) {
			t.headingText = t.div.title;
		} else {
			t.headingText = t.div.innerHTML;
		}
		
		if (this.removeTitle) {
            t.div.title = '';
        }
		
        if ( ! t.headingText) {
			for (i2 = 0; i2 < this.titleElements.length; i2 ++ ) {
                headingElement = t.div.getElementsByTagName(this.titleElements[i2])[0];
				if (headingElement) {
                    t.headingText = headingElement.innerHTML;
                    if (this.titleElementsStripHTML) {
                        t.headingText.replace(/<br>/gi, " ");
                        t.headingText = t.headingText.replace(/<[^>]+>/g, "");
                    }
                    break;
                }
            }
        }
        if ( !t.headingText) {
            t.headingText = i + 1;
        }
		
        DOM_li = document.createElement("li");
        t.li = DOM_li;
        DOM_a = document.createElement("a");
		DOM_span = document.createElement("span");
        DOM_a.appendChild(DOM_span);
		
		
		//find out if there needs to be a br tag
		// attach text with <br> checking
		
		br_tag = t.headingText.match('hasbr') ? t.headingText.match('hasbr') : false;
		//if (!br_tag)
			//br_tag = t.headingText.match('<br>') ? t.headingText.match('<br>') : false;
		
		if (br_tag) {
			DOM_ul.className = this.classNav + " " + this.classNavDbl;
			
			if (this.disableActions) {
				t.headingText = t.headingText.replace("hasbr", "<br />");
				t.div.innerHTML = t.headingText;
			} else {
				start_br = t.headingText.indexOf(br_tag);
				seg_1 = t.headingText.substring(0, start_br);
				seg_2 = t.headingText.substring(start_br + br_tag[0].length, t.headingText.length);
				DOM_br = document.createElement("br");
				DOM_span.appendChild(document.createTextNode(seg_1));
				DOM_span.appendChild(DOM_br);
				DOM_span.appendChild(document.createTextNode(seg_2));	
			}
		} else {
			if (this.disableActions) {
				tmp = $('page-nav').getElementsByTagName('li');
				tmpClass = tmp[i].className + ' single';
				tmp[i].className = tmpClass;
			}
			DOM_span.appendChild(document.createTextNode(t.headingText));
		}
		
		
		this.tabsbr.push(br_tag);
		
		DOM_a.href = "javascript:void(null);";
        DOM_a.title = t.headingText;
       
	   	if (!this.disableActions)
	   		DOM_a.onclick = this.navClick;
			
        DOM_a.tabber = this;
        DOM_a.tabberIndex = i;
        if (this.addLinkId && this.linkIdFormat) {
            aId = this.linkIdFormat;
            aId = aId.replace(/<tabberid>/gi, this.id);
            aId = aId.replace(/<tabnumberzero>/gi, i);
            aId = aId.replace(/<tabnumberone>/gi, i + 1);
            aId = aId.replace(/<tabtitle>/gi, t.headingText.replace(/[^a-zA-Z0-9\-]/gi, ''));
            DOM_a.id = aId;
        }
        DOM_li.appendChild(DOM_a);
        DOM_ul.appendChild(DOM_li);
    }
	
	if (!this.disableActions) {
    	e.insertBefore(DOM_ul, e.firstChild);
	}
	
    e.className = e.className.replace(this.REclassMain, this.classMainLive);
	
	if (!this.disableActions)
		this.tabShow(defaultTab);
    
	if (typeof this.onLoad == 'function') {
        this.onLoad( {
            tabber: this
        });
    }
	
	// if this is not a normal tabber, set the classname to the
	// exiting dom element 'page-nav'
	if (this.disableActions) {
    	if ($('page-nav')) {
			$('page-nav').className = DOM_ul.className;
		}
	}
	
    return this;
};
tabberObj.prototype.adjustArray = function(tab_len_ar, tabs_str_len) {
	/* 
		find the longest elem and break it at it's first available 'space'
		then replace that longest element in the array with the new longest of the strings
		between part before the <br /> and the part after the <br />
	*/
	
	/* 
		find the longest array index
	*/
	
	var longest = false;
	for (i = 0; i < tab_len_ar.length; i ++ ) {
		if (i == 0)
			longest = i;
		
		if (this.br_ified.indexOf(i) == -1) {
			if (tab_len_ar[i] > tab_len_ar[longest]) {
				longest = i;
			}
		}
	}
	
	if ( this.br_ified.indexOf(longest) == -1 ) {
		t = this.tabs[longest];
		
		/*
			fix the longest elem in tabs array
		*/
		var z = Math.round(t.headingText.length / 2);
		var y = z;
		var spaceFound = false;
		var spaceNum = false;
		
		/*
			find the next available spot to <br />
			before or after the halfway point
		*/
		/* MODIFICATION by ED 04/04/2011 to prevent infinite loop
		while(spaceFound == false) {
			if (t.headingText.charAt(y) == ' ') {
				spaceFound = true;	
				spaceNum = y;
			}
			if (t.headingText.charAt(z) == ' ') {
				spaceFound = true;	
				spaceNum = z;
			}
			z++;
			y--;
		}
		*/
		while ((spaceFound == false) && ((y + z) < t.headingText.length)) {
			if (t.headingText.charAt(y) == ' ') {
				spaceFound = true;	
				spaceNum = y;
			}
			if (t.headingText.charAt(z) == ' ') {
				spaceFound = true;	
				spaceNum = z;
			}
			z++;
			y--;
		}
		if (spaceFound == false) {
			spaceNum = Math.round(t.headingText.length / 2);
		}
		/* END MODIFICATION by ED 04/04/2011 */
		/* 
			set the new header text with br inserted
		*/
		seg_1 = t.headingText.substring(0, spaceNum);
		seg_2 = t.headingText.substring(spaceNum, t.headingText.length);
		
		tab_len_ar[longest] = (seg_2.length > seg_1.length) ? seg_2.length : seg_1.length;
		
		seg_1 += 'hasbr';
		t.headingText = seg_1 + seg_2;
		
		if (!this.disableActions) {
			t.div.title = t.headingText;
		} else {
			t.div.innerHTML = t.headingText;
		}
		
		/* 
			add this index to the array of
			<br />ified elems so to not use it again.
		*/
		this.br_ified.push(longest);
		
		//longest
		
		// return the new length of the tabs strings using the new length of the longest
		// tab which has a <br /> in it.
		var new_tabs_str_len;
		
		for( var i = 0, new_tabs_str_len = 0; i < tab_len_ar.length; new_tabs_str_len+=tab_len_ar[i++] );
		
		//return 50;
		return new_tabs_str_len;
	} else {
		return 0;
	}
};
tabberObj.prototype.navClick = function(event) {
    var rVal,
    a,
    self,
    tabberIndex,
    onClickArgs;
    a = this;
    if ( ! a.tabber) {
        return false;
    }
    self = a.tabber;
    tabberIndex = a.tabberIndex;
    a.blur();
    if (typeof self.onClick == 'function') {
        onClickArgs = {
            'tabber': self,
            'index': tabberIndex,
            'event': event
        };
        if ( ! event) {
            onClickArgs.event = window.event;
        }
        rVal = self.onClick(onClickArgs);
        if (rVal === false) {
            return false;
        }
    }
    self.tabShow(tabberIndex);
    return false;
};
tabberObj.prototype.tabHideAll = function() {
    var i;
    for (i = 0; i < this.tabs.length; i ++ ) {
        this.tabHide(i);
    }
};
tabberObj.prototype.tabHide = function(tabberIndex) {
    var div;
    if ( ! this.tabs[tabberIndex]) {
        return false;
    }
    div = this.tabs[tabberIndex].div;
    if ( ! div.className.match(this.REclassTabHide)) {
        div.className += ' ' + this.classTabHide;
    }
    this.navClearActive(tabberIndex);
    return this;
};
tabberObj.prototype.tabShow = function(tabberIndex) {
    var div;
    if ( ! this.tabs[tabberIndex]) {
        return false;
    }
    this.tabHideAll();
    div = this.tabs[tabberIndex].div;
    div.className = div.className.replace(this.REclassTabHide, '');
    this.navSetActive(tabberIndex);
    if (typeof this.onTabDisplay == 'function') {
        this.onTabDisplay( {
            'tabber': this,
            'index': tabberIndex
        });
    }
    return this;
};
tabberObj.prototype.navSetActive = function(tabberIndex) {
	
	for (var i = 0; i < this.tabs.length; i++)
	{
		if (this.tabsbr[i]) {
			this.tabs[i].li.className = '';
		} else {
			this.tabs[i].li.className = 'single';
		}
	}
	// added first and last class appending
	if (!this.tabsbr[0])
		this.tabs[0].li.className = 'single first';
	else
		this.tabs[0].li.className = 'first';
	
	if (!this.tabsbr[this.tabs.length-1])	
		this.tabs[this.tabs.length-1].li.className = 'single last';
	else
		this.tabs[this.tabs.length-1].li.className = 'last';
	
	if (this.tabs[tabberIndex-1])
	{
		if (this.tabs[tabberIndex-1].li.className != '')
			this.tabs[tabberIndex-1].li.className = this.tabs[tabberIndex-1].li.className+' '+this.classNavBeforeActive;
		else
			this.tabs[tabberIndex-1].li.className = this.classNavBeforeActive;
	}
	
	if (this.tabs[tabberIndex].li.className != '')
		this.tabs[tabberIndex].li.className = this.tabs[tabberIndex].li.className+' '+this.classNavActive;
	else
		this.tabs[tabberIndex].li.className = this.classNavActive;
	
	if (this.tabs[tabberIndex+1])
	{
		if (this.tabs[tabberIndex+1].li.className != '')
			this.tabs[tabberIndex+1].li.className = this.tabs[tabberIndex+1].li.className+' '+this.classNavAfterActive;
		else
			this.tabs[tabberIndex+1].li.className = this.classNavAfterActive;
	}
	
	if (tabberIndex == this.tabs.length-1) {
		if (this.tabs[this.tabs.length-1].li.className.match('single')) {
			this.tabs[this.tabs.length-1].li.className = 'single last-active';
		} else {
			this.tabs[this.tabs.length-1].li.className = 'last-active';
		}
	}
	if (tabberIndex == 0) {
		if (this.tabs[0].li.className.match('single')) {
			this.tabs[0].li.className = 'single first-active';
		} else {
			this.tabs[0].li.className = 'first-active';
		}
	}
    return this;
};
tabberObj.prototype.navClearActive = function(tabberIndex) {
    /*if (this.tabs[tabberIndex-1])
		this.tabs[tabberIndex-1].li.className = '';
	
	this.tabs[tabberIndex].li.className = '';
	
	if (this.tabs[tabberIndex+1])
		this.tabs[tabberIndex+1].li.className = '';*/
	
    return this;
};
function tabberAutomatic(tabberArgs) {
    var tempObj,
    divs,
    i;
    if ( ! tabberArgs) {
        tabberArgs = {};
    }
    tempObj = new tabberObj(tabberArgs);
    divs = document.getElementsByTagName("div");
    for (i = 0; i < divs.length; i ++ ) {
        if (divs[i].className && divs[i].className.match(tempObj.REclassMain) || 
			divs[i].className && divs[i].className.match(tempObj.REclassMainLive )) {
            tabberArgs.div = divs[i];
            divs[i].tabber = new tabberObj(tabberArgs);
        }
    }
    return this;
}
function tabberAutomaticOnLoad(tabberArgs) {
    var oldOnLoad;
    if ( ! tabberArgs) {
        tabberArgs = {};
    }
    oldOnLoad = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = function() {
            tabberAutomatic(tabberArgs);
        };
    } else {
        window.onload = function() {
            oldOnLoad();
            tabberAutomatic(tabberArgs);
        };
    }
}
if (typeof tabberOptions == 'undefined') {
    tabberAutomaticOnLoad();
} else {
    if ( ! tabberOptions['manualStartup']) {
        tabberAutomaticOnLoad(tabberOptions);
    }
}

