// dhtml library animation extensions by rod.o2theory.com | soloplay@msn.com
// bezier functions by 13thparallel.org, modified by youngpup.net then modified by me.
// keep these three lines and you're free to use this code

// last updated: 07.04.2003

// bezier math (calculates a given position along a bezier curve specified by 2, 3 or 4 control points)
var bezier = {
	// bezier functions
	b1: function(t) { return (t * t * t); },
	b2: function(t) { return (3 * t * t * (1 - t)); },
	b3: function(t) { return (3 * t * (1 - t) * (1 - t)); },
	b4: function(t) { return ((1 - t) * (1 - t) * (1 - t)); },
	// coordinate constructor
	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
	get: function(percent, c1, c2, c3, c4)
	{
		var pos = new bezier.coord();
		pos.x = Math.round(c2.x * bezier.b1(percent) + c4.x * bezier.b2(percent) + c3.x * bezier.b3(percent) + c1.x * bezier.b4(percent));
		pos.y = Math.round(c2.y * bezier.b1(percent) + c4.y * bezier.b2(percent) + c3.y * bezier.b3(percent) + c1.y * bezier.b4(percent));
		return pos;
	}
}

// animation timers
lib.makeObject.prototype.resizeTimer = 0;
lib.makeObject.prototype.slideTimer = 0;
lib.makeObject.prototype.fadeTimer = 0;

// 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		= function to execute when animation has finished
//			example: myObj.slideTo(x, y, 1000, 0, new Function('myFunc(' + arguments + ')'));
lib.makeObject.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('lib.registry[' + this.i + '].slide(' + this.x + ', ' + this.y + ', ' + x + ', ' + y + ', ' + acc + ', ' + startTime + ', ' + endTime + ', ' + fn + ')', 10);
}

lib.makeObject.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 && typeof fn == 'function') fn();
	}
	else
	{
		var percent = (currentTime - startTime) / (endTime - startTime);
		var c1 = new bezier.coord(startX, startY);
		var c2 = new bezier.coord(endX, endY);
		var c3 = new bezier.coord(c1.x + ((1 + -acc) * (c2.x - c1.x) / 3), c1.y + ((1 + -acc) * (c2.y - c1.y) / 3));
		var c4 = new bezier.coord(c1.x + ((2 + -acc) * (c2.x - c1.x) / 3), c1.y + ((2 + -acc) * (c2.y - c1.y) / 3));
		var pos = bezier.get(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
lib.makeObject.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('lib.registry[' + this.i + '].resize(' + this.w + ', ' + this.h + ', ' + w + ', ' + h + ', ' + acc + ', ' + startTime + ', ' + endTime + ', ' + fn + ')', 10);
}

lib.makeObject.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 && typeof fn == 'function') fn();
	}
	else
	{
		var percent = (currentTime - startTime) / (endTime - startTime);
		var c1 = new bezier.coord(startW, startH);
		var c2 = new bezier.coord(endW, endH);
		var c3 = new bezier.coord(c1.x + ((1 + -acc) * (c2.x - c1.x) / 3), c1.y + ((1 + -acc) * (c2.y - c1.y) / 3));
		var c4 = new bezier.coord(c1.x + ((2 + -acc) * (c2.x - c1.x) / 3), c1.y + ((2 + -acc) * (c2.y - c1.y) / 3));
		var pos = bezier.get(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
lib.makeObject.prototype.fadeTo = function(o, duration, fn)
{
	clearTimeout(this.fadeTimer);
	if (!fn) fn = 0;
	var startTime = new Date().valueOf();
	var endTime = startTime + duration;
	this.fadeTimer = setInterval('lib.registry[' + this.i + '].fade(' + this.o + ', ' + o + ', ' + startTime + ', ' + endTime + ', ' + fn + ')', 10);
}

lib.makeObject.prototype.fade = function(startO, endO, startTime, endTime, fn)
{
	var currentTime = new Date().valueOf();
	if (currentTime >= endTime)
	{
		clearInterval(this.fadeTimer);
		this.fadeTimer = 0;
		this.setOpacity(endO);
		if (fn && typeof fn == 'function') fn();
	}
	else
	{
		var percent = (currentTime - startTime) / (endTime - startTime);
		this.setOpacity((percent * (endO - startO)) + startO);
	}
}