/* Copyright 2009-2010 Taco Software. All rights reserved.
 * http://tacosw.com
 *
 * This file is part of the Component Library included in Taco HTML Edit.
 * Licensed users of Taco HTML Edit may modify and use this source code 
 * for their web development (including commercial projects), as long as 
 * this copyright notice is retained.
 *
 * The contents of this file may not be published in a format intended
 * for access by other humans, so you may not put code examples on a
 * web site with all or part of the contents of this file, and you may
 * not publish the contents of this file in a printed format.
 */

var tswTabbedContentMap = new Object(); //maps tabbled content id to TSWTabbedContent object;

//Returns the TSWTabbedContent object for an id, creating the object
//if necessary.
function tswTabbedContentGetForId(id)
{
	var tc = tswTabbedContentMap[id];
	if(tc == null)
	{
		tc = new TSWTabbedContent(id);
		tswTabbedContentMap[id] = tc;
	}
	return tc;
}

//TSWTabbedContent is a javascript object that represents
//the tabbed content component in the HTML document. The
//constructor takes the id of the object.
function TSWTabbedContent(id)
{
	this.id = id;
	this.selectedTab = 0; //The tab that is currently selected
	this.animationDuration = 0; //Duration of animation in milliseconds (0 for no animation)
	this.reserveSpaceForTallestTab = false;
	
	//Initialize DOM by adding needed divs to tabs
	var tabs = this.getTabElements();
	for(var i=0; i<tabs.length; i++)
	{
		var tab = tabs[i];
		
		var outerDiv = document.createElement('div');
		outerDiv.className = 'tswTabOuterDiv';
		var innerDiv = document.createElement('div');
		innerDiv.className = 'tswTabInnerDiv';
		outerDiv.appendChild(innerDiv);
		
		while (tab.hasChildNodes()) 
		{
			innerDiv.appendChild(tab.removeChild(tab.firstChild));
		}
		tab.appendChild(outerDiv);
		this.generateOnClick(tab, this, i);
		
		if(tab.className == 'tswTabSelected')
			this.selectedTab = i;
	}
	
	//Needed for IE7 in quirks mode
	this.getTabbedContentElement().insertBefore(document.createElement('br'),this.getTabContentContainerElement());
	
	this.animationIntervalId = null; //Identifies the interval timer being used for the animation
	this.animationStartDate = null; //date when the animation began
	this.previousSelectedTab = -1; //The previously selected tab
	this.previousTabContentRect; //The coordinates of the preview tab content
	
	this.init(this);
};

//tabbedContent is passed in for closure
TSWTabbedContent.prototype.init = function(tabbedContent)
{
	tswUtilsAddEventHandler(window, 'resize', 
		function(){ 
			if(tabbedContent.reserveSpaceForTallestTab)
				tabbedContent.setReserveSpaceForTallestTab(true);
		});
	tswUtilsAddEventHandler(window, 'load', 
		function(){ 
			if(tabbedContent.reserveSpaceForTallestTab)
				tabbedContent.setReserveSpaceForTallestTab(true);
		});
}

TSWTabbedContent.prototype.setReserveSpaceForTallestTab = function(bool)
{
	/*In IE inline JavaScript can be invoked multiple times, which is why
	 we need this check. For this to work correctly in Safari, it needs to
	 be called multiple times; hence, the Explorer check.*/
	if(!TSWBrowserDetect.browserMatches('Explorer', null, null) || this.reserveSpaceForTallestTab != bool)
	{
		this.reserveSpaceForTallestTab = bool;
		if(bool)
		{
			var maxHeight = 0;
			var tabContents = this.getTabContentElements();
			for(var i=0; i<tabContents.length; i++)
			{
				var h = tabContents[i].offsetHeight;
				if(h > maxHeight)
					maxHeight = h;
			}
			
			this.getTabContentContainerElement().style.height = maxHeight + 'px';
			
			//Needed for IE7 when a position:relative div is inside the tabbed
			//content for the content to appear in the correct location; don't ask me why
			var tabContents = this.getTabContentElements();
			tabContents[this.selectedTab].className = 'tswTabContentSelected';
		}
		else
		{
			this.getTabContentContainerElement().style.height = null;
		}
	}
};

TSWTabbedContent.prototype.getTabbedContentElement = function()
{
	return document.getElementById(this.id);
};

TSWTabbedContent.prototype.getTabListElement = function()
{
	var lists = TSWDomUtils.getChildrenWithTagName(this.getTabbedContentElement(), 'ul');
	if(lists.length > 0)
		return lists[0];
	return null;
};

TSWTabbedContent.prototype.getTabElements = function()
{
	return TSWDomUtils.getChildrenWithTagName(this.getTabListElement(), 'li');
};

TSWTabbedContent.prototype.getTabContentContainerElement = function()
{
	var divs = TSWDomUtils.getChildrenWithTagName(this.getTabbedContentElement(), 'div');
	for(var i=0; i<divs.length; i++)
	{
		if(divs[i].className == 'tswTabContent')
			return divs[i];
	}
	return null;
}

TSWTabbedContent.prototype.getTabContentElements = function()
{
	return TSWDomUtils.getChildrenWithTagName(this.getTabContentContainerElement(), 'div');
};

TSWTabbedContent.prototype.generateOnClick = function(tabElement, tabbedContent, index)
{
	tabElement.onclick = function() { tabbedContent.selectTab(index); };
};

TSWTabbedContent.prototype.selectTab = function(index)
{
	if(this.selectedTab == index)
		return;
	this.cleanupAnimation();
	
	var tabs = this.getTabElements();
	var tabContents = this.getTabContentElements();
	
	//Store preview tab content coords for animation
	var previousTabContents = tabContents[this.selectedTab];
	var prevPos = tswUtilsGetAbsolutePosition(previousTabContents);
	
	if(TSWBrowserDetect.browserMatches('Explorer', null, 6.0) ||
	   (TSWBrowserDetect.browserMatches('Explorer', null, null) && document.compatMode == 'BackCompat'))
	{
		//For IE 6 or IE quirks mode
		this.previousTabContentRect = 
			[prevPos[0], 
			prevPos[1], 
			previousTabContents.offsetWidth, 
			previousTabContents.offsetHeight];
	}
	else
	{
		this.previousTabContentRect = 
			[prevPos[0], 
			prevPos[1], 
			previousTabContents.offsetWidth 
				- tswUtilsGetPixelsAsInteger(tswUtilsGetStyle(previousTabContents, 'borderLeftWidth')) 
				- tswUtilsGetPixelsAsInteger(tswUtilsGetStyle(previousTabContents, 'borderRightWidth')) 
				- tswUtilsGetPixelsAsInteger(tswUtilsGetStyle(previousTabContents, 'paddingLeft')) 
				- tswUtilsGetPixelsAsInteger(tswUtilsGetStyle(previousTabContents, 'paddingRight')), 
			previousTabContents.offsetHeight
				- tswUtilsGetPixelsAsInteger(tswUtilsGetStyle(previousTabContents, 'borderTopWidth')) 
				- tswUtilsGetPixelsAsInteger(tswUtilsGetStyle(previousTabContents, 'borderBottomWidth')) 
				- tswUtilsGetPixelsAsInteger(tswUtilsGetStyle(previousTabContents, 'paddingTop')) 
				- tswUtilsGetPixelsAsInteger(tswUtilsGetStyle(previousTabContents, 'paddingBottom'))];
	}
	
	tabs[this.selectedTab].className = null;
	tabContents[this.selectedTab].className = 'tswTabContentUnselected';
	
	this.previousSelectedTab = this.selectedTab;
	this.selectedTab = index;
	
	tabs[this.selectedTab].className = 'tswTabSelected';
	tabContents[this.selectedTab].className = 'tswTabContentSelected';
	
	this.beginAnimation();
};

TSWTabbedContent.prototype.cleanupAnimation = function()
{
	if(this.animationDuration <= 0 || this.previousSelectedTab < 0)
		return;
	
	var tabContents = this.getTabContentElements();
	var previousTabContents = tabContents[this.previousSelectedTab];
	previousTabContents.style.display = 'none';
	previousTabContents.style.position = '';
	previousTabContents.style.left = '';
	previousTabContents.style.top = '';
	previousTabContents.style.width = '';
	previousTabContents.style.height = '';
	previousTabContents.style.zIndex = 0;
	tswUtilsSetOpacity(previousTabContents, 1.0);
	
	var currentTabContents = tabContents[this.selectedTab];
	tswUtilsSetOpacity(currentTabContents, 1.0);
	
	clearInterval(this.animationIntervalId)
	this.animationIntervalId = null;
};

TSWTabbedContent.prototype.beginAnimation = function()
{
	if(this.animationDuration <= 0)
		return;
	
	this.animationStartDate = new Date();
	var tabContents = this.getTabContentElements();
	var previousTabContents = tabContents[this.previousSelectedTab];
	
	previousTabContents.style.display = 'block';
	previousTabContents.style.visibility = 'visible';
	previousTabContents.style.position = 'absolute';
	previousTabContents.style.left = this.previousTabContentRect[0] + 'px';
	previousTabContents.style.top = this.previousTabContentRect[1] + 'px';
	previousTabContents.style.width = this.previousTabContentRect[2] + 'px';
	previousTabContents.style.height = this.previousTabContentRect[3] + 'px';
	previousTabContents.style.zIndex = 1;
	tswUtilsSetOpacity(previousTabContents, 1.0);
	
	var currentTabContents = tabContents[this.selectedTab];
	tswUtilsSetOpacity(currentTabContents, 0.0);
	currentTabContents.style.display = '';
	
	this.animationIntervalId = setInterval("_tswTabbedContentAnimate('"+this.id+"')", 25);
};

function _tswTabbedContentAnimate(id)
{
	tswTabbedContentGetForId(id).continueAnimation();
}

TSWTabbedContent.prototype.continueAnimation = function()
{
	var currentDate = new Date();
	var tabContents = this.getTabContentElements();
	var previousTabContents = tabContents[this.previousSelectedTab];
	var currentTabContents = tabContents[this.selectedTab];
	
	var delta = (currentDate.getTime() - this.animationStartDate.getTime()) / this.animationDuration;
	if(delta >= 1.0)
	{
		//complete the animation
		this.cleanupAnimation();
		return;
	}
	tswUtilsSetOpacity(previousTabContents, 1.0 - delta);
	tswUtilsSetOpacity(currentTabContents, delta);
}


/* The checksum below is for internal use by Taco HTML Edit, 
   to detect if a component file has been modified.
   TacoHTMLEditChecksum: 96A07087 */
