/*
 * jQuery css bezier animation support -- Jonah Fox
 * version 0.0.1
 * Released under the MIT license.
 */
/*
  var path = $.path.bezier({
    start: {x:10, y:10, angle: 20, length: 0.3},
    end:   {x:20, y:30, angle: -20, length: 0.2}
  })
  $("myobj").animate({path: path}, duration)

*/

;(function($){

	$.path = {};
	
	var V = {
				rotate:	function(p, degrees) {
							var radians = degrees * 3.141592654 / 180;
							var c = Math.cos(radians), s = Math.sin(radians);
							return [c*p[0] - s*p[1], s*p[0] + c*p[1] ];
						},
				scale:	function(p, n) {
							return [n*p[0], n*p[1]];
						},
				add:	function(a, b) {
							return [a[0]+b[0], a[1]+b[1]];
						},
				minus:	function(a, b) {
							return [a[0]-b[0], a[1]-b[1]];
						}
			};
   
	$.path.bezier = function( params ) { 
		params.start = $.extend({angle: 0, length: 0.3333}, params.start );
		params.end   = $.extend({angle: 0, length: 0.3333}, params.end );
	
		this.p1 = [params.start.x, params.start.y];
		this.p4 = [params.end.x, params.end.y];
	     
		var v14 = V.minus(this.p4, this.p1);
		var v12 = V.scale(v14, params.start.length);
		v12 = V.rotate(v12, params.start.angle);
		this.p2 = V.add(this.p1, v12);
	      
		var v41 = V.scale(v14, -1);
		var v43 = V.scale(v41, params.end.length);
		v43 = V.rotate(v43, params.end.angle);
		this.p3 = V.add(this.p4, v43);
	
		this.f1 = function(t) { return (t*t*t); };
		this.f2 = function(t) { return (3*t*t*(1-t)); };
		this.f3 = function(t) { return (3*t*(1-t)*(1-t)); };
		this.f4 = function(t) { return ((1-t)*(1-t)*(1-t)); };
	
	     /* p from 0 to 1 */
		this.css = function(p) {
			var f1 = this.f1(p), f2 = this.f2(p), f3 = this.f3(p), f4=this.f4(p);
			var x = this.p1[0]*f1 + this.p2[0]*f2 +this.p3[0]*f3 + this.p4[0]*f4;
			var y = this.p1[1]*f1 + this.p2[1]*f2 +this.p3[1]*f3 + this.p4[1]*f4;
			return {top: y + "px", left: x + "px"};
		};
	};

	$.path.arc = function(params) {
		for(var i in params){
			this[i] = params[i];
		}
		this.dir = this.dir || 1;

		while(this.start > this.end && this.dir > 0){
			this.start -= 360;
		}

		while(this.start < this.end && this.dir < 0){
			this.start += 360;
		}

		this.css = function(p) {
			var a = this.start * (p ) + this.end * (1-(p ));
			a = a * 3.1415927 / 180; // to radians

			var x = Math.sin(a) * this.radius + this.center[0];
			var y = Math.cos(a) * this.radius + this.center[1];
			return {top: y + "px", left: x + "px"};
		};

	};
	
	$.path.ellipse	=	function(params){
		for(var i in params){
			this[i] = params[i];
		}
		
		this.css = function(p) {
			var a = this.start * (p ) + this.end * (1-(p ));
			a = a * 3.1415927 / 180; // to radians

			
			var x = ( Math.sin(a) * this.radius * this.axis ) + this.center[0];
			var y = ( Math.cos(a) * this.radius ) + this.center[1];
			return { top: y + "px" , left: x + "px" };
		};
	};
   
	$.fx.step.path = function(fx){
		var css = fx.end.css(1 - fx.pos);
		for(var i in css){ 
			fx.elem.style[i] = css[i];
		}
	};
})(jQuery);
