
package jp.riken.brain.ni.samuraigraph.figure.java2d;

import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

import jp.riken.brain.ni.samuraigraph.figure.SGDrawingElementSymbol;

/**
 * An inner class for arrows.
 *
 */
public class SGArrow extends SGDrawingElementArrow2D
{

	/**
	 * 
	 *
	 */
	public SGArrow()
	{
		super();
	}

	protected SGDrawingElementSymbol getHeadInstance()
	{
		return new ArrowHead();
	}


	/**
	 * An inner class for arrow head.
	 */
	private class ArrowHead extends SGDrawingElementSymbol2D
	{

		/**
		 * 
		 */
		ArrowHead()
		{
			super();
		}


		/**
		 * 
		 */
		public Shape getShape()
		{
			if( this.getType() == SGDrawingElementSymbol.SYMBOL_TYPE_VOID )
			{
				return null;
			}

			final float x = this.getX();
			final float y = this.getY();

			final float mag = this.getMagnification();
			final float headSize = mag*this.getSize();

			final float open = SGArrow.this.getHeadOpenAngle();
			final float close = SGArrow.this.getHeadCloseAngle();
			final float tanOpen = (float)Math.tan(open);
			final float tanClose = (float)Math.tan(close);

			Point2D[] pointArray = new Point2D[4];
			pointArray[0] = new Point2D.Float(
				x,
				y
			);
			pointArray[1] = new Point2D.Float(
				x - headSize,
				y + headSize*tanOpen
			);
			pointArray[2] = new Point2D.Float(
				x - headSize*( 1.0f - tanOpen/tanClose ),
				y
			);
			pointArray[3] = new Point2D.Float(
				x - headSize,
				y - headSize*tanOpen
			);

			Shape[] pathArray = new Line2D[pointArray.length];
			for( int ii=0; ii<pathArray.length; ii++ )
			{
				pathArray[ii] = new Line2D.Float(
					pointArray[ii], pointArray[(ii+1)%pointArray.length] );
			}

			GeneralPath gp = new GeneralPath();
			for( int ii=0; ii<pathArray.length; ii++ )
			{
				gp.append( pathArray[ii], true );
			}

			AffineTransform af = this.getAffineTransform();

			Shape shape = af.createTransformedShape( gp );

//System.out.println( this.getAngle()/Math.PI );
//System.out.println( gp.getBounds() );
//System.out.println( "getShape:" + shape.getBounds() );
//System.out.println();

			return shape;
		}

	}


}


