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

import java.util.*;
import java.io.*;
import java.awt.*;
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.*;


/**
 * 
 */
public abstract class SGElementGroupSymbol extends SGElementGroupSXY
{

	/**
	 *
	 */
	protected float mSymbolSize;


	/**
	 *
	 */
	protected int mSymbolType;


	/**
	 * 
	 */
	protected double mAngle;


	/**
	 * 
	 */
	protected Color mLineColor = Color.BLACK;

		
	/**
	 * 
	 */
	protected float mLineWidth;



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


	/**
	 * 
	 */
	public float getSize()
	{
		return this.mSymbolSize;
	}


	/**
	 * 
	 */
	public int getType()
	{
		return this.mSymbolType;
	}


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


	/**
	 * 
	 */
	public float getLineWidth()
	{
		return this.mLineWidth;
	}


	/**
	 * 
	 */
	public Color getLineColor()
	{
		return this.mLineColor;
	}


	/**
	 *
	 */
	public boolean setSize( final float size )
	{
		mSymbolSize = size;
		for( int ii=0; ii<mDrawingElementList.size(); ii++ )
		{
			SGDrawingElementSymbol2D el = (SGDrawingElementSymbol2D)mDrawingElementList.get(ii);
			el.setSize(mSymbolSize);
		}
		return true;
	}


	  /**
	   *
	   */
	public boolean setType( final int type )
	  {
		  mSymbolType = type;
		  for( int ii=0; ii<mDrawingElementList.size(); ii++ )
		  {
			  SGDrawingElementSymbol2D el = (SGDrawingElementSymbol2D)mDrawingElementList.get(ii);
			  el.setType(mSymbolType);
		  }
		  return true;
	  }


	  /**
	   *
	   */
/*	public boolean setAngle( final double angle )
	  {
		  mAngle = angle;
		  for( int ii=0; ii<mDrawingElementList.size(); ii++ )
		  {
			  SGDrawingElementSymbol2D el = (SGDrawingElementSymbol2D)mDrawingElementList.get(ii);
			  el.setAngle(mAngle);
		  }
		  return true;
	  }
*/

	  /**
	   *
	   */
	public boolean setLineColor( final Color color )
	  {
		  mLineColor = color;
		  for( int ii=0; ii<mDrawingElementList.size(); ii++ )
		  {
			  SGDrawingElementSymbol2D el = (SGDrawingElementSymbol2D)mDrawingElementList.get(ii);
			  el.setLineColor(mLineColor);
		  }
		  return true;
	  }

	  /**
	   *
	   */
	public boolean setLineWidth( final float width )
	  {
		  mLineWidth = width;
		  for( int ii=0; ii<mDrawingElementList.size(); ii++ )
		  {
			  SGDrawingElementSymbol2D el = (SGDrawingElementSymbol2D)mDrawingElementList.get(ii);
			  el.setLineWidth(mLineWidth);
		  }
		  return true;
	  }


	/**
	 * 
	 */
	public SGDrawingElement getDrawingElement()
	{
		SGDrawingElementSymbol symbol = new SGDrawingElementSymbol2D();
		symbol.setSize( mSymbolSize );
		symbol.setType( mSymbolType );	
//		symbol.setAngle( mAngle );
		symbol.setColorList( mColorList );
		symbol.setLineColor( mLineColor );
		symbol.setLineWidth( mLineWidth );

		return symbol;
	}


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

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

		SGDrawingElementSymbol symbol = (SGDrawingElementSymbol)element;

		this.setType( symbol.getType() );
		this.setSize( symbol.getSize() );
//		this.setAngle( symbol.getAngle() );
		this.setLineWidth( symbol.getLineWidth() );
		this.setLineColor( symbol.getLineColor() );
	
		return true;
	}


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

		ArrayList colorList = new ArrayList(this.mColorList);
		if( this.mEnteredFlag )
		{
			ArrayList colorList_ = new ArrayList();
			for( int ii=0; ii<colorList.size(); ii++ )
			{
				Color colorOld = ((Color)colorList.get(ii));
/*		Color color_ = new Color(
			255 - colorOld.getRed(),
			255 - colorOld.getGreen(),
			255 - colorOld.getBlue()
		);
*/
				Color color_ = new Color(
					colorOld.getRed(),
					colorOld.getGreen(),
					colorOld.getBlue(),
					128
				);
				colorList_.add(color_);
			}
			this.setColorList(colorList_);
		}


		if( this.mSelectedFlag )
		{
//			this.shiftColorList();
		}



//System.out.println(dElementList.size());

		for( int jj=0; jj<this.mDrawingElementList.size(); jj++ )
		{
//System.out.println("jj="+jj);

			SGDrawingElementSymbol2D el
				= (SGDrawingElementSymbol2D)mDrawingElementList.get(jj);
			Shape shape = el.getShape();

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


			g2d.setStroke(
				new BasicStroke
				(
					mMagnification*this.mLineWidth,
					BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER
				)
			);
			g2d.setPaint(this.mLineColor);
			g2d.draw(shape);

		}


		this.setColorList(colorList);


		return true;
	}



	public static final String PF_SYMBOL_TITLE = "<Symbol>";
	public static final String KEY_SYMBOL_SIZE = "Size";
	public static final String KEY_SYMBOL_TYPE = "Type";
	public static final String KEY_LINE_WIDTH = "Edge Line Width";
	public static final String KEY_LINE_COLOR = "Edge Line Color";
	public static final String PF_SYMBOL_COLOR_LIST = "Inner Color List";





	/**
	 * 
	 */
	public boolean writePropertyOfData( final Writer writer ) throws IOException
	{
		writer.write( PF_SYMBOL_TITLE + "\n" );

		SGUtilityText.writePropertyLine( writer, KEY_VISIBLE, new Boolean( this.mVisibleFlag ) );
		SGUtilityText.writePropertyLine( writer, KEY_SYMBOL_SIZE, new Float( this.mSymbolSize*this.mRulerUnit ) );
		SGUtilityText.writePropertyLine( writer, KEY_SYMBOL_TYPE, SGDrawingElementSymbol.getSymbolTypeName( this.mSymbolType ) );
		SGUtilityText.writeColorListPropertyLine( writer, PF_SYMBOL_COLOR_LIST, this.mColorList );
		SGUtilityText.writePropertyLine( writer, KEY_LINE_WIDTH, new Float( this.mLineWidth ) );
		SGUtilityText.writeColorPropertyLine( writer, KEY_LINE_COLOR, this.mLineColor );

		writer.write("\n");

		return true;

	}



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

		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() );


		// symbol size
		if( ( line = SGUtilityText.readLine(br) ) == null )
		{
			return null;
		}
		Double dSymbolSize = SGUtilityText.getDoublePropertyFromLine(line,KEY_SYMBOL_SIZE);
		if( dSymbolSize == null )
		{
			return null;
		}
		p.setSize( dSymbolSize.floatValue()/SGConstants.CM_POINT_RATIO );


		// symbol type
		if( ( line = SGUtilityText.readLine(br) ) == null )
		{
			return null;
		}
		String strSymbolType = SGUtilityText.getPropertyFromLine(line,KEY_SYMBOL_TYPE);
		if( strSymbolType == null )
		{
			return null;
		}
		Integer nSymbolType = SGDrawingElementSymbol.getSymbolTypeFromName(strSymbolType);
		if( nSymbolType == null )
		{
			return null;
		}
		p.setSymbolType( nSymbolType.intValue() );


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


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


		// edge line color
		if( ( line = SGUtilityText.readLine(br) ) == null )
		{
			return null;
		}
		Color edgeLineColor = SGUtilityText.getColorPropertyFromLine(line,KEY_LINE_COLOR);
		if( edgeLineColor == null )
		{
			return null;
		}
		p.setLineColor( edgeLineColor );


		return p;

	}



	/**
	 * 
	 */
	public boolean createDrawingElement( final ArrayList pointList )
	{
//System.out.println("createDrawingElement");

		mDrawingElementList.clear();

		// シンボルの描画要素を作成
		for( int ii=0; ii<pointList.size(); ii++ )
		{
			SGTuple2f ratio = (SGTuple2f)pointList.get(ii);
			SGDrawingElementSymbol2D symbol = new SGDrawingElementSymbol2D();
			symbol.setLocation( ratio );
			symbol.setMagnification(mMagnification);
			symbol.setSize( this.mSymbolSize );
			symbol.setType( this.mSymbolType );
			symbol.setColorList( this.mColorList );
			symbol.setLineWidth( this.mLineWidth );
			symbol.setLineColor( this.mLineColor );

			this.addDrawingElement( symbol );
		}

		return true;
	}


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


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

		super.getProperties(p);

		SymbolProperties sp = (SymbolProperties)p;
		sp.setSize( this.getSize() );
		sp.setSymbolType( this.getType() );
		sp.setLineWidth( this.getLineWidth() );
		sp.setLineColor( this.getLineColor() );
		sp.angle = this.getAngle();

		return true;
	}


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

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

		final Float size = sp.getSize();
		if( size==null )
		{
			return false;
		}
		this.setSize( size.floatValue() );

		final Integer type = sp.getSymbolType();
		if( type==null )
		{
			return false;
		}
		this.setType( type.intValue() );

		final Float lineWidth = sp.getLineWidth();
		if( lineWidth==null )
		{
			return false;
		}
		this.setLineWidth( lineWidth.floatValue() );

		final Color lineColor = sp.getLineColor();
		if( lineColor==null )
		{
			return false;
		}
		this.setLineColor( lineColor );

		return true;
	}





	/**
	 * 
	 */
	public static class SymbolProperties extends ElementGroupProperties
	{
//		int type;
//		float size;
//		float lineWidth;
//		Color lineColor;
		double angle;

		public static final String[] keys = {
			KEY_SYMBOL_TYPE, KEY_SYMBOL_SIZE,
			KEY_LINE_WIDTH, KEY_LINE_COLOR
		};



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


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

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

			if( p.angle != this.angle ) return false;

			return true;
		}


		public Float getSize()
		{
			final String value = this.getProperty(KEY_SYMBOL_SIZE);
			return SGUtilityText.getFloat(value);
		}

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

		public Float getLineWidth()
		{
			final String value = this.getProperty(KEY_LINE_WIDTH);
			return SGUtilityText.getFloat(value);
		}

		public Color getLineColor()
		{
			final String value = this.getProperty(KEY_LINE_COLOR);
			return SGUtilityText.getColorFromString(value);
		}


		public boolean setSize( final float size )
		{
			if( size<0.0f )
			{
				return false;
			}
			this.setProperty( KEY_SYMBOL_SIZE, new Float(size).toString() );
			return true;
		}


		public boolean setSymbolType( final int type )
		{
			this.setProperty( KEY_SYMBOL_TYPE, new Integer(type).toString() );
			return true;
		}


		public boolean setLineWidth( final float width )
		{
			if( width<0.0f )
			{
				return false;
			}
			this.setProperty( KEY_LINE_WIDTH, new Float(width).toString() );
			return true;
		}

		public boolean setLineColor( final Color cl )
		{
			if( cl==null )
			{
				return false;
			}
			String str = SGUtilityText.getColorString(cl);
			if( str==null )
			{
				return false;
			}
			this.setProperty( KEY_LINE_COLOR, str );
			return true;
		}



		/**
		 * 
		 */
/*		public String toString()
		{
			String str = new String("[");
			str += new String("visible="+visible+", ");
			str += new String("colorList="+colorList+", ");
			str += new String("type="+type+", ");
			str += new String("size="+size+", ");
			str += new String("edgeLineWidth="+edgeLineWidth+", ");
			str += new String("edgeLineColor="+edgeLineColor+", ");
			str += new String("angle="+angle+", ");
			str += new String("]");

			return str;
		}
*/

	}



}
