/*
 * Created on 2004/09/13
 *
 * 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.util.*;
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import jp.riken.brain.ni.samuraigraph.base.*;
import jp.riken.brain.ni.samuraigraph.data.*;
import jp.riken.brain.ni.samuraigraph.figure.*;


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


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


	/**
	 * 
	 */
	public SGDrawingElementString2D( final String str )
	{
		super( str );
	}


	/**
	 * 
	 */
	public SGDrawingElementString2D( final SGDrawingElementString element )
	{
		super( element );
	}


	/**
	 *
	 */
	public SGDrawingElementString2D(
		final String str,
		final String fontFamilyName,
		final int fontStyle,
		final float fontSize )
	{
		super( str, fontFamilyName, fontStyle, fontSize );
	}
	

	/**
	 *
	 */
	public SGDrawingElementString2D(
		final String str,
		final String fontFamilyName,
		final int fontStyle,
		final float fontSize,
		final float x,
		final float y )
	{
		super( str, fontFamilyName, fontStyle, fontSize, x, y );
	}



	/**
	 * 
	 */
	public boolean setFont( final String name, final int style, final float size )
	{
		super.setFont( name, style, size );
		this.setStringRect();
		return true;
	}


	/**
	 * 
	 */
	public boolean setString( final String str )
	{
		super.setString( str );
		this.setStringRect();
		return true;
	}


	/**
	 *
	 */
	public boolean contains( final int x, final int y )
	{
		Shape shape = this.getElementBounds();
		return shape.contains(x,y);
	}



	/**
	 * 
	 */
	public Rectangle2D getElementBounds()
	{
		Rectangle2D sRect = this.getStringRect();
		AffineTransform af = this.getAffineTransform();
		Shape sh = af.createTransformedShape( sRect );
		return sh.getBounds2D();
	}




	/**
	 * 
	 */
	protected Rectangle2D mStringRect = new Rectangle2D.Float();


	/**
	 * 
	 * @return
	 */
	protected boolean setStringRect()
	{
		if( this.mFont==null || this.mString==null )
		{
			return false;
		}
		this.mStringRect = this.mFont.getStringBounds(
			this.getString(), new FontRenderContext( null, false, false ) );
		this.mStringRect.setRect(
			0.0, 0.0, this.mStringRect.getWidth(), this.mStringRect.getHeight() );

		return true;
	}


	/**
	 * 
	 */
	public Rectangle2D getStringRect()
	{
		return this.mStringRect;
	}


	/**
	 * 
	 */
	protected float getAscent()
	{
		LineMetrics lm = this.mFont.getLineMetrics(
			this.getString(),
			new FontRenderContext( null, false, false )
		);
		return lm.getAscent();
	}



	/**
	 * この文字列のアフィン変換を取得
	 */
	protected AffineTransform getAffineTransform()
	{
		AffineTransform af = new AffineTransform();

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

		// 平行移動
		af.translate( x, y );

		// 回転
		af.rotate( - this.getAngle() );
		
		return af;		
	}



	/**
	 * 
	 */
	public boolean drawString( final Graphics2D g2d )
	{
		String str = this.getString();

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

		// set the font
		g2d.setFont( this.mFont );

		// if the string element is horizontal
		if( Math.abs(this.getAngle()) < Float.MIN_VALUE )
		{
			this.drawStringHorizontally( str, g2d );
			return true;
		}


		// create an affine transformation matrix
		AffineTransform af = this.getAffineTransform();

		// transform
		AffineTransform saveAT = g2d.getTransform();
		g2d.transform(af);
		g2d.drawString(
			str, 0.0f, this.getAscent()
		);
		g2d.setTransform(saveAT);


		return true;
	}



	/**
	 * 
	 * @return
	 */
	protected boolean drawStringHorizontally(
		final String str, final Graphics2D g2d )
	{
		g2d.drawString(
			str, this.getX(), this.getY() + this.getAscent()
		);
		return true;
	}



}
