/****************************************************
* OSCDL Tab functions.                              *
* Provides (hopefully) nifty tab effects.           *
* I'm sure that this can be genericized.            *
* The function makeTabs should be called from       *
*     the document body's onLoad event handler      *
****************************************************/

/****************************************************
* TabItem ( string name, object panel ):
*     name is the uniform part of all the tab ids
*     panel is an object reference to the content
*         linked with the tab
*     closed is the base offset value of the bottom
*         of the tab when in the closed position
*     open is the base offset value of the bottom
*         of the tab in the open position
*
*     contains an array of objects that are all part
*         of the same tab. you should have a css
*         class for each element to function to its
*         fullest. (named "on" and "off, see below)
*
*     Note: The functions here operate under the
*         assumption that TabItem.elements[0]
*         is a div containing all of the tab's
*         elements (tab text, backgrounds, etc.)
****************************************************/
function TabItem (name,id,panel,closed,open,width,ordinal) {
	this.tabElements = new Array();
	this.name = name;
	this.panel = panel;
	this.id = id;
	this.ordinal = ordinal;
	this.isOpen = false;
	this.closed = closed;
	this.open = open;
	this.width = width;
	this.left = 0;
}

/****************************************************
* TabGroup ( bool doSlide, [TabItem tab_1] ... [TabItem tab_n] ):
*     doSlide:
*         true: do "sliding drawer" effect
*         right: tabs slide to the right when activated
*         left: tabs slide to the left when activated
*         up: tabs slide upwards when activated
*         down: tabs slide downwards when activated
*     second through nth arguments are TabItems that
*         are contained by the div in the first arg
*
*     Note: Yes, you can create a tabGroup with no
*         tabItems registered, but that would make
*         you look quite the fool.
****************************************************/
function TabGroup (doSlide) {
	this.effect = doSlide;    //     so we can get to 'em later in the game
	this.tabItems = new Array();
	this.activeTabItem = null;
  this.left = parseInt(document.getElementById("map_tabs").style.left);
  this.nextLeft = 0;
  
	for (var i=1; i < arguments.length; ++i ) {
		this.tabItems[i-1] = arguments[i];
	}
}

TabGroup.prototype.tabIsOpen=function(tabId) {
  // if this is a tab panel id, extract the tabId from it
  var idx=tabId.lastIndexOf("_panel");
  if (idx>0) tabId=tabId.substring(0,idx);
  
  if (this.activeTabItem && this.activeTabItem.id==tabId) {
    return this.activeTabItem.isOpen;
  }
  return false;
}

/****************************************************
* TabGroup.tabClick ( string tabId )
****************************************************/
TabGroup.prototype.tabClick=function(tabId) {
  // if this is a tab panel id, extract the tabId from it
  var idx=tabId.lastIndexOf("_panel");
  if (idx>0) tabId=tabId.substring(0,idx);
  
  if (this.activeTabItem && this.activeTabItem.id==tabId) {
    this.closeTab(this.activeTabItem);
  } else {
    if (this.activeTabItem && this.activeTabItem.isOpen) {
      this.closeTab(this.activeTabItem);
    }
    for (var i=0;i<this.tabItems.length;++i) {
      if (this.tabItems[i].id==tabId) {
        this.openTab(this.tabItems[i]);
        return;
      }
    }
  }
}

/****************************************************
* TabGroup.closeTab(TabItem object)
****************************************************/
TabGroup.prototype.closeTab=function (theTab) {
  if (theTab==null) return;
  if (!theTab.isOpen) return;
  
  var tabElems=new Array();
  for (var i=0;i<theTab.tabElements.length;++i) {
    tabElems[i]=document.getElementById(theTab.tabElements[i]);
  }
  
  if (this.effect==true) {
	  var numSteps = Math.abs(theTab.open - theTab.closed);
	  var tabPos = parseInt(tabElems[0].style.bottom);
	  var today = new Date();

	  for ( i=0; tabPos >= 0; ++i) {
	  	tabElems[0].style.bottom = tabPos + "px";
	  	theTab.panel.style.height = tabPos + "px";
	  	--tabPos;
	  }
  }
  
	// just for good measure...
	tabElems[0].style.bottom = 0 + "px";
	theTab.panel.style.height = 0 + "px";

	for ( i=0; i < tabElems.length; ++i) {
		tabElems[i].className = "off";
	}

	tabElems[0].style.zIndex = 100 + theTab.ordinal;
	theTab.panel.style.zIndex = 50 + theTab.ordinal;
	theTab.panel.style.display = "none";
  theTab.isOpen = false;
  
	this.activeTabItem = null;
}

/****************************************************
* TabGroup.openTab(TabItem object)
****************************************************/
TabGroup.prototype.openTab=function (theTab) {
  if (theTab==null) return;
  if (theTab.isOpen) return;
  
  var tabElems=new Array();
  for (var i=0;i<theTab.tabElements.length;++i) {
    tabElems[i]=document.getElementById(theTab.tabElements[i]);
  }
  
  theTab.panel.style.display = "block";
  if (this.effect==true) {
	  var numSteps = Math.abs(theTab.open - theTab.closed);
	  var tabPos = theTab.closed;

	  for ( i=0; i < numSteps; ++i) {
		  tabElems[0].style.bottom = tabPos + "px";
		  theTab.panel.style.height = tabPos + "px";
		  ++tabPos;
	  }
  } else {
    var tabPos = theTab.closed + Math.abs(theTab.open - theTab.closed);
    tabElems[0].style.bottom = tabPos + "px";
		theTab.panel.style.height = tabPos + "px";
		theTab.panel.style.width = theTab.width + "px";
  }
  
	for ( i=0; i < tabElems.length; ++i) {
		tabElems[i].className = "on";
	}

	tabElems[0].style.zIndex = 100;
	theTab.panel.style.zIndex = 101;
  theTab.isOpen = true;
  
	this.activeTabItem = theTab;
}

/****************************************************
* TabGroup.tabsResizeHandler ()
*     This exists solely because IE is "special"
****************************************************/
TabGroup.prototype.tabsResizeHandler=function () {
	var oldTab = this.activeTabItem;
	for (var i=0; i < this.tabItems.length; ++i){ 
		this.closeTab(this.tabItems[i]);
	}

	if (oldTab!=null) {
		this.openTab(oldTab);
	}
}

/****************************************************
* sleepFor ( int ms )
*     ms:
*         time to sleep, in milliseconds
*
*     javascript has no true "sleep" function.
*     here's a kludge to fix that.
*     depending on the browser/cpu/etc, this might
*         be off by a few milliseconds...
****************************************************/
function sleepFor (ms) {
	var start = new Date();
	var current = new Date();
	var start_time = start.getTime();
	var flag = 0;

	while (flag == 0) {
		if ( (current.getTime() - start_time) < ms ) {
			current = new Date();
		} else {
			flag = 1;
		}
	}
	return 0;
}

/************************************************************************
* addTab()
*   appends a TabItem object to the TabGroup
************************************************************************/
TabGroup.prototype.addTab=function(name,tabWidth,panelWidth,panelHeight) {
  var count=this.tabItems.length;
  var id="infoTab_"+count;
  
  var tab=document.createElement("div");
  tab.id=id;
  var html="<ul id=\""+id+"_ul\">";
  html+="<li class=\"off\" id=\""+id+"_li\" onclick=\"infoTabs.tabClick('"+id+"');\">";
  html+="<a class=\"off\" id=\""+id+"_a\">"+name+"</a></li></ul>";
  tab.innerHTML=html;
  document.getElementById("map_tabs").appendChild(tab);
  tab.style.left=this.nextLeft+"px";
  tab.style.width=tabWidth+"px";
  
  var panel=document.createElement("div");
  panel.id=id+"_panel";
  panel.className="tab_panel";
  panel.style.position="absolute";
  panel.style.left=this.left+this.nextLeft+"px";
  panel.style.width=panelWidth+"px";
  
  var newTab=new TabItem(name,id,panel,0,panelHeight,panelWidth,count);
  newTab.tabElements[0]=id;
  newTab.tabElements[1]=id+"_ul";
  newTab.tabElements[2]=id+"_li";
  newTab.tabElements[3]=id+"_a";
  this.tabItems[this.tabItems.length]=newTab;
  
  document.getElementById("body").appendChild(panel);
  
  this.nextLeft+=tabWidth;
  
  return panel.id;
}
