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

import java.awt.Color;

import jp.riken.brain.ni.samuraigraph.base.SGDrawingElement;
import jp.riken.brain.ni.samuraigraph.base.SGIDrawingElementConstants;
import jp.riken.brain.ni.samuraigraph.base.SGTuple2f;


/**
 * 
 */
public abstract class SGDrawingElementArrow extends SGDrawingElementLine
	implements SGIArrowConstants, SGIDrawingElementConstants
{

	/**
	 * 矢尻の長さ
	 */
	protected float mHeadSize;


	/**
	 * 矢尻の開き角度
	 */
	protected float mHeadOpenAngle;


	/**
	 * 矢尻の開き角度
	 */
	protected float mHeadCloseAngle;


	/**
	 * 
	 */
	protected float mHeadEdgeLineWidth;


	/**
	 * 
	 */
	protected Color mHeadEdgeLineColor;


	/**
	 * 
	 */
	protected int mStartHeadType;


	/**
	 * 
	 */
	protected int mEndHeadType;



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


	/**
	 * 
	 */
	public boolean setHeadSize( final float size )
	{
		this.mHeadSize = size;
		return true;
	}



	/**
	 * 
	 */
	public boolean setHeadOpenAngle( final float angle )
	{
		this.mHeadOpenAngle = angle;
		return true;
	}


	/**
	 * 
	 */
	public boolean setHeadCloseAngle( final float angle )
	{
		this.mHeadCloseAngle = angle;
		return true;
	}


	/**
	 * 
	 */
	public boolean setHeadEdgeLineWidth( final float width )
	{
		this.mHeadEdgeLineWidth = width;
		return true;
	}


	/**
	 * 
	 */
	public boolean setHeadEdgeLineColor( final Color color )
	{
		this.mHeadEdgeLineColor = color;
		return true;
	}


	/**
	 * 
	 */
	public boolean setStartHeadType( final int type )
	{
		this.mStartHeadType = type;
		return true;
	}


	/**
	 * 
	 */
	public boolean setEndHeadType( final int type )
	{
		this.mEndHeadType = type;
		return true;
	}



	/**
	 * 
	 * @return
	 */
	public float getHeadSize()
	{
		return this.mHeadSize;
	}


	/**
	 * 
	 * @return
	 */
	public float getHeadOpenAngle()
	{
		return this.mHeadOpenAngle;
	}


	/**
	 * 
	 * @return
	 */
	public float getHeadCloseAngle()
	{
		return this.mHeadCloseAngle;
	}


	/**
	 * 
	 * @return
	 */
	public float getHeadEdgeLineWidth()
	{
		return this.mHeadEdgeLineWidth;
	}


	/**
	 * 
	 * @return
	 */
	public Color getHeadEdgeLineColor()
	{
		return this.mHeadEdgeLineColor;
	}


	/**
	 * 
	 * @return
	 */
	public int getStartHeadType()
	{
		return this.mStartHeadType;
	}


	/**
	 * 
	 * @return
	 */
	public int getEndHeadType()
	{
		return this.mEndHeadType;
	}



	/**
	 * 
	 * @return
	 */
	protected double getLineAngle()
	{
		SGTuple2f start = this.getStart();
		SGTuple2f end = this.getEnd();
		
		final float tangent = (end.y-start.y)/(end.x-start.x);

		float angle = 0.0f;
		if( tangent == Double.POSITIVE_INFINITY || tangent == Double.NEGATIVE_INFINITY )
		{
			if( end.y > start.y )
			{
				angle = (float)(0.50*Math.PI);
			}
			else
			{
				angle = (float)(1.50*Math.PI);
			}
		}
		else
		{
			angle = (float)Math.atan(tangent);
		}

		return angle;
	}


	/**
	 * 
	 * @return
	 */
	public float getMagnitude()
	{
		SGTuple2f start = this.getStart();
		SGTuple2f end = this.getEnd();
		final float xDiff = end.x - start.x;
		final float yDiff = end.y - start.y;
		final float mag = (float)Math.sqrt( xDiff*xDiff + yDiff*yDiff );
		return mag;
	}


	/**
	 * 
	 */
	public boolean setProperty( final SGDrawingElement element )
	{
		if( !(element instanceof SGDrawingElementArrow) )
		{
			return false;
		}

		if( super.setProperty( element ) == false )
		{
			return false;
		}

		SGDrawingElementArrow arrow = (SGDrawingElementArrow)element;
		this.mHeadSize = arrow.getHeadSize();
		this.mHeadOpenAngle = arrow.getHeadOpenAngle();
		this.mHeadCloseAngle = arrow.getHeadCloseAngle();
		this.mHeadEdgeLineWidth = arrow.getHeadEdgeLineWidth();
		this.mHeadEdgeLineColor = arrow.getHeadEdgeLineColor();
		this.mStartHeadType = arrow.getStartHeadType();
		this.mEndHeadType = arrow.getEndHeadType();

		return true;
	}



}

