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

import java.awt.Color;
import jp.riken.brain.ni.samuraigraph.base.*;
import jp.riken.brain.ni.samuraigraph.data.*;


/**
 * 
 */
public abstract class SGDrawingElementArrow extends SGDrawingElement
{


	/**
	 *
	 */
	protected SGTuple2f mStart = null;


	/**
	 *
	 */
	protected SGTuple2f mEnd = null;




	/**
	 *
	 */
	protected int mLineType = SGDrawingElementLine.LINE_TYPE_SOLID;


	/**
	 * 線幅
	 */
	protected float mLineWidth = 1.0f;


	/**
	 * 矢尻の長さ
	 */
	protected float mHeadSize = 15.0f;


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


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


	/**
	 * 
	 */
	protected float mHeadEdgeLineWidth = 1.0f;


	/**
	 * 
	 */
	protected Color mHeadEdgeLineColor = Color.BLACK;


	/**
	 * 
	 */
	protected int mStartHeadType = -1;


	/**
	 * 
	 */
	protected int mEndHeadType = -1;



	/**
	 * 
	 */
	public static final int SYMBOL_ARROW_HEAD = 10;


	/**
	 * 
	 */
//	public static final int NO_HEAD = -1;



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


//this.setEndHeadType( SGDrawingElementSymbol.SYMBOL_TRIANGLE );
//this.setStartHeadType( SGDrawingElementSymbol.SYMBOL_CIRCLE );

//mEndHead = this.createHead( SYMBOL_ARROW_HEAD );
//mStartHead = this.createHead( SGDrawingElementSymbol.SYMBOL_TRIANGLE );

	}


	/**
	 *
	 */
	public boolean setTermPoints( final SGTuple2f start, final SGTuple2f end )
	{
		mStart = new SGTuple2f( start.x, start.y );
		mEnd = new SGTuple2f( end.x, end.y );

		return true;
	}


	/**
	 * 
	 */
	public boolean setLineType( final int type )
	{
		mLineType = type;
		return true;
	}


	/**
	 * 
	 */
	public boolean setLineWidth( final float width )
	{
		mLineWidth = width;
		return true;
	}


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



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


	/**
	 * 
	 */
	public boolean setHeadCloseAngle( final float angle )
	{
		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 int getLineType()
	{
		return mLineType;
	}


	/**
	 * 
	 * @return
	 */
	public float getLineWidth()
	{
		return mLineWidth;
	}


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


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


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


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


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


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


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


	/**
	 * 
	 */
	public SGTuple2f getStart()
	{
		return new SGTuple2f( mStart.x, mStart.y );
	}


	/**
	 * 
	 */
	public SGTuple2f getEnd()
	{
		return new SGTuple2f( mEnd.x, mEnd.y );
	}


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

//System.out.println("tangent=="+tangent);

		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);
		}

//System.out.println("angle=="+angle);
//System.out.println();

		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 );

/*
System.out.println("mStartRatio:"+"  "+mStartRatio.x+"  "+mStartRatio.y);
System.out.println("mEndRatio:"+"  "+mEndRatio.x+"  "+mEndRatio.y);
System.out.println("start:"+start.x+"  "+start.y);
System.out.println("end:"+"  "+end.x+"  "+end.y);
System.out.println("mag=="+mag);
System.out.println();
*/

		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.mLineType = arrow.getLineType();
		this.mLineWidth = arrow.getLineWidth();
		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;
	}



}

