
function Tabs(containerDivId,tabList,name,pathImages,useTransitionImages) {

	 /*
	 tabList = [
				[
				 'tab label',
				 'div id of tab content',
				 'function to be called when tab gets focus',
				 'function to be called when tab loses focus',
				 'function to ba called when tag is refreshed',
				 'url of tab content', (This features assumes prototype.js is available)
				 'function to be called when url above has been loaded in tab' (This features also assumes prototype.js is available)
				 ]
				]

	 The refreh code is executed after the focus code when a tab gets focus and the refresh flag
	 of this tab is set to true. This flag will automatically be lowered at the end of the refresh
	 code execution. Must call raiseRefreshFlags() to raise them again.
	 */

	if (pathImages == undefined) pathImages = '/images/tabs/';
	if (useTransitionImages == undefined || useTransitionImages != false) useTransitionImages = true;

	this.container = document.getElementById(containerDivId);
	this.tabList = tabList;
	this.name = name;
	this.pathImg = pathImages;
	this.useTransitionImg = useTransitionImages;
	this.tabRowElementId = 'tabRow_'+this.name;
	this.onTabNumber = null;
	this.refreshFlags = new Array();
	this.contentLoadedFlags = new Array();
	this.tabStatus = new Array();

};

Tabs.prototype.build = function(initialTab,simClickCallback) {

	var i;

	// empty the tabs container
	while (this.container.childNodes.length > 0) { this.container.removeChild(this.container.childNodes[0]); }

	// create the tab table
	var tabTable = document.createElement('table');
	tabTable.className = 'tabs';

	// create row of tabs
	tbodyElm = document.createElement('tbody');
	tabTable.appendChild(tbodyElm);
	tabRow = document.createElement('tr');
	tbodyElm.appendChild(tabRow);
	
	//tabRow = tabTable.insertRow(0);
	tabRow.setAttribute('id',this.tabRowElementId);

	var cell;
	var openImg;
	var closeImg;
	var cellCount = 0;
	var thisRef = this;
	for(var i = 0; i < this.tabList.length; i++) {

		// image that preceedes the tab
		cell = tabRow.insertCell(cellCount++);
		cell.className = 'transition';
		if (this.useTransitionImg) {
			/*
			openImg = document.createElement('img');
			if (i == 0) {
				openImg.src = this.pathImg + "tabs-null_off.gif";
			}
			else {
				openImg.src = this.pathImg + "tabs-off_off.gif";
			}
			cell.appendChild(openImg);
			*/
			if (i == 0) cell.className = 'transition transition-null-off';
			else cell.className = 'transition transition-off-off';
		}

		// the tab itself
		//cell = tabRow.insertCell(cellCount++);
		cell = document.createElement('td');
		cellCount++;
		cell.className = 'off';
		cell.appendChild(document.createTextNode(this.tabList[i][0]));
		cell.setAttribute('id','tab_'+i);
		tabRow.appendChild(cell);
		//cell.onclick = new Function('tabsObj_clickOnTab(this.id,\''+this.name+'\')');
		//cell.onclick = function(evt) { thisRef.clickOnTab(Event.element(evt).id); };
		//Event.observe(cell,'click', function(evt) { var i = 0; while (i < arguments.length) { alert(arguments[i++]); } });
		Event.observe(cell,'click', function(evt) { thisRef.clickOnTab(Event.element(evt).id); });

		// close the tabs
		if (i == (this.tabList.length - 1)) {
			cell = tabRow.insertCell(cellCount++);
			cell.className = 'transition';
			if (this.useTransitionImg) {
				/*
				closeImg = document.createElement('img');
				closeImg.src = this.pathImg + "tabs-off_null.gif";
				cell.appendChild(closeImg);
				*/
				cell.className = 'transition transition-off-null';
			}
		}
	}

	// build the array of refresh flags and status flags
	for(var i = 0; i < this.tabList.length; i++) {
		this.refreshFlags[i] = true;
		this.contentLoadedFlags[i] = false;
		this.tabStatus[i] = 'off';
	}

	// add to the container
	this.container.appendChild(tabTable);

	if (initialTab == undefined || initialTab == null || initialTab == '') {
		// select the first tab
		this.clickOnTab('tab_0');
	}
	else {
		var tabNb = 0;
		for(var i = 0; i < this.tabList.length; i++) {
			if (this.tabList[i][1] == initialTab) tabNb = i;
		}
		this.clickOnTab('tab_'+tabNb,simClickCallback);
	}

};

Tabs.prototype.clickOnTab = function(tabId,callback) {

	// find the index in the tabList of the tab clicked
	var tabNumber = tabId.match(/^tab_([0-9]+)$/i).pop();

	tabRow = document.getElementById(this.tabRowElementId);

	var cellCount=0;
	var cell;


	if (tabNumber == this.onTabNumber) {
		// clicked on the tab that is already visible
		return true;
	}

	// turn off the tab that was on
	//-------------------------------------------
	if (this.onTabNumber != null && this.onTabNumber != undefined) {
		// put tab as inactive
		cellCount = (this.onTabNumber * 2) + 1;
		if (tabRow.childNodes[cellCount] != undefined) {
			tabRow.childNodes[cellCount].className = 'off';
			//if (this.useTransitionImg) tabRow.childNodes[(cellCount-1)].firstChild.src = (cellCount == 1) ? this.pathImg + "tabs-null_off.gif" : this.pathImg + "tabs-off_off.gif";
			//if (this.useTransitionImg) tabRow.childNodes[(cellCount+1)].firstChild.src = ((cellCount+1) == (tabRow.childNodes.length - 1)) ? this.pathImg + "tabs-off_null.gif" : this.pathImg + "tabs-off_off.gif";
			if (this.useTransitionImg) tabRow.childNodes[(cellCount-1)].className = (cellCount == 1) ? "transition transition-null-off" : "transition transition-off-off";
			if (this.useTransitionImg) tabRow.childNodes[(cellCount+1)].className = ((cellCount+1) == (tabRow.childNodes.length - 1)) ? "transition transition-off-null" : "transition transition-off-off";
		}
		// hide the content of the tab page
		if (document.getElementById(this.tabList[this.onTabNumber][1])) {
			document.getElementById(this.tabList[this.onTabNumber][1]).style.display = 'none';
		}
	}


	// turn on the tab that was clicked
	//-------------------------------------------

	this.onTabNumber = tabNumber;
	cellCount = (tabNumber * 2);

	// first cell is transition image before the tab
	cell = tabRow.childNodes[cellCount++];
	//if (this.useTransitionImg) cell.firstChild.src = (tabNumber == 0) ? this.pathImg + "tabs-null_on.gif" : this.pathImg + "tabs-off_on.gif";
	if (this.useTransitionImg) cell.className = (tabNumber == 0) ? "transition transition-null-on" : "transition transition-off-on";
	// next cell is the tab itself
	cell = tabRow.childNodes[cellCount++];
	cell.className = 'on';
	// last cell is transition image after the tab
	cell = tabRow.childNodes[cellCount];
	//if (this.useTransitionImg) cell.firstChild.src = (tabNumber == (this.tabList.length - 1)) ? this.pathImg + "tabs-on_null.gif" : this.pathImg + "tabs-on_off.gif";
	if (this.useTransitionImg) cell.className = (tabNumber == (this.tabList.length - 1)) ? "transition transition-on-null" : "transition transition-on-off";

	// show tab page content
	if (document.getElementById(this.tabList[this.onTabNumber][1])) {
		document.getElementById(this.tabList[this.onTabNumber][1]).style.display = 'block';
	}


	// execute user defined fcts
	//-------------------------------------------

	// onBlur code
	for(var i=0; i<this.tabList.length; i++) {
		if (i != tabNumber) {
			// onBlur tab code
			if ((this.tabStatus[i] == 'on') && this.tabList[i][3] != undefined && typeof this.tabList[i][3] == 'function') (this.tabList[i][3])();
			this.tabStatus[i] = 'off';
		}
	}

	// load tab content if dynamic and not loaded yet
	if (this.tabList[tabNumber][5] != undefined && this.tabList[tabNumber][5] != '') {
		if (this.refreshFlags[tabNumber] || !this.contentLoadedFlags[tabNumber]) {
			// set content of tab to url specified
			var params = {};
			var tabDefinedCallback = null;
			var fctDefinedCallback = null;
			if (this.tabList[tabNumber][6] != undefined && typeof this.tabList[tabNumber][6] == 'function') {
				tabDefinedCallback = this.tabList[tabNumber][6];
			}
			if (callback != undefined && typeof callback == 'function') {
				fctDefinedCallback = callback;
			}
			
			if (typeof tabDefinedCallback == 'function' && typeof fctDefinedCallback == 'function') {
				params.onComplete = function(t) {
					(tabDefinedCallback)();
					(fctDefinedCallback)();
				};
			}
			else if (typeof tabDefinedCallback == 'function') {
				params.onComplete = tabDefinedCallback;
			}
			else if (typeof fctDefinedCallback == 'function') {
				params.onComplete = fctDefinedCallback;
			}
			
			new Ajax.Updater(document.getElementById(this.tabList[tabNumber][1]),this.tabList[tabNumber][5], params);
			this.contentLoadedFlags[tabNumber] = true;
		}
	}

	// onFocus and onRefresh
	/*for(var i=0; i<this.tabList.length; i++) {
		if (i == tabNumber) {
			// onFocus tab code
			if (this.tabList[i][2] != undefined && this.tabList[i][2] != '') eval(this.tabList[i][2]);
			this.tabStatus[i] = 'on';
			// onRefresh tab code
			if (this.refreshFlags[i] && this.tabList[i][4] != '') {
				eval(this.tabList[i][4]);
				this.refreshFlags[i] = false;
			}
		}
	}*/
	// onFocus tab code
	if (this.tabList[tabNumber][2] != undefined && typeof this.tabList[tabNumber][2] == 'function') (this.tabList[tabNumber][2])();
	this.tabStatus[tabNumber] = 'on';
	// onRefresh tab code
	if (this.refreshFlags[tabNumber] && this.tabList[tabNumber][4] != undefined && typeof this.tabList[tabNumber][4] == 'function') {
		(this.tabList[tabNumber][4])();
	}
	this.refreshFlags[tabNumber] = false;
};

Tabs.prototype.raiseRefreshFlags = function(execCodeForActiveTab,tabIds) {
	/*
	** if execCodeForActiveTab is true, the onRefresh code for the active tab will be executed
	** and the flag for this tab is lowered.
	** else, execCodeForActiveTab false will have the onRefresh function called the next time
	** this tab is clicked.
	**
	** tabIds (optional) indicate the number of each tabs for which the refresh flag must be raised.
	** If it is not defined, the flag is raised for all tabs. 
	*/
	execCodeForActiveTab = (execCodeForActiveTab == false) ? false : true;
	
	if (tabIds == undefined) {
		for (var i = 0; i < this.refreshFlags.length; ++i) {
			if (i == this.onTabNumber && execCodeForActiveTab) {
				if (this.tabList[i][5] != undefined && this.tabList[i][5] != '') {
					// set content of tab to url specified
					var params = {};
					if (this.tabList[i][6] != undefined && typeof this.tabList[i][6] == 'function') params.onComplete = this.tabList[i][6];
					new Ajax.Updater(document.getElementById(this.tabList[i][1]),this.tabList[i][5],params);
					this.contentLoadedFlags[i] = true;
				}
				if (this.tabList[i][4] != undefined && typeof this.tabList[i][4] == 'function') {
					// execute onRefresh callback function for the tab
					(this.tabList[i][4])();
				}
			}
			else {
				// raise refresh flag
				this.refreshFlags[i] = true;
			}
		}
	}
	else {
		for (var i = 0; i < tabIds.length; ++i) {
			// execute onRefreshCode for the tab
			if (tabIds[i] == this.onTabNumber && execCodeForActiveTab) {
				if (this.tabList[tabIds[i]][4] != undefined && typeof this.tabList[tabIds[i]][4] == 'function') (this.tabList[tabIds[i]][4])();
				var params = {};
				if (this.tabList[tabIds[i]][6] != undefined && typeof this.tabList[tabIds[i]][6] == 'function') params.onComplete = this.tabList[tabIds[i]][6];
				if (this.tabList[tabIds[i]][5] != undefined && this.tabList[tabIds[i]][5] != '') new Ajax.Updater(document.getElementById(this.tabList[tabIds[i]][1]),this.tabList[tabIds[i]][5]);
			}
			else {
				// raise refresh flag
				this.refreshFlags[tabIds[i]] = true;
			}
		}
	}
};

