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

import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import jp.riken.brain.ni.samuraigraph.base.SGTuple2f;
import jp.riken.brain.ni.samuraigraph.figure.SGDrawingElementLine;


/**
 *
 */

public class SGDrawingElementLine2D extends SGDrawingElementLine
	implements SGIDrawingElementJava2D
{



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


	/**
	 *
	 */
	public SGDrawingElementLine2D(
		final SGTuple2f start,
		final SGTuple2f end )
	{
		super( start, end );
	}



	/**
	 *
	 */
	public SGDrawingElementLine2D(
		final float x1, final float y1,
		final float x2, final float y2 )
	{
		super( x1, y1, x2, y2 );
	}



	/**
	 * The minimum line width used in "contains" method.
	 */
	public static final float MINIMUM_LINE_WIDTH = 2.0f;


	/**
	 *
	 */
	public boolean contains( final int x, final int y )
	{
		float lw = this.mLineWidth*this.mMagnification;
		if( lw<MINIMUM_LINE_WIDTH )
		{
			lw = MINIMUM_LINE_WIDTH;
		}
		final double lensq = Line2D.ptSegDistSq(
			this.mStartPoint.x, this.mStartPoint.y,
			this.mEndPoint.x, this.mEndPoint.y,
			x, y );
		return ( lensq < lw*lw );
	}

	
	
	
	/**
	 * 
	 */
	public boolean paintElement( final Graphics2D g2d )
	{

		if( g2d==null )
		{
			return false;
		}

		g2d.setPaint(this.getColor(0));

		final float width = this.mMagnification*this.mLineWidth;

		switch( this.mLineType )
		{
			case SGDrawingElementLine2D.LINE_TYPE_SOLID :
			{
				g2d.setStroke
				(
					new BasicStroke
					(
						width,
						this.mCap,
						this.mJoin
					)
				);
				break;
			}
					
			case SGDrawingElementLine2D.LINE_TYPE_BROKEN :
			{
				final float[] dash = {2.0f*width,width};
				g2d.setStroke
				(
					new BasicStroke
					(
						width,
						this.mCap,
						this.mJoin,
						this.mMiterLimit,
						dash,
						this.mDashPhase
					)
				);
				break;
			}

			case SGDrawingElementLine2D.LINE_TYPE_DOT :
			{
				final float[] dash = {width};
				g2d.setStroke
				(
					new BasicStroke
					(
						width,
						this.mCap,
						this.mJoin,
						this.mMiterLimit,
						dash,
						this.mDashPhase
					)
				);
				break;
			}
					
			default :
			{
						
			}

		}
		
		
		g2d.draw( this.getShape() );

		return true;
	}



	/**
	 * 
	 */
	public Rectangle2D getElementBounds()
	{
		SGTuple2f start = this.getStart();
		SGTuple2f end = this.getEnd();
		final float x = ( start.x < end.x ? start.x : end.x );
		final float y = ( start.y < end.y ? start.y : end.y );
		final float w = Math.abs( start.x - end.x );
		final float h = Math.abs( start.y - end.y );
		Rectangle2D rect = new Rectangle2D.Float(x,y,w,h);
		return rect;
	}



	/**
	 * 
	 */
	public Shape getShape()
	{
		Line2D line = new Line2D.Float(
			this.getStart().x, this.getStart().y,
			this.getEnd().x, this.getEnd().y );
		return line;
	}



	/**
	 * 
	 * @param line
	 * @return
	 */
	public static Line2D getLine( final SGDrawingElementLine line )
	{
		SGTuple2f start = line.getStart();
		SGTuple2f end = line.getEnd();
		Line2D sh = new Line2D.Float( start.x, start.y, end.x, end.y );
		return sh;
	}



	/**
	 * 
	 */
	public ArrayList getShapeList()
	{
		ArrayList list = new ArrayList();
		list.add( this.getShape() );
		return list;
	}



	/**
	 * 
	 */
	public Object copy()
	{
		SGDrawingElementLine2D el = new SGDrawingElementLine2D();
		return el;
	}


	protected boolean setForCopy( SGDrawingElementLine2D el )
	{
		el.setProperties( this.getProperties() );
		SGTuple2f start = this.getStart();
		SGTuple2f end = this.getEnd();
		el.setTermPoints( start.x, start.y, end.x, end.y );
		el.setMagnification( this.mMagnification );
		return true;
	}


}
