/*
 * Created on 2004/06/15
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package jp.riken.brain.ni.samuraigraph.figure.java2d;

import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

import jp.riken.brain.ni.samuraigraph.base.SGDrawingElement;
import jp.riken.brain.ni.samuraigraph.base.SGTuple2f;
import jp.riken.brain.ni.samuraigraph.base.SGUtility;
import jp.riken.brain.ni.samuraigraph.figure.SGDrawingElementLine;
import jp.riken.brain.ni.samuraigraph.figure.SGDrawingElementString;
import jp.riken.brain.ni.samuraigraph.figure.SGSignificantDifferenceSymbol;


/**
 * @author kuromaru
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class SGSignificantDifferenceSymbol2D extends SGSignificantDifferenceSymbol
	implements SGIDrawingElementJava2D
{


	/**
	 * 
	 */
	protected SGDrawingElementString2DExtended mStringElement = new SGDrawingElementString2DExtended("*");


	/**
	 * 
	 */
	protected SGDrawingElementLine2D mHorizontalLine = new SGDrawingElementLine2D();


	/**
	 * 
	 */
	protected SGDrawingElementLine2D mPerpendicularLine1 = new SGDrawingElementLine2D();


	/**
	 * 
	 */
	protected SGDrawingElementLine2D mPerpendicularLine2 = new SGDrawingElementLine2D();


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


	/**
	 * 
	 */
	public SGSignificantDifferenceSymbol2D(
		final float x,
		final float y,
		final float w,
		final float hl,
		final float hr )
	{
		super(x,y,w,hl,hr);
	}


	/**
	 * 
	 */
	public void dispose()
	{
		super.dispose();
		this.mHorizontalLine.dispose();
		this.mPerpendicularLine1.dispose();
		this.mPerpendicularLine2.dispose();
		this.mStringElement.dispose();
		this.mHorizontalLine = null;
		this.mPerpendicularLine1 = null;
		this.mPerpendicularLine2 = null;
		this.mStringElement = null;
	}


	/**
	 * 
	 */
	protected boolean createDrawingElement()
	{
//System.out.println("<< createDrawingElement >>");

		final float mag = this.getMagnification();
		final float width = mag*this.getWidth();
		final float h1 = mag*this.getPerpendicularHeight1();
		final float h2 = mag*this.getPerpendicularHeight2();
		final float space = mag*this.getSpace();

		final SGTuple2f leftTop = new SGTuple2f(
			this.getX(),
			this.getY() );

		final SGTuple2f rightTop = new SGTuple2f(
			this.getX() + width,
			this.getY() );

		final SGTuple2f leftBottom = new SGTuple2f(
			this.getX(),
			this.getY() + h1 );

		final SGTuple2f rightBottom = new SGTuple2f(
			this.getX() + width,
			this.getY() + h2 );

//System.out.println(this.getX()+"  "+this.getY());

		this.mHorizontalLine.setTermPoints( leftTop, rightTop );
		this.mPerpendicularLine1.setTermPoints( leftTop, leftBottom );
		this.mPerpendicularLine2.setTermPoints( rightTop, rightBottom );

		final Rectangle2D rect = this.mStringElement.getElementBounds();
		final float strLeading = this.mStringElement.getLeading() * 2.0f;
		final float rectWidth = (float)rect.getWidth();
		final float rectHeight = (float)rect.getHeight();


		final float strX = this.getX() + width/2.0f - (rectWidth/2.0f);
		float strY;
		if( !this.isFlippingVertical() )
		{
			strY = this.getY() - space - rectHeight - strLeading;
		}
		else
		{
			strY = this.getY() + space + strLeading;
		}

		this.mStringElement.setLocation( strX, strY );


		return true;

	}



	/**
	 * 
	 */
	public ArrayList getDrawingElementList()
	{
		ArrayList list = new ArrayList();
		list.add(this.mHorizontalLine);
		list.add(this.mPerpendicularLine1);
		list.add(this.mPerpendicularLine2);
		return list;
	}



	
	/**
	 * 
	 */
	public Point2D getJoint1()
	{
		Point2D pos = new Point2D.Float(
			this.getX1(), this.getY()
		);
		return pos;
	}



	/**
	 * 
	 */
	public Point2D getJoint2()
	{
		Point2D pos = new Point2D.Float(
			this.getX2(), this.getY()
		);
		return pos;
	}


	/**
	 * 
	 */
	public Point2D getLeftJoint()
	{
		final Point2D pos;
		if( !this.isFlippingHorizontal() )
		{
			pos = this.getJoint1();
		}
		else
		{
			pos = this.getJoint2();
		}
		return pos;
	}


	/**
	 * 
	 */
	public Point2D getLeftTerm()
	{
		final Point2D pos = this.getLeftJoint();
		pos.setLocation(
			pos.getX(),
			pos.getY() + this.getMagnification()*this.getLeftHeight()
		);
		return pos;
	}



	/**
	 * 
	 */
	public Point2D getRightJoint()
	{
		final Point2D pos;
		if( !this.isFlippingHorizontal() )
		{
			pos = this.getJoint2();
		}
		else
		{
			pos = this.getJoint1();
		}
		return pos;
	}



	/**
	 * 
	 */
	public Point2D getRightTerm()
	{
		final Point2D pos = this.getRightJoint();
		pos.setLocation(
			pos.getX(),
			pos.getY() + this.getMagnification()*this.getRightHeight()
		);
		return pos;
	}



	/**
	 * 
	 * @return
	 */
	public Point2D getHorizontalMiddle()
	{
		final Point2D pos = new Point2D.Float(
			this.getX1() + this.getMagnification()*this.getWidth()/2.0f,
			this.getY()
		);
		return pos;
	}



	/**
	 * 
	 * @return
	 */
	public Point2D getLeftMiddle()
	{
		final Point2D pos = new Point2D.Float();
		final Point2D joint = this.getLeftJoint();
		final Point2D term = this.getLeftTerm();
		pos.setLocation(
			( joint.getX() + term.getX() )/2.0,
			( joint.getY() + term.getY() )/2.0
		);
		return pos;
	}



	/**
	 * 
	 * @return
	 */
	public Point2D getRightMiddle()
	{
		final Point2D pos = new Point2D.Float();
		final Point2D joint = this.getRightJoint();
		final Point2D term = this.getRightTerm();
		pos.setLocation(
			( joint.getX() + term.getX() )/2.0,
			( joint.getY() + term.getY() )/2.0
		);
		return pos;
	}



	/**
	 * 
	 */
	public SGDrawingElementString getStringElement()
	{
		return this.mStringElement;
	}


	/**
	 * 
	 */
	public boolean setMagnification( final float mag )
	{
		super.setMagnification(mag);

		ArrayList dList = this.getDrawingElementList();
		for( int ii=0; ii<dList.size(); ii++ )
		{
			SGDrawingElement el = (SGDrawingElement)dList.get(ii);
			el.setMagnification(mag);
		}

		this.mStringElement.setMagnification(mag);

		return true;
	}


	/**
	 * 
	 */
	public boolean setLineWidth( final float width )
	{
		super.setLineWidth( width );

		ArrayList dList = this.getDrawingElementList();
		for( int ii=0; ii<dList.size(); ii++ )
		{
			SGDrawingElementLine el = (SGDrawingElementLine)dList.get(ii);
			el.setLineWidth(width);
		}

		return true;
	}


	/**
	 * 
	 */
	public boolean contains( final int x, final int y )
	{
		if( this.isLineVisible() )
		{
			if( this.mHorizontalLine.contains(x,y) )
			{
				return true;
			}

			if( this.mPerpendicularLine1.contains(x,y) )
			{
				return true;
			}

			if( this.mPerpendicularLine2.contains(x,y) )
			{
				return true;
			}
		}

		if( this.mStringElement.contains(x,y) )
		{
			return true;
		}

		return false;
	}


	/**
	 * 
	 */
	public ArrayList getShapeList()
	{
		ArrayList dList = this.getDrawingElementList();
		ArrayList list = new ArrayList();
		for( int ii=0; ii<dList.size(); ii++ )
		{
			SGDrawingElementLine2D el = (SGDrawingElementLine2D)dList.get(ii);
			list.add( el.getShape() );
		}

		return list;
	}



	/**
	 * 
	 */
	public Shape getConnectedShape()
	{
		GeneralPath gp = new GeneralPath();
		gp.append( this.mPerpendicularLine1.getShape(), true );
		gp.append( this.mHorizontalLine.getShape(), true );
		gp.append( this.mPerpendicularLine2.getShape(), true );

		return gp;
	}



	/**
	 * 
	 */
	public boolean zoom( final float mag )
	{
		super.zoom( mag );
		this.createDrawingElement();
		return true;
	}



	/**
	 * 
	 * @return
	 */
	public Rectangle2D getElementBounds()
	{
		ArrayList rectList = new ArrayList();
		rectList.add( this.getLineBounds() );
		rectList.add( this.getStringBounds() );
		Rectangle2D rect = SGUtility.createUnion(rectList);

		return rect;
	}


	/**
	 * 
	 */
	public Rectangle2D getLineBounds()
	{
		ArrayList rectList = new ArrayList();
		ArrayList dList = this.getDrawingElementList();
		for( int ii=0; ii<dList.size(); ii++ )
		{
			SGDrawingElementLine2D el = (SGDrawingElementLine2D)dList.get(ii);
			rectList.add( el.getShape().getBounds2D() );
		}

		Rectangle2D rect = SGUtility.createUnion(rectList);

		return rect;
	}


	/**
	 * 
	 */
	public Rectangle2D getStringBounds()
	{
		return this.mStringElement.getElementBounds();
	}



	/**
	 * 
	 * @param g2d
	 */
	public void paintElement( final Graphics2D g2d )
	{
		g2d.setPaint( this.getColor() );

		if( this.isLineVisible() )
		{
			final float lineWidth = this.mMagnification*this.getLineWidth();
			g2d.setStroke(
				new BasicStroke
				(
					lineWidth,
					BasicStroke.CAP_BUTT,
					BasicStroke.JOIN_MITER
				)
			);

			Shape sh = this.getConnectedShape();
			g2d.draw(sh);
		}


		// string
		SGDrawingElementString2DExtended sElement
			= (SGDrawingElementString2DExtended)this.getStringElement();
		sElement.paintElement(g2d);
		
	}



	/**
	 * 
	 */
	public void paint( final Graphics2D g2d, final Rectangle2D clipRect )
	{
		this.paintElement(g2d);
	}

}

