
//================================================
//=
//=	Tim Scarfe - Reusable Object-Oriented Tab System
//=
//=	Distributed Under The GNU Lesser General Public Licence (gnu.org)
//=
//=	Updated - 02:06 25/09/2001
//=
//=	Construction Time - 18 Hours
//=
//=	http://tim.developer-x.com - webmaster@developer-x.com
//=
//=
//= 	***Update History***
//=
//=	(08:34 20/08/2001) 1.0 : Initial Release
//=	(14:12 25/08/2001) 1.1 : Added some additional Methods
//=	(00:16 07/09/2001) 1.2 : Support for the Strict Box Model (In IE6/MACIE5)
//=	(15:26 07/09/2001) 1.3 : Massive strict browser tweaks/method tweaks
//=	(14:46 15/09/2001) 1.4 : More Tweaks. You must use NUMBERS now. No Literals please.
//=	(11:54 23/09/2001) 1.6 : Added Full Support for NS6/Gecko AND Image Tabs !
//=	(02:05 25/09/2001) 1.7 : Event Handlers Added !
//=	(21:49 02/09/2004) 1.8 : HideTab added to hide a tab
//=
//================================================


//======================
//=
//=	Create Main Object Constructor
//=
//======================

TabSystemInstances = new Object( );

function tabSystem( name ) {

	TabSystemInstances[ name ] = 1;

	this.name = name;
	this.backgroundColor = "#ffffff";
	this.border = "1px black solid";
	this.height = 500;
	this.width = 500;
	this.top = 70;
	this.left = 100;
	this.spacing = 5;

	this.css = "font: 10px verdana; padding: 40px;";
	this.tabCss = "font: 10px verdana; padding: 3px; text-align: center;"

	this.hoverColor = "#dddddd"

	this.inactiveColor = "#eeeeee"
	this.tabWidth = 80;
	this.tabHeight = 20;
	this.tabOffsetX = 0;
	this.tabOffsetY = 0;
	this.tabs = new Array;

	this.onReset = new Function;
	this.onLoad = new Function;

	currentSys = name;
}

//======================
//=
//=	Method to add tabs
//=
//======================

tabSystem.prototype.addTab = function ( txt, align, orie, fn, css, w, h, hovcol ) {

	tb = this.tabs[ this.tabs.length ] = new Object( );

	tb.txt = txt;
	tb.fn = fn;
	tb.align = align;
	tb.css = css;
	tb.orie = orie;
	tb.w = w;
	tb.h = h;
	tb.hovcol = hovcol;
	tb.clicked = false;
	tb.cached = false;
}

tabSystem.prototype.hideTab = function ( idx ) {

	tb = this.tabs[ idx ];
	tb.w = 0;
	tb.cached = true;
}

//======================
//=
//=	Construct it
//=
//======================

tabSystem.prototype.construct = function ( e ) {

	t = b = l = r = this.spacing;

	if (!e) document.write('<div id="'+ this.name +'_Cont" style="z-index:0; top: '+ this.top +'px; left: '+ this.left +'px; height: '+ this.height +'px; width: '+ this.width +'px; position: absolute; border: '+ this.border +'; visibility: visible; background-color: '+ this.backgroundColor +'; '+ this.css +'">' + ((bw.ie)?"loading...":"") + '</div>')

	this.contDiv = new lib_obj( this.name + "_Cont" )

	if (bw.strict && !e) {

		// tweak the measure measurements (strict box model shit..)

		this.contDiv.css.width = parseInt( this.contDiv.css.width ) - ( parseInt( this.contDiv.w ) - this.width ) + "px"
		this.contDiv.css.height = parseInt( this.contDiv.css.height ) - ( parseInt( this.contDiv.h ) - this.height ) + "px"
	}

	for(var x=0;x<this.tabs.length;x++){
        if ( this.tabs[ x ].cached == false) {

            if ( this.tabs[ x ].orie == "t" ) {

                if (!e) document.write( '<div id="'+ this.name +'_tabs_'+ x +'" style="z-index:'+ (x+500) +';top: 0px; left: 0px; position: absolute; background-color: '+ this.inactiveColor +'; border: '+ this.border +';'+ this.tabCss +';'+ this.tabs[ x ].css +'">'+ this.tabs[ x ].txt  +'</div>' )

                this.tabs[ x ].el = new lib_obj( this.name +'_tabs_'+ x )

                this.tabs[ x ].el.css.cursor = (bw.ns6) ? "pointer" : "hand";

                this.tabs[ x ].el.clipTo(0, ( ( this.tabs[ x ].w) ? this.tabs[ x ].w : this.tabWidth )  , ( ( this.tabs[ x ].h ) ? this.tabs[ x ].h : this.tabHeight ) , 0, 1) // fix strict

                if ( this.tabs[ x ].align ) this.tabs[ x ].el.moveIt( ( this.tabs[ x ].align + this.tabOffsetX + this.left ), ( this.top + parseInt( this.border ) + this.tabOffsetY - ( ( this.tabs[ x ].h ) ? this.tabs[ x ].h : this.tabHeight ) ) )

                    else  this.tabs[ x ].el.moveIt( ( t + this.tabOffsetX + this.left ), ( this.top + this.tabOffsetY + parseInt( this.border ) - ( ( this.tabs[ x ].h ) ? this.tabs[ x ].h : this.tabHeight ) ) )

                t += this.spacing + ( ( this.tabs[ x ].w ) ? this.tabs[ x ].w : this.tabWidth ) + ( parseInt( this.tabs[ x ].el.css.borderWidth ) * 2 );

            } else if ( this.tabs[ x ].orie == "b" ) {

                if (!e) document.write( '<div id="'+ this.name +'_tabs_'+ x +'" style="z-index:'+ (x+500) +';top: 0px; left: 0px; position: absolute; background-color: '+ this.inactiveColor +'; border: '+ this.border +';'+ this.tabCss +';'+ this.tabs[ x ].css +'">'+ this.tabs[ x ].txt  +'</div>' )

                this.tabs[ x ].el = new lib_obj( this.name +'_tabs_'+ x )

                this.tabs[ x ].el.css.cursor = (bw.ns6) ? "pointer" : "hand";

                this.tabs[ x ].el.clipTo(0, ( ( this.tabs[ x ].w) ? this.tabs[ x ].w : this.tabWidth ) , ( ( this.tabs[ x ].h) ? this.tabs[ x ].h : this.tabHeight ), 0, 1) // fix strict

                if ( this.tabs[ x ].align ) this.tabs[ x ].el.moveIt( ( this.tabs[ x ].align + this.tabOffsetX + this.left ), (  this.top - parseInt( this.border ) + this.contDiv.h + this.tabOffsetY  ) )

                    else  this.tabs[ x ].el.moveIt( ( b + this.tabOffsetX +  this.left ), ( this.top - parseInt( this.border ) + this.contDiv.h + this.tabOffsetY  ) )

                b += this.spacing + ( ( this.tabs[ x ].w ) ? this.tabs[ x ].w : this.tabWidth ) + ( parseInt( this.tabs[ x ].el.css.borderWidth ) * 2 );

            } else if ( this.tabs[ x ].orie == "l" ) {

                alert("left tabs not yet implemented !!!"); break;

                l++

            } else if ( this.tabs[ x ].orie == "r" ) {

                alert("right tabs not yet implemented !!!"); break;

                r++
            }
        }
	}

	this.assignEvents( )

	if (!e) this.paintGecko( )

	if (!e) this.onLoad( )
}

//======================
//=
//=	Assign Events
//=
//======================

tabSystem.prototype.assignEvents = function ( e ) {

	for(var x=0;x<this.tabs.length;x++){
        if ( this.tabs[ x ].cached == false) {

            if (!this.tabs[ x ].hovcol) this.tabs[ x ].el.evnt.onmouseover = new Function( this.name + ".tabs["+ x +"].el.bg( "+ this.name +".hoverColor )")

                else this.tabs[ x ].el.evnt.onmouseover = new Function(this.name + ".tabs["+ x +"].el.bg('"+ this.tabs[ x ].hovcol +"')")

            if ( this.tabs[ x ].el.css.backgroundColor.search( new RegExp( this.inactiveColor , "i") ) == -1 ) {

                this.tabs[ x ].backgc = (!e) ? this.tabs[ x ].el.css.backgroundColor : this.inactiveColor;

                this.tabs[ x ].el.evnt.onmouseout = new Function( this.name + ".tabs["+ x +"].el.bg('"+ this.tabs[ x ].backgc +"') ")

            } else this.tabs[ x ].el.evnt.onmouseout = new Function( this.name + ".tabs["+ x +"].el.bg('"+ this.inactiveColor +"')")

            if ( this.tabs[ x ].orie == "t" ) {

                this.tabs[ x ].el.evnt.onclick = new Function( this.name + ".buttonClicked('"+ x +"', 't');"+ ( (this.tabs[ x ].fn) ? "eval('"+ this.name +".tabs[ "+x+" ].fn()');" : ";") )

            } else if ( this.tabs[ x ].orie == "b" ) {

                this.tabs[ x ].el.evnt.onclick = new Function( this.name + ".buttonClicked('"+ x +"', 'b');"+ ( (this.tabs[ x ].fn) ? "eval('"+ this.name +".tabs[ "+x+" ].fn()');" : ";") )

            } else if ( this.tabs[ x ].orie == "l" ) {

                ;; // not yet ..

            } else if ( this.tabs[ x ].orie == "r" ) {

                ;; // not yet ..

            }
        }
	}
}

tabSystem.prototype.buttonClicked = function ( id, orie) {

	// reset everything first

	this.reset( )

	// Remove all events + move and change colour

	this.tabs[ id ].el.evnt.onmouseover = new Function;
	this.tabs[ id ].el.evnt.onmouseout = new Function;
	//this.tabs[ id ].el.evnt.onclick = new Function;
	this.tabs[ id ].el.bg( this.backgroundColor )
	this.tabs[ id ].el.css.cursor = "default"

	this.tabs[ id ].clicked = true;

	brdw = parseInt( this.contDiv.css.borderWidth )

	if (orie == "t") {

		this.tabs[ id ].el.css.borderWidth = brdw + "px "+brdw+"px 0px "+brdw+"px"

		if (bw.strict) {

			this.tabs[ id ].el.moveBy( 0, parseInt( this.contDiv.css.borderWidth ) )

		}

	} else if (orie == "b") {

		this.tabs[ id ].el.css.borderWidth = "0px "+brdw+"px "+brdw+"px "+brdw+"px"

	} else if (orie == "l") {

		;; // not yet ..

	} else if (orie == "r") {

		;; // not yet ..

	}
}

//======================
//=
//=	Resetting Tabs
//=
//======================

tabSystem.prototype.reset = function( e ) {

	for(var x=0;x<this.tabs.length;x++){

		if (this.tabs[ x ].clicked == true) {

			brdw = parseInt( this.contDiv.css.borderWidth );

			this.tabs[ x ].el.css.borderWidth = brdw + "px "+brdw+"px "+brdw+"px "+brdw+"px"

			this.tabs[ x ].el.bg( this.inactiveColor  )

			this.tabs[ x ].el.css.cursor = (bw.ns6) ? "pointer" : "hand";

			this.tabs[ x ].clicked = false;
		}
	}

	this.construct( 1 )

	this.assignEvents( 1 )

	this.onReset( )
}

//======================
//=
//=	Repositioning Tabs
//=
//======================

// Use this to pull up bottom/left/right tabs after resizing the cont div

tabSystem.prototype.repositionTabs = function( e ) {

	tabSet1.top=tabSet1.contDiv.y;
	tabSet1.left=tabSet1.contDiv.x;

	for(var x=0;x<this.tabs.length;x++){

		if (this.tabs[x].orie == "b") {

			this.contDiv = new lib_obj( this.name + "_Cont" )

			this.tabs[x].el.moveIt( this.tabs[ x ].el.x, ( parseInt( this.top ) + this.contDiv.h - parseInt( this.contDiv.css.borderWidth ) ) )
		}

		if (this.tabs[x].orie == "t") {

			this.contDiv = new lib_obj( this.name + "_Cont" )

			this.tabs[x].el.moveIt( this.tabs[ x ].el.x, ( parseInt( this.top ) - parseInt( this.contDiv.css.borderWidth ) - this.tabHeight ) )
		}
	}

	curS = this.getSelection( )

	this.reset(  )

	if (curS) this.buttonClicked( curS[0], curS[1] )
}

//======================
//=
//=	Get Selection
//=
//======================

tabSystem.prototype.getSelection = function( e ) {

	for(i=0;i<this.tabs.length;i++) {

		if ( this.tabs[ i ].clicked == true ) return [ i, this.tabs[ i ].orie ]
	}
}

//======================
//=
//=	Perform Actions On Resize.
//=
//=	ARG[0] : ARR : T , B, L, R (Numbers) / 0 bool
//=	ARG[1] : ARR : Anim ? (Bool), Dist (Num), Timeout (Num)
//=	ARG[2] : if ARR[0] == 0 { Resize BY ARR[ T, B, L, R ]
//=
//======================

tabSystem.prototype.doResize = function( e ) {


}

//======================
//=
//=	Move an entire tabset, (with arguments)
//=
//=	(Top/Left) 	ARG[0] : ARR[ Top: Number, Left: Number]
//=	(Anim ?) 		ARG[1] : ARR[ Distance: Number, Timeout: Number ]
//=	(Filter Use?)	ARG[2] : ARR[ YesNo: Bool, TypeandDur: String ] //(11:53 23/09/2001) Not Added Yet
//=	(Timeout)	ARR[3] : ARR[ Timeout: Number ]
//=
//======================

tabSystem.prototype.moveTo = function( pos, anim, filt, time, e ) {

	this.showHideTabs( 0 )

	this.top=pos[ 0 ];
	this.left=pos[ 1 ];

	if (anim) this.contDiv.slideIt( pos[0], pos[1], anim[0], anim[1], this.name + ".repositionTabs( );" + this.name + ".showHideTabs( 1 );")

	else this.contDiv.moveIt( pos[ 0 ], pos[ 1 ] );

	if (!anim) this.showHideTabs( 1 )

	tabSet1.top=tabSet1.contDiv.y;
	tabSet1.left=tabSet1.contDiv.x;
}

//======================
//=
//=	Centre an entire tabset Horizontally, added (02:13 03/10/2001)
//=
//======================

tabSystem.prototype.centerIt = function(  ) {

	this.moveTo( [(parseInt( new lib_doc_size( ).x2 )/2)-(parseInt(this.contDiv.w)/2), this.top] )
}

//======================
//=
//=	Resize an entire tabset, (with arguments)
//=
//======================

tabSystem.prototype.resizeTo = function( e ) {

}

//======================
//=
//=	Show / Hide Tabs on a set
//=
//======================

tabSystem.prototype.showHideTabs = function( showHide, filt ) {

	for(x=0;x<this.tabs.length;x++) this.tabs[x].el[ ( ( showHide ) ? "show" : "hide" ) + "It" ] ( )
}

//======================
//=
//=	Re-Paint Gecko Needed Due To Bug (Thanks to Aaron Boodman for this) (not needed for gecko.95+)
//=
//======================

tabSystem.prototype.paintGecko = function( e ) {

	if ( bw.gecko ) {

		if ( new Number( navigator.userAgent.match(/(rv:\d\.(\d\.\d+))/)[ 2 ] ) <= 9.2) {

			window.resizeBy(0,1);
			window.resizeBy(0,-1);
		}
	}
}

//======================
//=
//=	Hide/Show an entire tabset ?
//=
//======================

tabSystem.prototype.showHideTabset= function( showHide, filt ) {

	this.contDiv[((showHide)?"show":"hide") + "It"]( )

	for(x=0;x<this.tabs.length;x++) this.tabs[x].el[((showHide)?"show":"hide") + "It"]( )
}