/*
 * Created on 2004/08/06
 *
 * 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.io.*;
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
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 abstract class SGElementGroupErrorBar extends SGElementGroupArrow
{

	/**
	 * 
	 */
	public static final String ERROR_BAR_TITLE = "<Error Bar>";
	public static final String KEY_ERROR_BAR_STYLE = "Error Bar Style";

	public static final String ERROR_BAR_HEAD_TYPE = "Head Type";


	/**
	 * 
	 */
	public static final int ERROR_BAR_FULL = 0;


	/**
	 * 
	 */
	public static final int ERROR_BAR_UPPER_ONLY = 1;


	/**
	 * 
	 */
	public static final int ERROR_BAR_LOWER_ONLY = 2;



	/**
	 * 
	 */
	public static final String SHOW_FULLY = "Bothsides";


	/**
	 * 
	 */
	public static final String SHOW_UPPER_ONLY = "Upside";


	/**
	 * 
	 */
	public static final String SHOW_LOWER_ONLY = "Downside";


	/**
	 * 
	 */
	public int mErrorBarStyle = ERROR_BAR_FULL;



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


	/**
	 * 
	 */
	public boolean setColor( final Color color )
	{
		super.setColor( color );

		this.mHeadEdgeLineColor = color;
		for( int ii=0; ii<mDrawingElementList.size(); ii++ )
		{
			SGDrawingElementArrow2D el = (SGDrawingElementArrow2D)mDrawingElementList.get(ii);
			el.setHeadEdgeLineColor(color);
		}

		return true;
	}


	/**
	 * 
	 */
	public boolean setColorList( final ArrayList cList )
	{
		super.setColorList( cList );

		Color color = (Color)cList.get(0);
		this.mHeadEdgeLineColor = color;
		for( int ii=0; ii<mDrawingElementList.size(); ii++ )
		{
			SGDrawingElementArrow2D el = (SGDrawingElementArrow2D)mDrawingElementList.get(ii);
			el.setHeadEdgeLineColor(color);
		}
		
		return true;
	}


	/**
	 * 
	 * @return
	 */
	public int getErrorBarStyle()
	{
		return this.mErrorBarStyle;
	}


	/**
	 * 
	 * @param style
	 * @return
	 */
	public boolean setErrorBarStyle( final int style )
	{
		this.mErrorBarStyle = style;
		return true;
	}



	/**
	 * 
	 */
	public boolean writePropertyOfData( final Writer writer ) throws IOException
	{

		writer.write( ERROR_BAR_TITLE + "\n" );

		SGUtilityText.writePropertyLine( writer, KEY_VISIBLE, new Boolean( this.mVisibleFlag ) );
		SGUtilityText.writePropertyLine( writer, KEY_ERROR_BAR_STYLE, getErrorBarStyleName( this.mErrorBarStyle ) );
		SGUtilityText.writePropertyLine( writer, KEY_LINE_WIDTH, new Float( this.mLineWidth ) );
		SGUtilityText.writePropertyLine( writer, KEY_HEAD_SIZE, new Float( this.mHeadSize*this.mRulerUnit ) );
		SGUtilityText.writePropertyLine( writer, KEY_HEAD_LINE_WIDTH, new Float( this.mLineWidth ) );
//		SGUtilityText.writePropertyLine( writer, PF_ERROR_BAR_HEAD_TYPE, new Integer( this.getHeadType() ) );
SGUtilityText.writePropertyLine( writer, ERROR_BAR_HEAD_TYPE, SGDrawingElementSymbol.getSymbolTypeName( this.getHeadType() ) );
		SGUtilityText.writeColorListPropertyLine( writer, KEY_COLOR_LIST, this.mColorList );

		writer.write("\n");

		return true;

	}


	/**
	 * 
	 */
	public static Integer getErrorBarStyleFromName( final String name )
	{
		if( name==null )
		{
			return null;
		}

		int style;
		if( name.equals(SHOW_FULLY) )
		{
			style = ERROR_BAR_FULL;
		}
		else if( name.equals(SHOW_UPPER_ONLY) )
		{
			style = ERROR_BAR_UPPER_ONLY;
		}
		else if( name.equals(SHOW_LOWER_ONLY) )
		{
			style = ERROR_BAR_LOWER_ONLY;
		}
		else
		{
			return null;
		}

		return new Integer(style);
	}



	/**
	 * 
	 */
	public static String getErrorBarStyleName( final int style )
	{

		String name = null;
		switch( style )
		{
			case ERROR_BAR_FULL :
			{
				name = SHOW_FULLY;
				break;
			}

			case ERROR_BAR_UPPER_ONLY :
			{
				name = SHOW_UPPER_ONLY;
				break;
			}

			case ERROR_BAR_LOWER_ONLY :
			{
				name = SHOW_LOWER_ONLY;
				break;
			}
			
			default :
			{
				
			}
		}

		return name;
	}




	/**
	 * 
	 */
	public int getHeadType()
	{

		int headType;
		switch( this.mErrorBarStyle )
		{
			case ERROR_BAR_FULL :
			{
				headType = this.mStartHeadType;
				break;
			}
			
			case ERROR_BAR_UPPER_ONLY :
			{
				headType = this.mEndHeadType;
				break;
			}

			case ERROR_BAR_LOWER_ONLY :
			{
				headType = this.mStartHeadType;
				break;
			}

			default :
			{
				throw new Error();
			}
		}

		return headType;
	}


	/**
	 * 
	 */
	public boolean setHeadType( int type )
	{
		switch( this.mErrorBarStyle )
		{
			case ERROR_BAR_FULL :
			{
				this.mStartHeadType = type;
				this.mEndHeadType = type;
				break;
			}
			
			case ERROR_BAR_UPPER_ONLY :
			{
				this.mEndHeadType = type;
				break;
			}

			case ERROR_BAR_LOWER_ONLY :
			{
				this.mStartHeadType = type;
				break;
			}

			default :
			{
				throw new Error();
			}
		}

		return true;
	}



		/**
		 * 
		 */
		public SGProperties readProperties( final BufferedReader br ) throws IOException
		{
			ErrorBarProperties p = new ErrorBarProperties();


			String line = null;

			// visible
			if( ( line = SGUtilityText.readLine(br) ) == null )
			{
				return null;
			}
			Boolean bVisible = SGUtilityText.getBooleanPropertyFromLine(line,KEY_VISIBLE);
			if( bVisible == null )
			{
				return null;
			}
			p.setVisible( bVisible.booleanValue() );


			// style of error bars
			if( ( line = SGUtilityText.readLine(br) ) == null )
			{
				return null;
			}

			String strErrorBarStyle = SGUtilityText.getPropertyFromLine(line,KEY_ERROR_BAR_STYLE);
			if( strErrorBarStyle==null )
			{
				return null;
			}
			Integer nErrorBarStyle = getErrorBarStyleFromName( strErrorBarStyle );
			if( nErrorBarStyle == null )
			{
				return null;
			}
			p.setErrorBarStyle( nErrorBarStyle.intValue() );


			// line width
			if( ( line = SGUtilityText.readLine(br) ) == null )
			{
				return null;
			}
			Double dErrBarLineWidth = SGUtilityText.getDoublePropertyFromLine(line,KEY_LINE_WIDTH);
			if( dErrBarLineWidth == null )
			{
				return null;
			}
			p.setLineWidth( dErrBarLineWidth.floatValue() );


			// head size
			if( ( line = SGUtilityText.readLine(br) ) == null )
			{
				return null;
			}
			Double dHeadSize = SGUtilityText.getDoublePropertyFromLine(line,KEY_HEAD_SIZE);
			if( dHeadSize == null )
			{
				return null;
			}
			p.setHeadSize( dHeadSize.floatValue()/SGConstants.CM_POINT_RATIO );


			// head edge line width
			if( ( line = SGUtilityText.readLine(br) ) == null )
			{
				return null;
			}
			Double dHeadEdgeLineWidth = SGUtilityText.getDoublePropertyFromLine(line,KEY_HEAD_LINE_WIDTH);
			if( dHeadEdgeLineWidth == null )
			{
				return null;
			}
			p.setHeadLineWidth( dHeadEdgeLineWidth.floatValue() );


			// start head type
			if( ( line = SGUtilityText.readLine(br) ) == null )
			{
				return null;
			}
			String strHeadType = SGUtilityText.getPropertyFromLine(line,ERROR_BAR_HEAD_TYPE);
			if( strHeadType==null )
			{
				return null;
			}
			Integer nHeadType = SGDrawingElementSymbol.getSymbolTypeFromName( strHeadType );
			if( nHeadType==null )
			{
				return null;
			}
			if( nHeadType == null )
			{
				return null;
			}
			p.setStartHeadType( nHeadType.intValue() );
			p.setEndHeadType( nHeadType.intValue() );


			// color
			if( ( line = SGUtilityText.readLine(br) ) == null )
			{
				return null;
			}
			ArrayList colorList = SGUtilityText.getColorListFromLine(line,KEY_COLOR_LIST);
			if( colorList==null )
			{
				return null;
			}
			p.setColorList( colorList );


			// not from bufferred reader
			p.setLineType( this.mLineType );


			return p;

		}



		/**
		 * 
		 */
		public boolean createDrawingElement(
			final ArrayList startPointList,
			final ArrayList endPointList )
		{
//System.out.println("<< createDrawingElement >>");

			mDrawingElementList.clear();

			if( startPointList.size() != endPointList.size() )
			{
				return false;
			}


			// シンボルの描画要素を作成
			for( int ii=0; ii<startPointList.size(); ii++ )
			{
				SGTuple2f startRatio = (SGTuple2f)startPointList.get(ii);
				SGTuple2f endRatio = (SGTuple2f)endPointList.get(ii);

//System.out.println( startRatio.x+"  "+startRatio.y+"  "+endRatio.x+"  "+endRatio.y);

				SGDrawingElementArrow2D arrow
					= (SGDrawingElementArrow2D)this.getDrawingElement();
				arrow.setTermPoints( startRatio, endRatio );
				arrow.setMagnification(mMagnification);

				if( mErrorBarStyle == ERROR_BAR_FULL )
				{
					arrow.setStartHeadType( this.mStartHeadType );
					arrow.setEndHeadType( this.mEndHeadType );
				}
				else if ( mErrorBarStyle == ERROR_BAR_UPPER_ONLY )
				{
					arrow.setStartHeadType( SGDrawingElementSymbol.SYMBOL_TYPE_VOID );
					arrow.setEndHeadType( this.mEndHeadType );
				}
				else if ( mErrorBarStyle == ERROR_BAR_LOWER_ONLY )
				{
					arrow.setStartHeadType( this.mStartHeadType );
					arrow.setEndHeadType( SGDrawingElementSymbol.SYMBOL_TYPE_VOID );
				}


//System.out.println(arrow.getHeadOpenAngle()+"  "+arrow.getHeadCloseAngle());

				this.addDrawingElement( arrow );
			}

//System.out.println("mDrawingElementList.size()=="+mDrawingElementList.size());
//System.out.println();

/*
System.out.println("*** "+this.mLineWidth+"  "+this.mHeadEdgeLineWidth);
for( int ii=0; ii<this.mDrawingElementList.size(); ii++ )
{
	SGDrawingElementArrow el = (SGDrawingElementArrow)this.mDrawingElementList.get(ii);
	System.out.println(ii+"  "+el.getLineWidth()+"  "+el.getHeadEdgeLineWidth());
}
System.out.println();
*/

			return true;
		}



		/**
		 * 
		 */
		protected String[] getPopupMenuCommandArray()
		{
			final String[] commandArray = {
				SYMBOL_CIRCLE,
				SYMBOL_TRANSVERSE_LINE,
				NO_SYMBOL,
				SHOW_FULLY,
				SHOW_UPPER_ONLY,
				SHOW_LOWER_ONLY
			};

			return commandArray;
		}



		/**
		 * 
		 */
		public SGProperties getProperties()
		{
			ErrorBarProperties p = new ErrorBarProperties();
			this.getProperties(p);

//System.out.println(p);

			return p;
		}



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

			super.getProperties(p);

			ErrorBarProperties ep = (ErrorBarProperties)p;
			ep.setErrorBarStyle( this.getErrorBarStyle() );

			return true;
		}



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

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

			ErrorBarProperties ep = (ErrorBarProperties)p;
			Integer style = ep.getErrorBarStyle();
			if( style==null )
			{
				return false;
			}
			this.mErrorBarStyle = style.intValue();

			return true;
		}





		/**
		 * 
		 */
		public static class ErrorBarProperties extends ArrowProperties
		{
//			int style;

			public static final String[] keys =
			{
				KEY_ERROR_BAR_STYLE
			};


			/**
			 * 
			 *
			 */
			public ErrorBarProperties()
			{
				super();
				this.init();
			}


			/**
			 * 
			 * @return
			 */
			private boolean init()
			{
				this.setLineType( SGDrawingElementLine.LINE_TYPE_SOLID );
				this.setHeadOpenAngle( 0.0f );
				this.setHeadCloseAngle( 0.0f );

				return true;
			}



			/*
			 * 
			 */
			public boolean equals( final Object obj )
			{
				if( ( obj instanceof ErrorBarProperties ) == false )
				{
					return false;
				}

				boolean flag = super.equals(obj);
				if( !flag ) return false;

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

				return true;
			}


			public Integer getErrorBarStyle()
			{
				final String value = this.getProperty(KEY_ERROR_BAR_STYLE);
				return SGUtilityText.getInteger(value);
			}

			public boolean setErrorBarStyle( final int style )
			{
				this.setProperty( KEY_ERROR_BAR_STYLE, new Integer(style).toString() );
				return true;
			}


			/**
			 * 
			 */
			public String toString()
			{
				String str = new String("[");
				str += this.getProperty(KEY_ERROR_BAR_STYLE);
				str += new String("]");

				return str;
			}


		}



}
