// spLib by rod.o2theory.com | soloplay@msn.com
// keep these two lines and you're free to use this code

// last update: 08.29.2003

// Global reference to the dhtml object
spMakeObject.registry = new Array();

// Object constructor
function spMakeObject(id)
{
	this.el = document.getElementById ? document.getElementById(id) : null;
	this.css = this.el.style;
	this.i = spMakeObject.registry.length;
	spMakeObject.registry[this.i] = this;
	this.w = this.el.offsetWidth ? this.el.offsetWidth : 0;
	this.h = this.el.offsetHeight ? this.el.offsetHeight : 0;
	this.x = this.el.offsetLeft ? this.el.offsetLeft : 0;
	this.y = this.el.offsetTop ? this.el.offsetTop : 0;
	this.o = 100;
	this.slideTimer = 0;
	this.resizeTimer = 0;
	this.fadeTimer = 0;
}

// Update object values
spMakeObject.prototype.update = function()
{
	this.w = this.el.offsetWidth ? this.el.offsetWidth : 0;
	this.h = this.el.offsetHeight ? this.el.offsetHeight : 0;
	this.x = this.el.offsetLeft ? this.el.offsetLeft : 0;
	this.y = this.el.offsetTop ? this.el.offsetTop : 0;
}

// Moves a layer to (x, y) pixels
spMakeObject.prototype.moveTo = function(x, y)
{
	if (x != null && typeof x == 'number')
	{
		x = Math.round(x);
		this.x = x;
		this.css.left = x + 'px';
	}
	if (y != null && typeof y == 'number')
	{
		y = Math.round(y);
		this.y = y;
		this.css.top = y + 'px';
	}
}

// Moves a layer by (x, y) pixels
spMakeObject.prototype.moveBy = function(x, y) { this.moveTo(this.x + x, this.y + y); }

// Visibility
spMakeObject.prototype.show = function() { this.css.visibility = 'visible'; }
spMakeObject.prototype.hide = function() { this.css.visibility = 'hidden'; }

// Resize layer to (width, height) pixels
spMakeObject.prototype.setSize = function(w, h)
{
	if (w != null && typeof w == 'number')
	{
		w = Math.round(w);
		this.css.width = w + 'px';
		this.w = this.el.offsetWidth ? this.el.offsetWidth : w;
	}
	if (h != null && typeof h == 'number')
	{
		h = Math.round(h);
		this.css.height = h + 'px';
		this.h = this.el.offsetHeight ? this.el.offsetHeight : h;
	}
}

// Write content to layer
spMakeObject.prototype.write = function(text)
{
	if (typeof this.el.innerHTML != 'undefined')
	{
		this.el.innerHTML = text;
		this.update();
	}
}

// Set layer opacity (in percent, between 0 and 100)
spMakeObject.prototype.setOpacity = function(o)
{
	if (typeof this.css.MozOpacity != 'undefined') { this.css.MozOpacity = (o / 100); this.o = o; }
	else if (this.el.filters) { this.css.filter = 'alpha(opacity=' + o + ')'; this.o = o; }
}

// slideTo(); slides a layer from it's current position to another point over a specified time period.
// x, y		= destination coordinates in pixels
// duration = how long in milliseconds to do the animation for
// acc		= coefficient of accelleration: 1 = accelerate; 0 = linear; -1 = deccelerate
// fn		= execute onSlideEnd() function when animation has finished?
spMakeObject.prototype.slideTo = function(x, y, duration, acc, fn)
{
	clearInterval(this.slideTimer);
	if (!acc) acc = 0;
	if (!fn) fn = null;
	var startTime = new Date().valueOf();
	var endTime = startTime + duration;
	this.slideTimer = setInterval('spMakeObject.registry[' + this.i + '].slide(' + this.x + ', ' + this.y + ', ' + x + ', ' + y + ', ' + acc + ', ' + startTime + ', ' + endTime + ', ' + fn + ')', 10);
}

spMakeObject.prototype.onSlideEnd = new Function();

spMakeObject.prototype.slide = function(startX, startY, endX, endY, acc, startTime, endTime, fn)
{
	var currentTime = new Date().valueOf();
	if (currentTime >= endTime)
	{
		clearInterval(this.slideTimer);
		this.slideTimer = 0;
		this.moveTo(endX, endY);
		if (fn != null) this.onSlideEnd();
	}
	else
	{
		var percent = (currentTime - startTime) / (endTime - startTime);
		var c1 = new spMakeObject.coord(startX, startY);
		var c2 = new spMakeObject.coord(endX, endY);
		var c3 = new spMakeObject.coord(c1.x + ((1 + -acc) * (c2.x - c1.x) / 3), c1.y + ((1 + -acc) * (c2.y - c1.y) / 3));
		var c4 = new spMakeObject.coord(c1.x + ((2 + -acc) * (c2.x - c1.x) / 3), c1.y + ((2 + -acc) * (c2.y - c1.y) / 3));
		var pos = spMakeObject.getBezier(percent, c1, c2, c3, c4);
		this.moveTo(pos.x, pos.y);
	}
}

// resizeTo(); resizes a layer from it's current size to another size over a specified time period.
// w, h		= destination (width, height) in pixels
// duration = how long in milliseconds to do the animation for
// acc		= coefficient of accelleration: 1 = accelerate; 0 = linear; -1 = deccelerate
// fn		= execute onResizeEnd() function when animation has finished?
spMakeObject.prototype.resizeTo = function(w, h, duration, acc, fn)
{
	clearTimeout(this.resizeTimer);
	if (!acc) acc = 0;
	if (!fn) fn = null;
	var startTime = new Date().valueOf();
	var endTime = startTime + duration;
	this.resizeTimer = setInterval('spMakeObject.registry[' + this.i + '].resize(' + this.w + ', ' + this.h + ', ' + w + ', ' + h + ', ' + acc + ', ' + startTime + ', ' + endTime + ', ' + fn + ')', 10);
}

spMakeObject.prototype.onResizeEnd = new Function();

spMakeObject.prototype.resize = function(startW, startH, endW, endH, acc, startTime, endTime, fn)
{
	var currentTime = new Date().valueOf();
	if (currentTime >= endTime)
	{
		clearInterval(this.resizeTimer);
		this.resizeTimer = 0;
		this.setSize(endW, endH);
		if (fn != null) this.onResizeEnd();
	}
	else
	{
		var percent = (currentTime - startTime) / (endTime - startTime);
		var c1 = new spMakeObject.coord(startW, startH);
		var c2 = new spMakeObject.coord(endW, endH);
		var c3 = new spMakeObject.coord(c1.x + ((1 + -acc) * (c2.x - c1.x) / 3), c1.y + ((1 + -acc) * (c2.y - c1.y) / 3));
		var c4 = new spMakeObject.coord(c1.x + ((2 + -acc) * (c2.x - c1.x) / 3), c1.y + ((2 + -acc) * (c2.y - c1.y) / 3));
		var pos = spMakeObject.getBezier(percent, c1, c2, c3, c4);
		this.setSize(pos.x, pos.y);
	}
}

// fade animation
// o		= target opacity to fade to
// duration = how long in milliseconds to do the animation for
// acc		= coefficient of accelleration: 1 = accelerate; 0 = linear; -1 = deccelerate
// fn		= execute onResizeEnd() function when animation has finished?
spMakeObject.prototype.fadeTo = function(o, duration, acc, fn)
{
	clearTimeout(this.fadeTimer);
	if (!acc) acc = 0;
	if (!fn) fn = null;
	var startTime = new Date().valueOf();
	var endTime = startTime + duration;
	this.fadeTimer = setInterval('spMakeObject.registry[' + this.i + '].fade(' + this.o + ', ' + o + ', ' + acc + ', ' + startTime + ', ' + endTime + ', ' + fn + ')', 10);
}

spMakeObject.prototype.onFadeEnd = new Function();

spMakeObject.prototype.fade = function(startO, endO, acc, startTime, endTime, fn)
{
	var currentTime = new Date().valueOf();
	if (currentTime >= endTime)
	{
		clearInterval(this.fadeTimer);
		this.fadeTimer = 0;
		this.setOpacity(endO);
		if (fn != null) this.onFadeEnd();
	}
	else
	{
		var percent = (currentTime - startTime) / (endTime - startTime);
		var c1 = new spMakeObject.coord(startO, startO);
		var c2 = new spMakeObject.coord(endO, endO);
		var c3 = new spMakeObject.coord(c1.x + ((1 + -acc) * (c2.x - c1.x) / 3), c1.y + ((1 + -acc) * (c2.y - c1.y) / 3));
		var c4 = new spMakeObject.coord(c1.x + ((2 + -acc) * (c2.x - c1.x) / 3), c1.y + ((2 + -acc) * (c2.y - c1.y) / 3));
		var pos = spMakeObject.getBezier(percent, c1, c2, c3, c4);
		this.setOpacity(pos.x);
	}
}

// bezier math (calculates a given position along a bezier curve specified by 2, 3 or 4 control points)
spMakeObject.b1 = function(t) { return (t * t * t); }
spMakeObject.b2 = function(t) { return (3 * t * t * (1 - t)); }
spMakeObject.b3 = function(t) { return (3 * t * (1 - t) * (1 - t)); }
spMakeObject.b4 = function(t) { return ((1 - t) * (1 - t) * (1 - t)); }

// coordinate constructor
spMakeObject.coord = function(x, y) { if (!x) var x = 0; if (!y) var y = 0; return { x: x, y: y } }

// finds the coordinates of a point at a certain stage through a bezier curve
spMakeObject.getBezier = function(percent, c1, c2, c3, c4)
{
	var pos = new spMakeObject.coord();
	pos.x = c2.x * spMakeObject.b1(percent) + c4.x * spMakeObject.b2(percent) + c3.x * spMakeObject.b3(percent) + c1.x * spMakeObject.b4(percent);
	pos.y = c2.y * spMakeObject.b1(percent) + c4.y * spMakeObject.b2(percent) + c3.y * spMakeObject.b3(percent) + c1.y * spMakeObject.b4(percent);
	return pos;
}



// Tool kit (functions or tools used for scripts)
var spToolkit = {
	// attach event to an element
	addListener: function(obj, et, fn, capture)
	{
		if (obj.addEventListener) { obj.addEventListener(et, fn, capture); return true; }
		else if (obj.attachEvent) { var ae = obj.attachEvent('on' + et, fn); return ae; }
		else { obj['on' + et] = fn; }
	},

	// detach event from an element
	removeListener: function(obj, et, fn, capture)
	{
		if (obj.removeEventListener) { obj.removeEventListener(et, fn, capture); return true; }
		else if (obj.detachEvent) { var re = obj.detachEvent('on' + et, fn); return re; }
		else { obj['on' + et] = null; }
	},

	// fix events
	fixEvents: function(e, currentTarget)
	{
		if (!e) e = event;
		if (!e.target) e.target = e.srcElement;
		if (!e.currentTarget) e.currentTarget = currentTarget;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		if (typeof e.clientX == 'undefined') e.clientX = e.pageX;
		if (typeof e.clientY == 'undefined') e.clientY = e.pageY;
		if (!e.stopPropagation) e.stopPropagation = function() { this.cancelBubble = true; }
		if (!e.preventDefault) e.preventDefault = function() { this.returnValue = false; }
		return e;
	},

	// Get width, height and scroll offsets
	getViewport: function()
	{
		if (document.documentElement && document.documentElement.scrollLeft) this.scrollX = document.documentElement.scrollLeft;
		else if (document.body && document.body.scrollLeft) this.scrollX = document.body.scrollLeft;
		else if (window.scrollX) this.scrollX = window.scrollX;
		else if (window.pageXOffset) this.scrollX = window.pageXOffset;
		else this.scrollX = 0;

		if (document.documentElement && document.documentElement.scrollTop) this.scrollY = document.documentElement.scrollTop;
		else if (document.body && document.body.scrollTop) this.scrollY = document.body.scrollTop;
		else if (window.scrollY) this.scrollY = window.scrollY;
		else if (window.pageYOffset) this.scrollY = window.pageYOffset;
		else this.scrollY = 0;
		
		if (document.documentElement && document.documentElement.clientWidth) this.width = document.documentElement.clientWidth;
		else if (document.body && document.body.clientWidth) this.width = document.body.clientWidth;
		else if (window.innerWidth) this.width = window.innerWidth;
		else this.width = 0;

		if (document.documentElement && document.documentElement.clientHeight) this.height = document.documentElement.clientHeight;
		else if (document.body && document.body.clientHeight) this.height = document.body.clientHeight;
		else if (window.innerHeight) this.height = window.innerHeight;
		else this.height = 0;
		
		this.w = this.width + this.scrollX;
		this.h = this.height + this.scrollY;
		
		return this;
	},

	// browser check
	browserCheck: function()
	{
		this.ua = navigator.userAgent.toLowerCase();
		this.dom = document.getElementById ? 1 : 0;
		this.op7 = (this.dom && this.ua.indexOf('opera 7') > -1 || this.ua.indexOf('opera/7') > -1) ? 1 : 0;
		this.ie5 = (this.dom && this.ua.indexOf('msie 5') > -1) ? 1 : 0;
		this.ie6 = (this.dom && this.ua.indexOf('msie 6') > -1) ? 1 : 0;
		this.moz = (this.dom && this.ua.indexOf('mozilla') > -1 && this.ua.indexOf('gecko') > -1) ? 1 : 0;
		return this;
	}
}
// end of spToolkit

// browser check variable
var bw = spToolkit.browserCheck();