  /*----------------------------------------------------------------------------\
|                               Tab Pane 1.02                                 |
|-----------------------------------------------------------------------------|
|                         Created by Erik Arvidsson                           |
|                  (http://webfx.eae.net/contact.html#erik)                   |
|                      For WebFX (http://webfx.eae.net/)                      |
|-----------------------------------------------------------------------------|
|                Copyright (c) 2002, 2003, 2006 Erik Arvidsson                |
|-----------------------------------------------------------------------------|
| Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| use this file except in compliance with the License.  You may obtain a copy |
| of the License at http://www.apache.org/licenses/LICENSE-2.0                |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| Unless  required  by  applicable law or  agreed  to  in  writing,  software |
| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |
| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |
| License  for the  specific language  governing permissions  and limitations |
| under the License.                                                          |
|-----------------------------------------------------------------------------|
| 2002-01-?? | First working version                                          |
| 2002-02-17 | Cleaned up for 1.0 public version                              |
| 2003-02-18 | Changed from javascript uri for anchors to return false        |
| 2003-03-03 | Added dispose methods to release IE memory                     |
| 2006-05-28 | Changed license to Apache Software License 2.0.                |
|-----------------------------------------------------------------------------|
| Dependencies: *.css           a css file to define the layout               |
|-----------------------------------------------------------------------------|
| Created 2002-01-?? | All changes are in the log above. | Updated 2006-05-28 |
\----------------------------------------------------------------------------*/

// This function is used to define if the browser supports the needed
// features
function hasSupport() {

	if (typeof hasSupport.support != "undefined")
		return hasSupport.support;
	
	var ie55 = /msie 5\.[56789]/i.test( navigator.userAgent );
	
	hasSupport.support = ( typeof document.implementation != "undefined" &&
			document.implementation.hasFeature( "html", "1.0" ) || ie55 )
			
	// IE55 has a serious DOM1 bug... Patch it!
	if ( ie55 ) {
		document._getElementsByTagName = document.getElementsByTagName;
		document.getElementsByTagName = function ( sTagName ) {
			if ( sTagName == "*" )
				return document.all;
			else
				return document._getElementsByTagName( sTagName );
		};
	}

	return hasSupport.support;
}

///////////////////////////////////////////////////////////////////////////////////
// The constructor for tab panes
//
// el : HTMLElement		The html element used to represent the tab pane
// bUseCookie : Boolean	Optional. Default is true. Used to determine whether to us
//						persistance using cookies or not
//
function WebFXTabPane( el, parent,  bUseCookie ) {
	if ( !hasSupport() || el == null ) return;

	this._parent = parent;

	this.element = el;
	this.element.tabPane = this;
	//$ this._parent = _parent; // _parent was a parameter before bUseCookie
	
	//Nethrom.Dispatcher.addAccessKey(this.element, new Nethrom.Utils.Hotkey("37", true,true), this.showPrev.bind(this)    , "");
    //Nethrom.Dispatcher.addAccessKey(this.element, new Nethrom.Utils.Hotkey("39", true,true), this.showNext.bind(this)    , "");

	this.pages = [];
	this.selectedIndex = null;
	this.useCookie = bUseCookie != null ? bUseCookie : true;

	this.useCookie = bUseCookie != null ? bUseCookie : false;  /* Default: true. But the first tab should be displayed on creation. BPx */
	
	// add class name tag to class name
	//this.element.className = this.classNameTag + " " + this.element.className;
	Element.addClassName(this.element, this.classNameTag);

	//$ DOC now only works as part of the projapi (see reffrence to parent object)
	// add tab row
	this.tabRow = document.createElement( "div" );
	this.tabRow.className = "tab-row";
	//this.tabRow.appendChild(this.tabSelector = document.createElement("span"));
	this.tabSelector = document.createElement("span")
	this.tabContainer = this.tabRow;//.appendChild(document.createElement("div"));
	this.tabSelector.className = "tab selector";
	this.tabSelector.innerHTML = '<span class="part head">&nbsp;</span><span class="tabOut"><span class="tabIn"><a class="label" href="#">\u25bc</a></span></span><span class="part tail">&nbsp;</span>';
	//this.tabSelector.style.display = "none";
	var oThis = this;
	Event.observe(this.tabSelector, "click", function() { oThis.openSelector(); }, false, parent);
	this.popup = new Projapi.Widgets.PJPopupMenu("generated-for-" + parent._objectName, { objectPage: -1 });
	Projapi.Controller.subscribe(parent, Projapi.Links.Container.CreateObjects, this.popup);
/*$ Element.addClassName(_tempNode, this._parent._DOMClassPrefix+"TabRow");
  this.tabRow.id = this._parent.getObjectName()+"TabRow";
  
  var _tempNode1 = document.createElement("DIV");
  _tempNode1.className = this._parent._DOMClassPrefix + 'TabRowB1';
  this.tabRow.appendChild(_tempNode1);

  var _tempNode2 = document.createElement("DIV");
  _tempNode2.className = this._parent._DOMClassPrefix + 'TabRowB2';
  _tempNode1.appendChild(_tempNode2);

  var _tempNode3 = document.createElement("DIV");
  _tempNode3.className = this._parent._DOMClassPrefix + 'TabRow';
  _tempNode3.id = 'pjContent_' + this._parent.getObjectName() + "_tabRow";
  _tempNode2.appendChild(_tempNode3);
$*/
	el.insertBefore( this.tabRow, el.firstChild );
	el.insertBefore(this.tabSelector, this.tabRow);
	//$ this.tabRow = _tempNode3;

	var tabIndex = 0;
	if ( this.useCookie ) {
		tabIndex = Number( WebFXTabPane.getCookie( "webfxtab_" + this.element.id ) );
		if ( isNaN( tabIndex ) )
			tabIndex = 0;
	}
	this.selectedIndex = tabIndex;
	
	// loop through child nodes and add them
	var cs = el.childNodes;
	var n = cs.length;
	for (var i = 0; i < n; i++) {
		if (cs[i].nodeType == 1 && cs[i].className == "tab-page") {
			this.addTabPage( cs[i] );
		}
	}
}

WebFXTabPane.prototype.openSelector = function() {
	if (!this.popup._objectHidden) {	// make the selector work as a toggle button
		this.popup._actions.collapse();
		return;
	}
	var x, y;
	y = Position.cumulativeOffset(this.tabSelector)[1] + this.tabSelector.offsetHeight;
	x = Position.cumulativeOffset(this.tabSelector.parentNode)[0];
	this.popup.pop(x, y);
	this.popup._ignoreNextClick = true;		// for when the current click reaches the top level
	var node = this.popup.getDOMNode().domNode;
	//x = x - node.offsetWidth;
	node.style.left = parseInt(node.style.left) + this.tabSelector.parentNode.offsetWidth - node.offsetWidth + "px";
}

WebFXTabPane.prototype.deletePage = function(_pageNumber) {
	this.tabContainer.removeChild(this.pages[_pageNumber].tab);
	for (var i = _pageNumber; i < this.pages.length; i++)
		--this.pages[i].index;
	this.pages[_pageNumber].dispose();
	this.pages.splice(_pageNumber,1);
	if (this.selectedIndex >= _pageNumber)
		--this.selectedIndex;
}

WebFXTabPane.prototype.classNameTag = "dynamic-tab-pane-control";

// DOC override: needs to first select the page like a Smart Object;
WebFXTabPane.prototype.setSelectedIndex = function ( n ) {
	this._parent.selectPage(n);
};

// DOC override: original setSelectedindex.
// @private
WebFXTabPane.prototype._setSelectedIndex = function ( n ) {
	if (this.selectedIndex != n) {
		if (this.selectedIndex != null && this.pages[ this.selectedIndex ] != null )
			this.pages[ this.selectedIndex ].hide();
		this.selectedIndex = n;
		this.pages[ this.selectedIndex ].show();
		
		if ( this.useCookie )
			WebFXTabPane.setCookie( "webfxtab_" + this.element.id, n );	// session cookie
	}
};

WebFXTabPane.prototype.getSelectedIndex = function () {
	return this.selectedIndex;
};

WebFXTabPane.prototype.showPanel = function (n) {
                                      this.setSelectedIndex(n);
                                      this.pages[ this.selectedIndex ].show();
                                      value = this.pages[ this.selectedIndex ].element.getElementsByTagName('textarea')[0];
                                      if (typeof(value) == "undefined") value = this.pages[ this.selectedIndex ].element.getElementsByTagName('input')[0];
                                      setTimeout("value.focus()",250);
                                     }

WebFXTabPane.prototype.showPrev = function ()
                                {
                                if ((this.selectedIndex - 1) == -1)
                                   {
                                   var prev = this.pages.length - 1;
                                   }
                                else
                                    {
                                    var prev = this.selectedIndex - 1;
                                    }

                                   this.pages[ this.selectedIndex].hide();
                                   this.pages[ prev ].show();
                                   this.selectedIndex = prev;
                                   value = this.pages[ this.selectedIndex ].element.getElementsByTagName('textarea')[0];
                                   if (typeof(value) == "undefined") value = this.pages[ this.selectedIndex ].element.getElementsByTagName('input')[0];
                                   setTimeout("value.focus()",250);

                                }

WebFXTabPane.prototype.showNext = function ()
                                {
                                if ((this.selectedIndex + 1) == this.pages.length)
                                   {
                                   var next = 0;
                                   }
                                else
                                    {
                                     var next =this.selectedIndex + 1;
                                    }

                                    this.pages[ this.selectedIndex].hide();
                                    this.pages[ next ].show();
                                    this.selectedIndex = next;
                                    value = this.pages[ this.selectedIndex ].element.getElementsByTagName('textarea')[0];
                                    if (typeof(value) == "undefined") value = this.pages[ this.selectedIndex ].element.getElementsByTagName('input')[0];
                                    setTimeout("value.focus()",250);

                                }

WebFXTabPane.prototype.addTabPage = function ( oElement, _tabPosition ) {

	if ( !hasSupport() ) return;
	
	if ( oElement.tabPage == this )	// already added
		return oElement.tabPage;
	
	// added functionality: able to insert a tab before an other one:
	//DOC
	
	var insert = true;
	if ((isNaN(_tabPosition)) || (_tabPosition == null) || (_tabPosition < 0) || (_tabPosition > this.pages.length)) {
		insert = false;
	}
	if (insert) {
		var n = _tabPosition;
		if (n <= this.selectedIndex) {
      ++this.selectedIndex;
    }
		this.pages.splice(n,0,'');
		var _idx = n+1, _idxEnd = this.pages.length;  
		for (; _idx<_idxEnd; ++_idx) {
			++this.pages[_idx].index;
		}
	} else {
		var n = this.pages.length;
	}


	
	var tp = this.pages[n] = new WebFXTabPage( oElement, this, n );
	tp.tabPane = this;
	
	var title = tp.element.getElementsByTagName('span')[0].getAttribute("title");
    var accesskey = tp.element.getElementsByTagName('span')[0].getAttribute("accesskey");
	var final_accesskey;
    if (accesskey)
      {
      if (title.search(accesskey))
          {
          final_accesskey = title.substring(title.indexOf(accesskey),title.indexOf(accesskey) + 1);
          //Nethrom.Dispatcher.addAccessKey(document.body, new Nethrom.Utils.Hotkey(final_accesskey, false, true), (function() {this.showPanel(n)}).bind(this)     , "");
          }
      else
          {
          final_accesskey = accesskey;
          //Nethrom.Dispatcher.addAccessKey(document.body, new Nethrom.Utils.Hotkey(final_accesskey, false, true), (function() {this.showPanel(n)}).bind(this)     , "");
          }
      }
    else
      {
      if (title && title.search('@') >= 0)
          {

          final_accesskey = title.substring(title.indexOf('@')+1,title.indexOf('@') + 2);
          //Nethrom.Dispatcher.addAccessKey(document.body, new Nethrom.Utils.Hotkey(final_accesskey, false, true), (function() {this.showPanel(n)}).bind(this)     , "");
          }
      }


	// move the tab out of the box
	// added functionality: able to insert a tab before an other one:
	//DOC
	if (!this.tabContainer.childNodes[n]) {
   	this.tabContainer.appendChild( tp.tab );
  } else {
  		this.tabContainer.insertBefore( tp.tab, this.tabContainer.childNodes[n] );
  }
	
	if ( n == this.selectedIndex )
		tp.show();
	else
		tp.hide();


	return tp;
};
	
WebFXTabPane.prototype.dispose = function () {
	this.element.tabPane = null;
	this.element = null;		
	this.tabRow = null;
	
	for (var i = 0; i < this.pages.length; i++) {
		this.pages[i].dispose();
		this.pages[i] = null;
	}
	this.pages = null;
};



// Cookie handling
WebFXTabPane.setCookie = function ( sName, sValue, nDays ) {
	var expires = "";
	if ( nDays ) {
		var d = new Date();
		d.setTime( d.getTime() + nDays * 24 * 60 * 60 * 1000 );
		expires = "; expires=" + d.toGMTString();
	}

	document.cookie = sName + "=" + sValue + expires + "; path=/";
};

WebFXTabPane.getCookie = function (sName) {
	var re = new RegExp( "(\;|^)[^;]*(" + sName + ")\=([^;]*)(;|$)" );
	var res = re.exec( document.cookie );
	return res != null ? res[3] : null;
};

WebFXTabPane.removeCookie = function ( name ) {
	setCookie( name, "", -1 );
};








///////////////////////////////////////////////////////////////////////////////////
// The constructor for tab pages. This one should not be used.
// Use WebFXTabPage.addTabPage instead
//
// el : HTMLElement			The html element used to represent the tab pane
// tabPane : WebFXTabPane	The parent tab pane
// nindex :	Number			The index of the page in the parent pane page array
//
function WebFXTabPage( el, tabPane, nIndex ) {
	if ( !hasSupport() || el == null ) return;
	this.element = el;
	this.element.tabPage = tabPane;
	this.index = nIndex;
	
	var cs = el.childNodes;
	for (var i = 0; i < cs.length; i++) {
		if (cs[i].nodeType == 1 && cs[i].className == "tab") {
			this.tab = cs[i];
			break;
		}
	}
	
	// insert a tag around content to support keyboard navigation
	//RP
	
	var oEl = document.createElement( "span" );
	oEl.className = "tabOut";
	var oIl = document.createElement( "span" );
	oIl.className = "tabIn";
	oEl.appendChild(oIl);
	var btnX = document.createElement("span");
	btnX.className = "tabClose";
	btnX.innerHTML = "&nbsp;";
	var oThis = this;
	Event.observe(btnX, "click", function(){
		oThis.tabPane._parent.deletePage(oThis.tabPane.pages.indexOf(oThis));
	}, false, this._parent);
	oEl.appendChild(btnX);
	
	var a = document.createElement( "A" );
	this.aElement = a;
	a.className = "label";	// added by BPx. a.label is filtered for dynamic labels
	a.href = "#";
	a.onclick = function () { return false; };
	while ( this.tab.hasChildNodes() )
		a.appendChild( this.tab.firstChild );
	oIl.appendChild( a );
	var spn;
	this.tab.appendChild(spn = document.createElement("span"));
	spn.className = "part head";
	spn.innerHTML = "&nbsp;";
    this.tab.appendChild(oEl);
	this.tab.appendChild(spn = document.createElement("span"));
	spn.className = "part tail";
	spn.innerHTML = "&nbsp;";
    
	// hook up events, using DOM0
	var oThis = this;
	this.tab.onclick = function () { oThis.select(); };
	Event.observe(this.tab, 'keydown', function (event) {
		if( event.keyCode == Event.KEY_RETURN  || event.keyCode == 32) {
			oThis.select();
			Event.stop(event);
		}		
	});
	this.tab.onmouseover = function () { oThis.tabOver(); };
	this.tab.onmouseout = function () { oThis.tabOut(); };
	
	var name = "generated-for-" + tabPane._parent._objectName + "-" + this.aElement.innerHTML;
	var i = 0;
	while ($P(name + i)) i++;
	
	Projapi.Controller.subscribe(tabPane.popup, Projapi.Links.Container.CreateObjects,
		this.menuItem = new Projapi.Widgets.PJMenuItem(name + i, {
			label: this.aElement.innerHTML,
			clickTarget: this.tab
		}));
}

WebFXTabPage.prototype.show = function () {
	var el = this.tab, p = el.parentNode;
	var x = p.scrollLeft, dx = el.offsetLeft - p.firstChild.offsetLeft, post = 0, pre = 0;
	if (el.nextSibling) post = 50;
	if (el.previousSibling) pre = 50;
	if (dx + el.offsetWidth + post > p.scrollLeft + p.offsetWidth)
		x = dx + el.offsetWidth + post - p.offsetWidth;
	if (dx > 0) dx = (dx > pre) ? dx - pre : 0;
	if (dx < x)
		x = dx;
	var s = el.className + " selected";
	s = s.replace(/ +/g, " ");
	if (x != p.scrollLeft) p.scrollLeft = x;
	el.className = s;
	this.element.style.display = "block";
};

WebFXTabPage.prototype.hide = function () {
	var el = this.tab;
	var s = el.className;
	s = s.replace(/ selected/g, "");
	el.className = s;

	this.element.style.display = "none";
};

WebFXTabPage.prototype.select = function () {
	if (!this.element.tabPage._parent._objectEnabled) {
		return;
	}
	this.tabPane.setSelectedIndex( this.index );
};
	
WebFXTabPage.prototype.dispose = function () {
	this.menuItem.destroyObject();
	this.aElement.onclick = null;
	this.aElement = null;
	this.element.tabPage = null;
	this.tab.onclick = null;
	this.tab.onmouseover = null;
	this.tab.onmouseout = null;
	this.tab = null;
	this.tabPane = null;
	this.element = null;
};

WebFXTabPage.prototype.tabOver = function () {
	if (!this.element.tabPage._parent._objectEnabled) {
		return;
	}
	var el = this.tab;
	var s = el.className + " hover";
	s = s.replace(/ +/g, " ");
	el.className = s;
};

WebFXTabPage.prototype.tabOut = function () {
	var el = this.tab;
	var s = el.className;
	s = s.replace(/ hover/g, "");
	el.className = s;
};


// This function initializes all uninitialized tab panes and tab pages
function setupAllTabs() {



	if ( !hasSupport() ) return;

	var all = document.getElementsByTagName( "*" );
	var l = all.length;

	var tabPaneRe = /tab\-pane/;
	var tabPageRe = /tab\-page/;
	var cn, el;
	var parentTabPane;
	
	for ( var i = 0; i < l; i++ ) {
		el = all[i]
		cn = el.className;

		// no className
		if ( cn == "" ) continue;
		
		// uninitiated tab pane
		if ( tabPaneRe.test( cn ) && !el.tabPane )
			new WebFXTabPane( el );

		// unitiated tab page wit a valid tab pane parent
		else if ( tabPageRe.test( cn ) && !el.tabPage &&
					tabPaneRe.test( el.parentNode.className ) ) {

			el.parentNode.tabPane.addTabPage( el );
		}
	}
}

function disposeAllTabs() {
	if ( !hasSupport() ) return;
	
	var all = document.getElementsByTagName( "*" );
	var l = all.length;
	var tabPaneRe = /tab\-pane/;
	var cn, el;
	var tabPanes = [];
	
	for ( var i = 0; i < l; i++ ) {
		el = all[i]
		cn = el.className;

		// no className
		if ( cn == "" ) continue;
		
		// tab pane
		if ( tabPaneRe.test( cn ) && el.tabPane )
			tabPanes[tabPanes.length] = el.tabPane;
	}
	
	for (var i = tabPanes.length - 1; i >= 0; i--) {
		tabPanes[i].dispose();
		tabPanes[i] = null;
	}
}

/*

// initialization hook up

// DOM2
if ( typeof window.addEventListener != "undefined" )
	window.addEventListener( "load", setupAllTabs, false );

// IE
else if ( typeof window.attachEvent != "undefined" ) {
	window.attachEvent( "onload", setupAllTabs );
	window.attachEvent( "onunload", disposeAllTabs );
}

else {
	if ( window.onload != null ) {
		var oldOnload = window.onload;
		window.onload = function ( e ) {
			oldOnload( e );
			setupAllTabs();
		};
	}
	else
		window.onload = setupAllTabs;
}

*/
