//	cbe.js
//	Cross-Browser Elements - Javascript Library version 1.2

//	Opera support - v1.2, 12/31/00
//	Tested with IE 4.01, IE 5.0, NN 4.75, Moz M18, and Opera 5.1.
//	version 1.01, December 8, 2000
//	mfoster@cybrtyme.com
//	http://lineoflight.com/
//	http://www.mikefoster.f2s.com/
//  Edited by Brisid to reduce filesize


// CrossBrowserElement Object Constructor:

function CrossBrowserElement(eleId, width, height)
{
	// Properties:
	this.id = eleId;
	this.ele = null;
	this.x = 0;
	this.y = 0;
	this.width = 0;
	this.height = 0;
	this.clipping = false;
	this.xMoving = false;
	this.yMoving = false;
	this.xTarget = 0;
	this.yTarget = 0;
	this.clipSpeed = 50;
	this.xSpeed = .5;
	this.ySpeed = .6;

	// Methods (high-level):
	this.setSize = cbeSetSize;
	this.moveTo = cbeMoveTo;
	this.moveToPos = cbeMoveToPos;
	this.moveBy = cbeMoveBy;
	this.slideTo = cbeSlideTo;
	this.slideToPos = cbeSlideToPos;
	this.slideToX = cbeSlideToX;
	this.slideToY = cbeSlideToY;
	this.scrollBy = cbeScrollBy;
	this.clipBy = cbeClipBy;
	this.autoClip = cbeAutoClip;
	this.getPos = cbeGetPos;

	// Methods (browser-specific):
	this.setLeft = domSetLeft;
	this.getLeft = domGetLeft;
	this.setTop = domSetTop;
	this.getTop = domGetTop;
	this.setZIndex = domSetZIndex;
	this.getZIndex = domGetZIndex;
	this.setWidth = domSetWidth;
	this.getWidth = domGetWidth;
	this.setHeight = domSetHeight;
	this.getHeight = domGetHeight;
	this.setClip = domSetClip;
	this.getClip = domGetClip;
	this.getClipTop = domGetClipTop;
	this.getClipRight = domGetClipRight;
	this.getClipBottom = domGetClipBottom;
	this.getClipLeft = domGetClipLeft;
	this.getClipWidth = domGetClipWidth;
	this.getClipHeight = domGetClipHeight;
	this.getClipArray = domGetClipArray;
	this.show = domShow;
	this.hide = domHide;
	this.isVisible = domIsVisible;
	this.setHtml = domSetHtml;
	this.setBgColor = domSetBgColor;
	this.setBgImage = domSetBgImage;

	// Assign browser-specifics:

	if (document.getElementById) {
		this.ele = document.getElementById(eleId);
		if (is.opera) {
			this.setLeft = opSetLeft;
			this.getLeft = opGetLeft;
			this.setTop = opSetTop;
			this.getTop = opGetTop;
			this.setWidth = opSetWidth;
			this.setHeight = opSetHeight;
			this.setClip = 
			this.getClip = 
			this.getClipTop = 
			this.getClipRight = 
			this.getClipBottom = 
			this.getClipLeft = 
			this.getClipArray = returnZero;
			this.getClipWidth = domGetWidth;
			this.getClipHeight = domGetHeight;
			this.show = opShow;
			this.setHtml = returnZero;
			this.setBgColor = opSetBgColor;
			this.setBgImage = returnZero;
			
		}
	}
	else if (is.ie4up) {
		this.ele = document.all[eleId];
	}
	else if (is.nav4up) {
		this.ele = document.layers[eleId];
		this.setLeft = nnSetLeft;
		this.getLeft = nnGetLeft;
		this.setTop = nnSetTop;
		this.getTop = nnGetTop;
		this.setZIndex = nnSetZIndex;
		this.getZIndex = nnGetZIndex;
		this.setWidth = nnSetWidth;
		this.getWidth = nnGetWidth;
		this.setHeight = nnSetHeight;
		this.getHeight = nnGetHeight;
		this.setClip = nnSetClip;
		this.getClip = nnGetClip;
		this.getClipTop = nnGetClipTop;
		this.getClipRight = nnGetClipRight;
		this.getClipBottom = nnGetClipBottom;
		this.getClipLeft = nnGetClipLeft;
		this.getClipWidth = nnGetClipWidth;
		this.getClipHeight = nnGetClipHeight;
		this.getClipArray = nnGetClipArray;
		this.show = nnShow;
		this.hide = nnHide;
		this.isVisible = nnIsVisible;
		this.setHtml = nnSetHtml;
		this.setBgColor = nnSetBgColor;
		this.setBgImage = nnSetBgImage;
	}
	else {
		alert("This javascript will not run on your browser!");
		return;
	}
	if (!this.ele) {
		alert(eleId + " does not exist");
		return;
	}

	if (arguments.length > 1) {
		this.setSize(width, height);
		this.setClip(0, width , height , 0);
		this.moveTo(-width, -height);
		this.hide();
	}
}

//-------
// CrossBrowserElement Method Definitions:

//-------
// Move element to x,y position.

function cbeMoveTo(newX, newY)
{
	this.setLeft(newX);
	this.setTop(newY);
}

//-------
// Move element to logical position.

function cbeMoveToPos(pos, margin, outside)
{
	this.getPos(pos, margin, outside);
	this.setLeft(this.x);
	this.setTop(this.y);
}

//-------
// Get coordinates of logical position and assign to this.x and this.y

function cbeGetPos(pos, margin, outside)
{
	var x = this.getLeft();
	var y = this.getTop();
	var w = this.getClipWidth();
	var h = this.getClipHeight();
	var cw = getClientWidth();
	var ch = getClientHeight();
	var left = getScrollX();
	var top = getScrollY();
	var right = left + cw;
	var bottom = top + ch;
	var cenLeft = left + Math.floor(cw/2) - Math.floor(w/2);
	var cenTop = top + Math.floor(ch/2) - Math.floor(h/2);
	
	if (arguments.length > 1) {
		if (outside)
			margin = -margin;
		left += margin;
		top += margin;
		right -= margin;
		bottom -= margin;
	}

	switch (pos.toLowerCase()) {
		case 'center':
			x = cenLeft;
			y = cenTop;
			break;
		case 'centerH':
			x = cenLeft;
			break;
		case 'centerV':
			y = cenTop;
			break;	
		case 'n':
			if (outside) y = top - h;
			else y = top;
			break;
		case 'ne':
			if (outside) { x = right; y = top - h; }
			else { x = right - w; y = top; }
			break;
		case 'e':
			if (outside) x = right;
			else x = right - w;
			break;
		case 'se':
			if (outside) { x = right; y = bottom; }
			else { x = right - w; y = bottom - h }
			break;
		case 's':
			if (outside) y = top - h;
			else y = bottom - h;
			break;
		case 'sw':
			if (outside) { x = left - w; y = bottom; }
			else { x = left; y = bottom - h; }
			break;
		case 'w':
			if (outside) x = left - w;
			else x = left;
			break;
		case 'nw':
			if (outside) { x = left - w; y = top - h; }
			else { x = left; y = top; }
			break;
		default:
			alert("invalid 'pos' argument in getPos()");
	}
	this.x = x;
	this.y = y;
}

//-------
// Move element with respect to current position.

function cbeMoveBy(dX, dY)
{
	if (dX)
		this.setLeft(this.getLeft() + dX);
	if (dY)
		this.setTop(this.getTop() + dY);
}

//-------
// Set element's x position.

function domSetLeft(newX)
{
	this.ele.style.left = newX + "px";
}

function nnSetLeft(newX)
{
	this.ele.left = newX;
}

function opSetLeft(newX)
{
	this.ele.style.pixelLeft = newX;
}

//-------
// Set element's y position.

function domSetTop(newY)
{
	this.ele.style.top = newY + "px";
}

function nnSetTop(newY)
{
	this.ele.top = newY;
}

function opSetTop(newY)
{
	this.ele.style.pixelTop = newY;
}

//-------
// Get element's current x position.

function domGetLeft()
{
	return parseInt(this.ele.style.left);
}

function nnGetLeft()
{
	return this.ele.left;
}

function opGetLeft()
{
	return this.ele.style.pixelLeft;
}

//-------
// Get element's current y position.

function domGetTop()
{
	return parseInt(this.ele.style.top);
}

function nnGetTop()
{
	return this.ele.top;
}

function opGetTop()
{
	return this.ele.style.pixelTop;
}

//-------
// Set the element's z index.

function domSetZIndex(newZ)
{
	this.ele.style.zIndex = newZ;
}

function nnSetZIndex(newZ)
{
	this.ele.zIndex = newZ;
}

//-------
// Get the element's z index.

function domGetZIndex()
{
	return this.ele.style.zIndex;
}

function nnGetZIndex()
{
	return this.ele.zIndex;
}

//-------
// Set element's width and height.

function cbeSetSize(newWidth, newHeight)
{
	this.setWidth(newWidth);
	this.setHeight(newHeight);
}

//-------
// Set element's width.

function domSetWidth(newWidth)
{
	this.width = newWidth;
	this.ele.style.width = newWidth + "px";
}

function nnSetWidth(newWidth)
{
	this.width = newWidth;
}

function opSetWidth(newWidth)
{
	this.width = newWidth;
	this.ele.style.pixelWidth = newWidth;
}

//-------
// Set element's height.

function domSetHeight(newHeight)
{
	this.height = newHeight;
	this.ele.style.height = newHeight + "px";
}

function nnSetHeight(newHeight)
{
	this.height = newHeight;
}

function opSetHeight(newHeight)
{
	this.height = newHeight;
	this.ele.style.pixelHeight = newHeight;
}

//-------
// Get element's width.

function domGetWidth()
{
	return this.width;
}

function nnGetWidth()
{
	return this.width;
}

//-------
// Get element's height.

function domGetHeight()
{
	return this.height;
}

function nnGetHeight()
{
	return this.height;
}

//-------
// Show the element.

function domShow()
{
	this.ele.style.visibility = 'inherit';
}

function nnShow()
{
	this.ele.visibility = 'inherit';
}

function opShow()
{
	this.ele.style.visibility = 'visible';
}

//-------
// Hide the element.

function domHide()
{
	this.ele.style.visibility = 'hidden';
}

function nnHide()
{
	this.ele.visibility = 'hide';
}

//-------
// Return true if the element is visible (or vis is inherited), else false.

function domIsVisible()
{
	return (
		this.ele.style.visibility == 'visible'
		|| this.ele.style.visibility == 'inherit'
		|| this.ele.style.visibility == ''
	);
}

function nnIsVisible()
{
	return (
		this.ele.visibility == 'show'
		|| this.ele.visibility == 'inherit'
		|| this.ele.visibility == ''
	);
}

//-------
// Set the element's innerHTML.

function domSetHtml(newHtml)
{
	this.ele.innerHTML = newHtml;
}

function nnSetHtml(newHtml)
{
	if (newHtml == '') newHtml = ' ';
	this.ele.document.open();
	this.ele.document.write(newHtml);
	this.ele.document.close();
}

//-------
// Set the element's background color.

function domSetBgColor(newBgColor)
{
	if (newBgColor == null || newBgColor == 'transparent')
		newBgColor = null;
	this.ele.style.backgroundColor = newBgColor;
}

function nnSetBgColor(newBgColor)
{
	if (newBgColor == null || newBgColor == 'transparent')
		newBgColor = null;
	this.ele.bgColor = newBgColor;
}

function opSetBgColor(newBgColor)
{
	this.ele.style.background = newBgColor;
}

//-------
// Set the element's background image.

function domSetBgImage(newBgImage)
{
	this.ele.style.backgroundImage = "url(" + newBgImage + ")";
}

function nnSetBgImage(newBgImage)
{
	this.ele.background.src = newBgImage || null;
}

//-------
// Slide element to x,y position.

function cbeSlideTo(newXTarget, newYTarget)
{
	if ( newXTarget != null)
		this.slideToX(newXTarget);
	if ( newYTarget != null)
		this.slideToY(newYTarget);
}

//-------
// Slide element to logical position.

function cbeSlideToPos(pos, margin, outside)
{
	this.getPos(pos, margin, outside);
	this.slideToX(this.x);
	this.slideToY(this.y);
}

//-------
// Slide element to x position.
// assumes id == object variable name

function cbeSlideToX(newXTarget, iterating)
{
	var delta, currentX;

	if (!this.xMoving) {
		this.xTarget = newXTarget;
	}
	else if (!iterating) {
		this.xTarget = newXTarget;
		return;
	}
	currentX = this.getLeft();
	this.xMoving = true;
	if (this.xSpeed < 1) {
		delta = this.xSpeed * Math.abs(Math.abs(currentX) - Math.abs(this.xTarget));
		if (delta < 1) delta = 1;
	}
	else
		delta = this.xSpeed;
	if (currentX < this.xTarget) {
		if (currentX + delta <= this.xTarget)
			this.setLeft(currentX + delta);
		else
			this.setLeft(this.xTarget);
	}
	else if (currentX > this.xTarget) {
		if (currentX - delta >= this.xTarget)
			this.setLeft(currentX - delta);
		else
			this.setLeft(this.xTarget);
	}
	else {
		this.xMoving = false;
		return;
	}
	setTimeout(this.id+".slideToX("+this.xTarget+","+true+")",25);
}

//-------
// Slide element to y position.
// assumes id == object variable name

function cbeSlideToY(newYTarget, iterating)
{
	var delta, currentY;

	if (!this.yMoving) {
		this.yTarget = newYTarget;
	}
	else if (!iterating) {
		this.yTarget = newYTarget;
		return;
	}
	currentY = this.getTop();
	this.yMoving = true;
	if (this.ySpeed < 1) {
		delta = this.ySpeed * Math.abs(Math.abs(currentY) - Math.abs(this.yTarget));
		if (delta < 1) delta = 1;
	}
	else
		delta = this.ySpeed;
	if (currentY < this.yTarget) {
		if (currentY + delta <= this.yTarget)
			this.setTop(currentY + delta);
		else
			this.setTop(this.yTarget);
	}
	else if (currentY > this.yTarget) {
		if (currentY - delta >= this.yTarget)
			this.setTop(currentY - delta);
		else
			this.setTop(this.yTarget);
	}
	else {
		this.yMoving = false;
		return;
	}
	setTimeout(this.id+".slideToY("+this.yTarget+","+true+")",25);
}

//-------
//

function returnZero()
{
	return 0;
}

//-------
// Set the clipping region.

function domSetClip(top, right, bottom, left)
{
	var clipRect =
		"rect("
		+ top + "px "
		+ right + "px "
		+ bottom + "px "
		+ left + "px"
		+ ")";

	this.ele.style.clip = clipRect;
}

function nnSetClip(top, right, bottom, left)
{
	this.ele.clip.top = top;
	this.ele.clip.right = right;
	this.ele.clip.bottom = bottom;
	this.ele.clip.left = left;
}

//-------
// Get the clipping region as the css clip value (a string).

function domGetClip() {
	return this.ele.style.clip;
}

function nnGetClip()
{
	var clipRect =
		"rect("
		+ this.ele.clip.top + "px "
		+ this.ele.clip.right + "px "
		+ this.ele.clip.bottom + "px "
		+ this.ele.clip.left + "px"
		+ ")";
	return clipRect;
}

//-------
// Get the clipping region as an array of individual values.
// a[1]==top, a[2]==right, a[3]==bottom, a[4]==left

function domGetClipArray()
{
	var re = /\(|px,?\s?\)?/;
	return this.ele.style.clip.split(re);
}

function nnGetClipArray()
{
	alert('method not implemented for NN4');
}

//-------
// Get individual clipping region values.

function domGetClipTop()
{
	var a = this.getClipArray();
	return parseInt(a[1]);
}

function nnGetClipTop()
{
	return this.ele.clip.top;
}
//--
function domGetClipRight()
{
	var a = this.getClipArray();
	return parseInt(a[2]);
}

function nnGetClipRight()
{
	return this.ele.clip.right;
}
//--
function domGetClipBottom()
{
	var a = this.getClipArray();
	return parseInt(a[3]);
}

function nnGetClipBottom()
{
	return this.ele.clip.bottom;
}
//--
function domGetClipLeft()
{
	var a = this.getClipArray();
	return parseInt(a[4]);
}

function nnGetClipLeft()
{
	return this.ele.clip.left;
}

//-------
// Get clipping region width and height.

function domGetClipWidth()
{
	var a = this.getClipArray();
	return (a[2] - a[4]);
}

function nnGetClipWidth()
{
	return this.ele.clip.width;
}

function domGetClipHeight()
{
	var a = this.getClipArray();
	return (a[3] - a[1]);
}

function nnGetClipHeight()
{
	return this.ele.clip.height;
}

//-------
// If cmd=='clip', clip edge until clip coords==0.
// If cmd=='unclip', unclip edge until coords reach element dimensions.

function cbeAutoClip(edge, cmd, dt, dr, db, dl)
{
	if (arguments.length == 2) {
		if (this.clipping) return;
		else this.clipping = true;
		var unclip = true;
		var w = this.getWidth();
		var h = this.getHeight();
		var xcs = Math.abs(this.clipSpeed);
		var ycs = xcs;
		// Get x and y speeds that are proportional
		// to the element's width and height
		if (h > w) {
			ycs *= (h/w);
		}
		else if(w > h) {
			xcs *= (w/h);
		}
		// Setup clip parameters
		// and initial clip position
		if (cmd.toLowerCase() == 'clip') {
			xcs *= -1;
			ycs *= -1;
			unclip = false;
			this.setClip(0, w, h, 0);
		}
		switch(edge.toLowerCase()) {
			case 'n':
				dt = -ycs; dr = 0; db = 0; dl = 0;
				if (unclip) this.setClip(h, w, h, 0);
				break;
			case 'ne':
				dt = -ycs; dr = xcs; db = 0; dl = 0;
				if (unclip) this.setClip(h, 0, h, 0);
				break;
			case 'e':
				dt = 0; dr = xcs; db = 0; dl = 0;
				if (unclip) this.setClip(0, 0, h, 0);
				break;
			case 'se':
				dt = 0;	 dr = xcs; db = ycs; dl = 0;
				if (unclip) this.setClip(0, 0, 0, 0);
				break;
			case 's':
				dt = 0;	 dr = 0; db = ycs; dl = 0;
				if (unclip) this.setClip(0, w, 0, 0);
				break;
			case 'sw':
				dt = 0;	 dr = 0; db = ycs; dl = -xcs;
				if (unclip) this.setClip(0, w, 0, w);
				break;
			case 'w':
				dt = 0;	 dr = 0; db = 0;	dl = -xcs;
				if (unclip) this.setClip(0, w, h, w);
				break;
			case 'nw':
				dt = -ycs; dr = 0; db = 0;	dl = -xcs;
				if (unclip) this.setClip(h, w, h, w);
				break;
			case 'center':
				dt = -ycs; dr = xcs; db = ycs; dl = -xcs;
				if (unclip) this.setClip(h/2, w/2, h/2, w/2);
//				if (unclip) this.setClip(h, 0, 0, w);
				break;	
			default:
				alert("invalid direction in autoClip()");
		}
	}		// end if
	
	if (this.clipBy(dt, dr, db, dl))
		setTimeout(this.id+".autoClip("+null+","+null+","+dt+","+dr+","+db+","+dl+")",10);
	else
		this.clipping = false;
}

//-------
// Scroll the element by moving and clipping.

function cbeScrollBy(dx, dy) {

	var ct = this.getClipTop();
	var cr = this.getClipRight();
	var cb = this.getClipBottom();
	var cl = this.getClipLeft();

	// Don't scroll beyond the edge of the element
	if (cl + dx < 0) {
		cl = 0;
		dx = 0;
	}
	else if (cr + dx > this.getWidth()) {
		cr = cl + this.getClipWidth();
		dx = 0;
	}
	if (ct + dy < 0) {
		ct = 0;
		dy = 0;
	}
	else if (cb + dy > this.getHeight()) {
		cb = ct + this.getClipHeight();
		dy = 0;
	}

// Move and clip to simulate scrolling
	this.setClip(ct + dy, cr + dx, cb + dy, cl + dx);
	this.moveBy(-dx, -dy);
}

//-------
// Clip an element by a relative amount.
// Return false when there is no change.

function cbeClipBy(dt, dr, db, dl) {

	var ct = this.getClipTop();
	var cr = this.getClipRight();
	var cb = this.getClipBottom();
	var cl = this.getClipLeft();
	var w = this.getWidth();
	var h = this.getHeight();

	// Don't clip beyond the existing width and height of the element
	// and don't let top/bottom and left/right coords cross.

	// Top
	if (ct + dt < 0) {
		ct = 0; dt = 0;
	}
	else if (ct + dt > cb) {
		ct = cb; dt = 0;
	}
	// Right
	if (cr + dr < cl) {
		cr = cl; dr = 0;
	}
	else if (cr + dr > w) {
		cr = w; dr = 0;
	}
	// Bottom
	if (cb + db < ct) {
		cb = ct; db = 0;
	}
	else if (cb + db > h) {
		cb = h; db = 0;
	}
	// Left
	if (cl + dl < 0) {
		cl = 0; dl = 0;
	}
	else if (cl + dl > cr) {
		cl = cr; dl = 0;
	}

	this.setClip(ct + dt, cr + dr, cb + db, cl + dl);

	if (dt || dr || db || dl) return true;
	else return false;
}

// End of CrossBrowserElement Methods
//-------


//-------
// Get client area width.

function getClientWidth()
{
	var w = 0;
	if (is.nav4up) {
		w = window.innerWidth;
		if (document.height > window.innerHeight) // has vert scrollbar
			w -= 16;
	}
	else if (is.ie4up) {
		w = document.body.clientWidth;
	}
	else if (is.opera) {
		w = window.innerWidth;
	}
	return w;
}

//-------
// Get client area height.

function getClientHeight()
{
	var h = 0;
	if (is.nav4up) {
		h = window.innerHeight;
		if (document.width > window.innerWidth) // has horz scrollbar
			h -= 16;
	}
	else if (is.ie4up) {
		h = document.body.clientHeight;
	}
	else if (is.opera) {
		h = window.innerHeight;
	}
	return h;
}

//-------
// Get x scroll position.
// The number of pixels the document has scrolled horizontally.

function getScrollX()
{
	var offset;
	if (is.nav4up || is.opera) {
		offset = window.pageXOffset;
	}
	else if (is.ie4up) {
		offset = document.body.scrollLeft;
	}
	return offset;
}

//-------
// Get y scroll position.
// The number of pixels the document has scrolled vertically.

function getScrollY()
{
	var offset;
	if (is.nav4up || is.opera) {
		offset = window.pageYOffset;
	}
	else if (is.ie4up) {
		offset = document.body.scrollTop;
	}
	return offset;
}

//-------
// Get a reference to an Element object
// This is a cross-browser version of getElementById().

function getElementRef(eleId)
{
	var ele;

	if (document.getElementById)
		ele = document.getElementById(eleId);
	else if (is.ie4up)
		ele = document.all[eleId];
	else if (is.nav4up)
		ele = document.layers[eleId];

	return ele;
}

//-------
// ClientSnifferJr Object Constructor.
// This is a simplified version of the Client Sniffer code found at
// http://developer.netscape.com/docs/examples/javascript/browser_type.html

function ClientSnifferJr()
{
	this.ua = navigator.userAgent.toLowerCase();
	this.major = parseInt(navigator.appVersion);
	this.minor = parseFloat(navigator.appVersion);
	this.nav	 = (
		(this.ua.indexOf('mozilla')!=-1)
		&& ((this.ua.indexOf('spoofer')==-1)
		&& (this.ua.indexOf('compatible') == -1))
	);
	this.nav4	= (this.nav && (this.major == 4));
	this.nav4up= (this.nav && (this.major >= 4));
	this.nav5up= (this.nav && (this.major >= 5));
	this.gecko = (this.ua.indexOf('gecko') != -1); 
	this.ie		= (this.ua.indexOf("msie") != -1);
	this.ie3	 = (this.ie && (this.major == 2));
	this.ie4	 = (
		this.ie && (this.major == 4)
		&& (this.ua.indexOf("msie 5.0")==-1)
	);
	this.ie4up = (this.ie	&& (this.major >= 4));
	this.ie5up = (this.ie && !this.ie3 && !this.ie4);
	this.opera = (this.ua.indexOf("opera") != -1);
	this.hotjava = (this.ua.indexOf("hotjava") != -1); 
	this.webtv = (this.ua.indexOf("webtv") != -1);
	this.aol	 = (this.ua.indexOf("aol") != -1); 
}

var is = new ClientSnifferJr();

