package org.papervision3d.objects.special.commands {
	import flash.display.Graphics;
	
	import org.papervision3d.core.geom.renderables.Vertex3D;
	import org.papervision3d.core.geom.renderables.Vertex3DInstance;
	import org.papervision3d.core.render.data.RenderSessionData;
	import org.papervision3d.materials.special.VectorShapeMaterial;
	import org.papervision3d.objects.special.commands.IVectorShape;	

	/**
	 * @author Mark Barcinski
	 */
	public class CurveTo implements IVectorShape{
		public var control : Vertex3D;
		public var anchor : Vertex3D;
		
		public function CurveTo(control:Vertex3D , anchor:Vertex3D)
		{
			this.control = control;
			this.anchor = anchor;	
		}
		
		public function draw(graphics : Graphics, prevDrawn : Boolean) : Boolean {
			if(control.vertex3DInstance.visible && anchor.vertex3DInstance.visible){
				if(prevDrawn)
					graphics.curveTo(control.vertex3DInstance.x , control.vertex3DInstance.y , 
									anchor.vertex3DInstance.x , anchor.vertex3DInstance.y);
				else
					graphics.moveTo(control.vertex3DInstance.x , control.vertex3DInstance.y);
					
				return true;
			}
			
			return false;
		}
		
		static private var halfPI :Number = Math.PI/2;
		public function drawScaledStroke( prevVertex : Vertex3D, graphics : Graphics, renderSessionData : RenderSessionData , material : VectorShapeMaterial) : void {
			if(!control.vertex3DInstance.visible || !anchor.vertex3DInstance.visible)return;
			
			if(!prevVertex.vertex3DInstance.visible){
				graphics.moveTo(control.vertex3DInstance.x , control.vertex3DInstance.y);
				return;
			}
			
			var focus    :Number = renderSessionData.camera.focus;
			var fz       :Number = focus * renderSessionData.camera.zoom;
			
			
			var v0Scale  :Number = (fz / (focus + anchor.vertex3DInstance.z)) * material.lineThickness;
			var v1Scale  :Number = (fz / (focus + prevVertex.vertex3DInstance.z)) * material.lineThickness;
			var cScale  :Number = (fz / (focus + control.vertex3DInstance.z)) * material.lineThickness;
			
			
			var x0:Number = anchor.vertex3DInstance.x;
			var y0:Number = anchor.vertex3DInstance.y;
			
			var x1:Number = anchor.vertex3DInstance.x;
			var y1:Number = anchor.vertex3DInstance.y;
			
			var x2:Number = prevVertex.vertex3DInstance.x;
			var y2:Number = prevVertex.vertex3DInstance.y;
			
			var x3:Number = prevVertex.vertex3DInstance.x;
			var y3:Number = prevVertex.vertex3DInstance.y;
			
			var cx0:Number = control.vertex3DInstance.x;
			var cy0:Number = control.vertex3DInstance.y;
			
			var cx1:Number = cx0;
			var cy1:Number = cy0;
		
			var rot:Number = Math.atan2( x2 - x1 , y2 - y1 );	
			
			
			var tempSin:Number = Math.sin(rot - halfPI);
			var tempCos:Number = Math.cos(rot - halfPI);
			
			x0 -= tempSin * v0Scale;
			y0 -= tempCos * v0Scale;
			
			x1 += tempSin * v0Scale;
			y1 += tempCos * v0Scale;
			
			x2 += tempSin * v1Scale;
			y2 += tempCos * v1Scale;
			
			x3 -= tempSin * v1Scale;
			y3 -= tempCos * v1Scale;
			
			
			cx0 -= tempSin * cScale;
			cy0 -= tempCos * cScale;
			
			cx1 += tempSin * cScale;
			cy1 += tempCos * cScale;
			
			
			
			graphics.lineStyle();
			graphics.beginFill(material.lineColor, material.lineAlpha);
			graphics.moveTo( x0, y0 );	
			graphics.curveTo(anchor.vertex3DInstance.x - (Math.sin(rot) * v0Scale), anchor.vertex3DInstance.y - (Math.cos(rot) * v0Scale), x1, y1);
			//graphics.lineTo( x2, y2 );
			
			graphics.curveTo(cx1 , cy1 , x2, y2);
			
			graphics.curveTo(prevVertex.vertex3DInstance.x + (Math.sin(rot) * v1Scale), prevVertex.vertex3DInstance.y + (Math.cos(rot) * v1Scale), x3, y3);
//			graphics.lineTo( x0, y0 );
			
			graphics.curveTo(cx0 , cy0, x0, y0);

			graphics.endFill();
		}
	}
}
