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

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.List;
import jp.riken.brain.ni.samuraigraph.base.SGDrawingElement;
import jp.riken.brain.ni.samuraigraph.base.SGIConstants;
import jp.riken.brain.ni.samuraigraph.base.SGProperties;
import jp.riken.brain.ni.samuraigraph.base.SGTuple2f;
import jp.riken.brain.ni.samuraigraph.base.SGUtilityText;
import jp.riken.brain.ni.samuraigraph.figure.SGDrawingElementString;
import jp.riken.brain.ni.samuraigraph.figure.SGIStringConstants;
import org.w3c.dom.Element;


public abstract class SGElementGroupString extends SGElementGroupSXY
	implements SGIStringConstants, SGIElementGroupConstants
{

	/**
	 * 
	 */
	protected String mFontName;


	/**
	 *
	 */
	protected float mFontSize;


	/**
	 *
	 */
	protected int mFontStyle;


	/**
	 * 
	 */
	protected float mAngle;


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



	/**
	 * 
	 */
	public void dispose()
	{
		super.dispose();

		this.mFontName = null;
	}




	/**
	 * 
	 * @param name
	 * @param style
	 * @param size
	 * @return
	 */
	public boolean setFont( final String name, final int style, final float size )
	{
		this.mFontName = name;
		this.mFontStyle = style;
		this.mFontSize = size;
		if( this.mDrawingElementArray!=null )
		{
			for( int ii=0; ii<this.mDrawingElementArray.length; ii++ )
			{
				SGDrawingElementString el
					= (SGDrawingElementString)this.mDrawingElementArray[ii];
				el.setFont( name, style, size );
			}
		}

		return true;
	}


	/**
	 * 
	 * @param name
	 * @return
	 */
	public boolean setFontName( final String name )
	{
		this.mFontName = name;
		if( this.mDrawingElementArray!=null )
		{
			for( int ii=0; ii<this.mDrawingElementArray.length; ii++ )
			{
				SGDrawingElementString el
					= (SGDrawingElementString)this.mDrawingElementArray[ii];
				el.setFontName(name);
			}
		}

		return true;
	}


	/**
	 * 
	 * @param size
	 * @return
	 */
	public boolean setFontSize( final float size )
	{
		this.mFontSize = size;
		if( this.mDrawingElementArray!=null )
		{
			for( int ii=0; ii<this.mDrawingElementArray.length; ii++ )
			{
				SGDrawingElementString el
					= (SGDrawingElementString)this.mDrawingElementArray[ii];
				el.setFontSize(size);
			}
		}
		return true;
	}


	/**
	 * 
	 * @param size
	 * @return
	 */
	public boolean setFontSize( final float size, final String unit )
	{
		final double s = SGUtilityText.convertToPoint( size, unit );
		if( this.setFontSize( (float)s ) == false )
		{
			return false;
		}

		return true;
	}


	/**
	 * 
	 * @param style
	 * @return
	 */
	public boolean setFontStyle( final int style )
	{
		this.mFontStyle = style;
		if( this.mDrawingElementArray!=null )
		{
			for( int ii=0; ii<this.mDrawingElementArray.length; ii++ )
			{
				SGDrawingElementString el
					= (SGDrawingElementString)this.mDrawingElementArray[ii];
				el.setFontStyle(style);
			}
		}
		return true;
	}


	/**
	 * 
	 * @param value
	 * @return
	 */
	public boolean setFontStyle( final String value )
	{
		final Number num = SGUtilityText.getInteger( value );
		if( num==null )
		{
			return false;
		}
		this.setFontStyle( num.intValue() );
		return true;
	}


	/**
	 * 
	 */
	public boolean setAngle( final float angle )
	{
		this.mAngle = angle;
		if( this.mDrawingElementArray!=null )
		{
			for( int ii=0; ii<this.mDrawingElementArray.length; ii++ )
			{
				SGDrawingElementString el
					= (SGDrawingElementString)this.mDrawingElementArray[ii];
				el.setAngle(angle);
			}
		}
		return true;
	}


	/**
	 * 
	 */
	public String getFontName()
	{
		return this.mFontName;
	}


	/**
	 * 
	 */
	public float getFontSize()
	{
		return this.mFontSize;
	}


	/**
	 * 
	 * @param unit
	 * @return
	 */
	public float getFontSize( final String unit )
	{
		return (float)SGUtilityText.convertFromPoint( this.getFontSize(), unit );
	}


	/**
	 * 
	 */
	public int getFontStyle()
	{
		return this.mFontStyle;
	}


	/**
	 * 
	 */
	public float getAngle()
	{
		return this.mAngle;
	}



	/**
	 * 
	 * @return
	 */
	protected boolean initDrawingElement( final SGTuple2f[] array )
	{
		final int num = array.length;
		this.initDrawingElement(num);

		SGDrawingElement[] sArray = this.mDrawingElementArray;
		for( int ii=0; ii<num; ii++ )
		{
			((SGDrawingElementString)sArray[ii]).setLocation( array[ii] );
		}
		return true;
	}


	/**
	 * 
	 */
	public boolean paintElement( final Graphics2D g2d, Rectangle2D clipRect )
	{
		if( this.mDrawingElementArray!=null )
		{
			for( int ii=0; ii<this.mDrawingElementArray.length; ii++ )
			{
				SGDrawingElementString2DExtended el
					= (SGDrawingElementString2DExtended)this.mDrawingElementArray[ii];
				el.paintElement(g2d);
			}
		}
		return true;
	}



	/**
	 * 
	 */
	public SGDrawingElement getDrawingElement()
	{
		SGDrawingElementString el
			= (SGDrawingElementString)this.createDrawingElementInstance();
		el.setVisible( this.isVisible() );
		el.setFont( this.getFontName(), this.getFontStyle(), this.getFontSize() );
		el.setAngle( this.getAngle() );
		el.setColorList( this.getColorList() );
		return el;
	}


	/**
	 * 
	 */
	public boolean setLocation(
		final SGTuple2f[] pointArray )
	{

		if( pointArray==null )
		{
			throw new IllegalArgumentException("pointArray==null");
		}

		if( pointArray.length != this.mDrawingElementArray.length )
		{
			throw new Error("pointArray.length != this.mDrawingElementArray.length");
		}

		// シンボルの描画要素を作成
		for( int ii=0; ii<pointArray.length; ii++ )
		{
			SGDrawingElementString2DExtended el
				= (SGDrawingElementString2DExtended)this.mDrawingElementArray[ii];
			final boolean eff = !( pointArray[ii].isInfinite() || pointArray[ii].isNaN() );
			el.setVisible( eff );
			if( eff )
			{
				el.setLocation( pointArray[ii] );
			}
		}

		return true;
	}


	/**
	 * 
	 * @return
	 */
	public boolean setPropertiesOfDrawingElements()
	{
		for( int ii=0; ii<this.mDrawingElementArray.length; ii++ )
		{
			final SGDrawingElementString el
				= (SGDrawingElementString)this.mDrawingElementArray[ii];
			el.setFont( this.mFontName, this.mFontStyle, this.mFontSize );
			el.setAngle( this.mAngle );
			el.setColorList( this.mColorList );
			el.setMagnification( this.mMagnification );
		}
		return true;
	}



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

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

		SGDrawingElementString el = (SGDrawingElementString)element;

		this.setFont( el.getFontName(), el.getFontStyle(), el.getFontSize() );		
		this.setAngle( el.getAngle() );

		return true;
	}





	
	/**
	 * 
	 * @return
	 */
	public String getTagName()
	{
		return TAG_NAME_LABEL;
	}


	/**
	 * 
	 */
	public boolean writeProperty( final Element el )
	{
		el.setAttribute( KEY_FONT_SIZE, Float.toString( this.mFontSize ) + SGIConstants.pt );
		el.setAttribute( KEY_FONT_NAME, this.mFontName );
		el.setAttribute( KEY_FONT_STYLE, SGUtilityText.getFontStyleName( this.mFontStyle ) );
		el.setAttribute( KEY_COLOR_LIST, SGUtilityText.getColorListString( this.mColorList ) );
		el.setAttribute( KEY_ANGLE, Float.toString( - this.mAngle/RADIAN_DEGREE_RATIO ) + SGIConstants.degree );

		return true;
	}



	/**
	 * 
	 * @param el
	 * @return
	 */
	public boolean readProperty( final Element el )
	{
		String str = null;
		Number num = null;
		Color cl = null;
		Boolean b = null;
		List list = null;


		// set font size
		str = el.getAttribute( KEY_FONT_SIZE );
		if( str.length()!=0 )
		{
			StringBuffer uFontSize = new StringBuffer();
			num = SGUtilityText.getNumber( str, uFontSize );
			if( num==null )
			{
				return false;
			}
			if( this.setFontSize( num.floatValue(), uFontSize.toString() ) == false )
			{
				return false;
			}
		}


		// set font name
		str = el.getAttribute( KEY_FONT_NAME );
		if( str.length()!=0 )
		{
			if( this.setFontName( str ) == false )
			{
				return false;
			}
		}


		// set font style
		str = el.getAttribute( KEY_FONT_STYLE );
		if( str.length()!=0 )
		{
			final int fontStyle = SGUtilityText.getFontStyle(str);
			if( fontStyle==-1 )
			{
				return false;
			}
			if( this.setFontStyle( fontStyle ) == false )
			{
				return false;
			}
		}


		// color
		str = el.getAttribute( KEY_COLOR_LIST );
		if( str.length()!=0 )
		{
			list = SGUtilityText.getColorList(str);
			if( list==null )
			{
				return false;
			}
			if( list.size()<1 )
			{
				return false;
			}
			final Color color = (Color)list.get(0);
			if( this.setColor( color ) == false )
			{
				return false;
			}
		}


		return true;
	}



	/**
	 * 
	 */
	public SGProperties getProperties()
	{
		StringProperties p = new StringProperties();
		this.getProperties(p);
		return p;
	}


	/**
	 * 
	 */
	public boolean getProperties( SGProperties p )
	{
		if( p==null ) return false;
		if( ( p instanceof StringProperties ) == false ) return false;

		super.getProperties(p);

		StringProperties sp = (StringProperties)p;
		sp.setFontName( this.getFontName() );
		sp.setFontSize( this.getFontSize() );
		sp.setFontStyle( this.getFontStyle() );
		sp.setAngle( this.getAngle() );

		return true;
	}


	/**
	 * 
	 */
	public boolean setProperties( SGProperties p )
	{
		if( ( p instanceof StringProperties ) == false ) return false;

		if( super.setProperties(p) == false ) return false;
		
		StringProperties sp = (StringProperties)p;

		final Float fontSize = sp.getFontSize();
		if( fontSize==null )
		{
			return false;
		}

		final Integer fontStyle = sp.getFontStyle();
		if( fontStyle==null )
		{
			return false;
		}

		this.setFont( sp.getFontName(), fontStyle.intValue(), fontSize.floatValue() );

		final Float angle = sp.getAngle();
		if( angle==null )
		{
			return false;
		}
		this.setAngle( angle.floatValue() );

		return true;
	}




	/**
	 * @author  okumura
	 */
	public static class StringProperties extends ElementGroupProperties
	{

		private SGDrawingElementString.StringProperties mStringProperties
			= new SGDrawingElementString.StringProperties();
		
		
//		public static final String[] keys = {
//			KEY_FONT_SIZE, KEY_FONT_STYLE, KEY_FONT_NAME, KEY_ANGLE
//		};



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


		/**
		 * 
		 */
		public boolean equals( final Object obj )
		{

			if( ( obj instanceof StringProperties ) == false )
			{
				return false;
			}
			
			if( super.equals(obj) == false ) return false;

			StringProperties p = (StringProperties)obj;
			if( this.mStringProperties.equals(p.mStringProperties) == false ) return false;

//			for( int ii=0; ii<keys.length; ii++ )
//			{
//				if( this.getProperty(keys[ii]).equals(p.getProperty(keys[ii])) == false )
//				{
//					return false;
//				}
//			}

			return true;
		}



		public Float getFontSize()
		{
			return this.mStringProperties.getFontSize();
//			final String value = this.getProperty(KEY_FONT_SIZE);
//			return SGUtilityText.getFloat(value);
		}


		public Integer getFontStyle()
		{
			return this.mStringProperties.getFontStyle();
//			final String value = this.getProperty(KEY_FONT_STYLE);
//			return SGUtilityText.getInteger(value);
		}


		public String getFontName()
		{
			return this.mStringProperties.getFontName();
//			return this.getProperty(KEY_FONT_NAME);
		}


		public Float getAngle()
		{
			return this.mStringProperties.getAngle();
//			final String value = this.getProperty(KEY_ANGLE);
//			return SGUtilityText.getFloat(value);
		}


		public void setFontSize( final float size )
		{
			this.mStringProperties.setFontSize( size );
//			if( size<0.0f )
//			{
//				return false;
//			}
//			this.setProperty( KEY_FONT_SIZE, new Float(size).toString() );
//			return true;
		}


		public void setFontStyle( final int style )
		{
			this.mStringProperties.setFontStyle( style );
//			this.setProperty( KEY_FONT_STYLE, new Integer(style).toString() );
//			return true;
		}


		public void setFontName( final String name )
		{
			this.mStringProperties.setFontName( name );
//			if( name==null )
//			{
//				return false;
//			}
//			this.setProperty( KEY_FONT_NAME, new String(name) );
//			return true;
		}

		public void setAngle( final float angle )
		{
			this.mStringProperties.setAngle( angle );
//			this.setProperty( KEY_ANGLE, new Float(angle).toString() );
//			return true;
		}

	}


}

