/* 
	CurveFlow: Arranges items in a cool clickable curve
	Copyright (C) 2008 Best Foot Forward

	You must include baseflow.js before including this file.
*/

CurveFlow = Class.create (BaseFlow,
{
	initialize : function ($super, elem, opts)
	{
		$super (elem, opts);

		var linearopts = {
		}
		Object.extend (linearopts, opts);

		for (var i = 0; i < this.stack.length; ++i) {
			var item = this.stack [i];
			/* Set item "time" to 0 */
			item.t = 0;
		}
	},

	position : function ($super, anim)
	{
		$super(anim);

		/* CurveFlow limits animation ticks to 100 */
		if (anim.ticks > 25)
			return false;

		return true;
	},

	positionItem : function (anim, index, pos)
	{
		var item = this.stack [index];

		/* Calculate target position in "time" [0, 1]
		   based on offset from focused item */
		var offset_norm = (index - anim.target) / this.stack.length; /* In range [-0.5, 0.5] */
		var target_t = offset_norm + 0.5; /* In range [0, 1] */

		/* Move our actual position towards the target */
		item.t += (target_t - item.t) / 5;

		/* Convert our "time" variable to a position using the map provided */
		this.map (item.t, pos);
		/* Move pos so that it is at the center of the item */
		pos.x -= item.width / 2;
	},

	/* Maps a float around [0, 1] to pos (but not necessarily inside [0, 1] */
	map : function (t, pos)
	{
		/* First clamp t to [0, 1] */
		t = Math.min (Math.max (t, 0), 1);

		/* Push t to the edges */
		t = 3 * t * t - 2 * t * t * t;

		pos.x = (t * this.width);
		pos.y = Math.cos ((t - 0.5) * Math.PI) * 70;

		/* Use map so that z (0) = z (1) = 0; z (0.5) = 100 */
		pos.z = 100 - Math.round (Math.abs (t - 0.5) * 200);
	}	
});

