
function getObj(name) {
  if (document.getElementById) {
    this.obj = document.getElementById(name);
    if (this.obj!=null) { this.style = document.getElementById(name).style; } 
  }
  else if (document.all) {
    this.obj = document.all[name];
    if (this.obj!=null) { this.style = document.all[name].style; }
  }
  else if (document.layers) {
    this.obj = document.layers[name];
    if (this.obj!=null) { this.style = document.layers[name]; }
  }
}

function objDimensions(obj) {
        if (document.getElementById) {
	        this.width=obj.offsetWidth;
		this.height=obj.offsetHeight;
  	}
	else {
	        this.width=obj.clip.width;
		this.height=obj.clip.height;
        }
}	

function windowSS() {
        if (document.getElementById && !document.all) {
	        this.width=window.innerWidth;
		this.height=window.innerHeight;
		this.scrollX=window.scrollX;
		this.scrollY=window.scrollY;
	}
	else if (document.all) {
	        this.width=document.body.clientWidth;
		this.height=document.body.clientHeight;
		this.scrollX=document.body.scrollLeft;
		this.scrollY=document.body.scrollTop;
        }
	else if (document.layers) { 
	        this.width=window.innerWidth;
		this.height=window.innerHeight;
		this.scrollX=window.pageXOffset;
		this.scrollY=window.pageYOffset;
	}
}

var _d=document; 
var _w=window; 
var _DOM1=(parseInt(navigator.appVersion) >= 5 || navigator.appVersion.indexOf["MSIE 5"] != -1);
var _NS4=(_d.layers)?1:0; 
var _IE4=(_d.all)?1:0;
var _Gecko=(navigator.userAgent.indexOf("Gecko"))?1:0;

var _vH=(_IE4)?"none":"hidden"; 
var _vS=(_IE4)?"block":"visible"; 

function _Sh(l,s){
var o= new getObj(l);
//FIXME: Comented out version ment for DOM1, but old flags used in HTML... compatability??
if (_DOM1) { /*o.style.display=(s)?_vS:_vH; cludge ->*/ o.style.visibility=(s)?"visible":"hidden"; } 
else { o.style.visibility=(s)?_vS:_vH; }
}

function _Ps(l,x,y){
var o= new getObj(l);
o.style.left=x;
o.style.top=y; 
}


// Needed to filter out events from contained objects in Netscape 6
function ContainsNN6 (container, containee) {
  var isParent = false;
  do {
    if ((isParent = container == containee))
      break;
   if (containee) { containee = containee.parentNode; } else { isParent=true; break; }
  }
  while (containee != null);
  return isParent;
}


function BTCPoint (theX, theY) {
	this.x=theX;
	this.y=theY;
}


function BTCNavTab (theDiv, theHome, theFrames, theFrameRate, theCurrentFrame, theDirection, theScrollLock, theGlobalObject) {
	var t=this;
	
	//set the instance variables
	t.controlDiv=theDiv;			//string equal to DIV name
	t.home=theHome;			       	//initial absolute location of DIV
	t.frames=theFrames;	       		//array[0-n] of BTCPoint objects defining offsets from home for each frame
	t.delay=1000/theFrameRate;
	t.currentFrame=theCurrentFrame;
	t.direction=theDirection;		//1 is opening, 0 is closing
	t.scrollLockBase=theScrollLock;         //the intended scroll lock state (max)
	t.globject=theGlobalObject;             //the global object that the NavTab object is stored in.... (string)
        t.lastFrame=(theFrames.length-1);
	t.scrollOffset= new BTCPoint(0,0); 
	t.tabLock=0;

	function Open () {
		if (t.tabLock==0) {t.direction=1; t.Animate(0);}
	}

	function Close () {
		if (t.tabLock==0) {t.direction=0; t.Animate(0);}
	}

	function Lock (theLock) {
		t.tabLock=theLock;
	}
	
	function ScrollLock (state) {
		//none==0, x==1, y==2, both==3 
		var d= new getObj(t.controlDiv);
		var dim= new objDimensions(d.obj);
		var divX=dim.width, divY=dim.height;
		var wins= new windowSS();
		var winX=wins.width, winY=wins.height;
		
		if ((state==1) && (winX < divX)) {state=0;}
		if ((state==2) && (winY < divY)) {state=0;}
		
		if ((state==3) && (winX < divX) && (winY > divY)) {state=2;}
		if ((state==3) && (winX > divX) && (winY < divY)) {state=1;}
		if ((state==3) && (winX < divX) && (winY < divY)) {state=0;}

		t.scrollLock=state;
	}
	t.ScrollLock=ScrollLock;
	t.ScrollLock(theScrollLock);
	
	function BusyTime() {
		return (t.frames.length*t.delay);
	}

	function Animate (u) {
		//Note: Animate does not care about the lock state because open() & close() handle that. 
		//Animate uses offsets form the 'home' location (NOT absolute coordinates)
		//u=0:animate,1:update,2:home(unused);

		//Update scrollOffset as needed
		var scrl= new windowSS();
		if (u!=2) {
		        if ((t.scrollLock==1)||(t.scrollLock==3)) {
			        //update x position to scroll
	        		t.scrollOffset.x=scrl.scrollX;
	        	} else {
			        t.scrollOffset.x=0;
			}
	               	if (t.scrollLock>1) {
	        		//update y position to scroll
		        	t.scrollOffset.y=scrl.scrollY;
		        } else { 
			        t.scrollOffset.y=0;
			}
		} 
		else { //Home the navtabs
		        t.scrollOffset.x=0;
			t.scrollOffset.y=0;
		}
		
		
		//incriment the current frame pointer if we haven't bumped up aginst the end of the frames array and if this in not an update.
		if (u==0) {
			if (t.direction==1 && t.currentFrame<t.lastFrame) {t.currentFrame=t.currentFrame+1;}
			if (t.direction==0 && t.currentFrame>0) {t.currentFrame=t.currentFrame-1;}
		}
		
		//acctual move code
		_Ps(t.controlDiv, t.home.x + t.frames[t.currentFrame].x + t.scrollOffset.x, t.home.y + t.frames[t.currentFrame].y + t.scrollOffset.y);
		
		//schedual the next frame event if we aren't at the end
		if (u==0) {
			if (t.currentFrame!=0 && t.currentFrame!=t.lastFrame) {
				//Note: setTimeout uses the context of window to execute the code, needs to be local context!
				setTimeout(t.globject+"['"+t.controlDiv+"'].Animate(0)", t.delay);
			}	
		}
	}

	//attach our functions to the new object making them methods
	t.Open=Open; 
	t.Close=Close;
	t.Lock=Lock;
	t.ScrollUpdate=function() {Animate(1);};
	t.Home=function() {Animate(2);};
        t.BusyTime=BusyTime;
	t.Animate=Animate;    //private method	
}

