$.fn.bumpUp = function(timeFactor, timings)
{
	for (i in timings)
	{
		var t = timings[i];

		// x change
		if (t.x == null)
			t.x = 0;
		if (t.x < 0)
			t.xd = '-=' + (-t.x);
		else
			t.xd = '+=' + t.x;

		// y change
		if (t.y == null)
			t.y = 0;
		if (t.y < 0)
			t.yd = '-=' + (-t.y);
		else
			t.yd = '+=' + t.y;

		// rotation change
		if (t.r == null)
			t.r = 0;
		if (t.r < 0)
			t.rd = '-=' + (-t.r);
		else
			t.rd = '+=' + t.r;

		// time
		if (t.t == null)
			t.t = (Math.sqrt(Math.abs(t.y) + Math.abs(t.r * 2.5))) * timeFactor;

		// pause
		if (t.p == null)
			t.p = 0;
	}

	return this.each(function()
	{
		for (i in timings)
		{
			var t = timings[i];
			$(this)
				.animate(
				{
					left: t.xd,
					top: t.yd,
					rotation: t.rd
				}, t.t, 'easeOutBounce')
				.animate({ dummy: 0 }, t.p);
		}
	});
};

$.fn.splitAndBumpUp = function(fadeInTime, timeFactor, perWordDelay, params)
{
	var words = $.trim($(this).text()).split(' ');
	var html = '';
	for (var i = 0; i < words.length; i++)
		html += '<span style="position: absolute; left: ' + params[i].x + 'px; top: ' + params[i].y + 'px;">' + words[i] + '</span>';
	$(this)
		.html(html)
		.fadeIn(fadeInTime, function()
		{
			var $spans = $(this).find('span');
			for (var i = 0; i < words.length; i++)
				$($spans[i])
					.animate({ dummy: 0 }, i * perWordDelay)
					.bumpUp(timeFactor, params[i].a);
		});
};

$.fn.splitAndTell = function()
{
	var words = $(this).text().split(' ');
	var html = '';
	for (var i = 0; i < words.length; i++)
		html += '<span>' + words[i] + ' </span>';
	$(this).html(html);
	var tell = '';
	$(this).find('span').each(function()
	{
		tell += $(this).offset().left + ', ' + $(this).offset().top + '\n';
	});
	alert(tell);
};
