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

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


/**
 * 描画要素のグループの基本クラス
 * 描画要素(SGDrawingElement)のリストを持つ
 */
public abstract class SGElementGroup
	implements ActionListener
{

	/**
	 * 描画要素(SGDrawingElement)のリスト
	 */
	protected ArrayList mDrawingElementList = new ArrayList();



	/**
	 * ElementGroupSetへの参照
	 */
	protected SGElementGroupSet mGroupSet = null;



	/**
	 * 
	 */
	protected float mMagnification = 1.0f;


	/**
	 * 
	 */
	protected float mRulerUnit = SGConstants.CM_POINT_RATIO;



	/**
	 * 
	 */
	protected ArrayList mColorList = new ArrayList();


	/**
	 * 
	 */
	protected boolean mEnteredFlag = false;


	/**
	 * 
	 */
	protected boolean mSelectedFlag = false;


	/**
	 * 
	 */
	protected boolean mVisibleFlag = true;



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


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


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


	/**
	 *
	 */
	public static final int ARROW_GROUP = 3;



	/**
	 * 
	 */
	public static final String KEY_VISIBLE = "Visible";


	public static final String KEY_COLOR_LIST = "Colors";



	/**
	 * 
	 * @return
	 */
	public SGElementGroup()
	{
	}



	/**
	 * 
	 */
	protected boolean setDialogProperty()
	{
		return true;
	}



	/**
	 * 
	 */
	public boolean setMagnification( final float ratio )
	{
		mMagnification = ratio;
		for( int ii=0; ii<mDrawingElementList.size(); ii++ )
		{
			SGDrawingElement el = (SGDrawingElement)mDrawingElementList.get(ii);
			el.setMagnification(ratio);
		}

		return true;
	}


	/**
	 * 
	 */
	public boolean addColor( final Color color )
	{

//System.out.println("addColor"+"  "+color);
//System.out.println(this.mColorList);

		mColorList.add(color);
		for( int ii=0; ii<this.mDrawingElementList.size(); ii++ )
		{
			SGDrawingElement el = (SGDrawingElement)mDrawingElementList.get(ii);
			el.addColor( color );
		}

//System.out.println(this.mColorList);
//System.out.println();

		return true;
	}


	/**
	 * 
	 */
	public boolean setColor( final Color color )
	{
		mColorList.clear();
		mColorList.add(color);
		for( int ii=0; ii<this.mDrawingElementList.size(); ii++ )
		{
			SGDrawingElement el = (SGDrawingElement)mDrawingElementList.get(ii);
			el.setColor( color );
		}
		return true;
	}


	/**
	 * 
	 */
	public boolean setColorList( final ArrayList colorList )
	{
		mColorList = new ArrayList(colorList);
		for( int ii=0; ii<this.mDrawingElementList.size(); ii++ )
		{
			SGDrawingElement el = (SGDrawingElement)mDrawingElementList.get(ii);
			el.setColorList( colorList );
		}
		
		return true;
	}


	/**
	 * 
	 */
	public Color getColor( final int index )
	{
		if( mColorList == null )
		{
			return null;
		}

		if( index >= mColorList.size() )
		{
			return null;
		}

		return (Color)mColorList.get(index);
	}


	/**
	 * 
	 */
	public ArrayList getColorList()
	{
		return mColorList;
	}



	/**
	 * 
	 */
	public boolean zoom( final int w, final int h, final float ratio )
	{

		this.mMagnification = ratio;

		for( int ii=0; ii<this.mDrawingElementList.size(); ii++ )
		{
			SGDrawingElement element = (SGDrawingElement)mDrawingElementList.get(ii);
			element.zoom(w,h,ratio);
		}

		return true;
	}



	/**
	 *
	 */
	public boolean addDrawingElement( final SGDrawingElement element )
	{
		mDrawingElementList.add(element);
		return true;
	}


	/**
	 * 
	 */
	public ArrayList getDrawingElementList()
	{
		return this.mDrawingElementList;
	}



	/**
	 * 
	 */
	public boolean isVisible()
	{
		return this.mVisibleFlag;
	}


	/**
	 * 
	 */
	public void setVisible( final boolean flag )
	{
		this.mVisibleFlag = flag;
	}



	/**
	 * 
	 */
	public boolean contains( final int x, final int y )
	{
		for( int ii=0; ii<this.mDrawingElementList.size(); ii++ )
		{
			SGDrawingElement el = (SGDrawingElement)this.mDrawingElementList.get(ii);
			if( el.contains(x,y) )
			{
				return true;
			}
		}
		return false;
	}



	/**
	 * 
	 */
	public abstract boolean paintElement( final Graphics2D g2d );


	/**
	 * 
	 */
	public abstract SGDrawingElement getDrawingElement();


	/**
	 * 
	 */
	public boolean setProperty( final SGDrawingElement element )
	{
		this.setColorList( element.getColorList() );

		return true;
	}



	/**
	 * 
	 */
	protected boolean shiftColorList()
	{
		ArrayList colorList_ = new ArrayList();
		for( int ii=0; ii<this.mColorList.size(); ii++ )
		{
			Color colorOld = ((Color)this.mColorList.get(ii));
			Color color_ = new Color(
				( colorOld.getRed() + 128 )%256,
				( colorOld.getGreen() + 128 )%256,
				( colorOld.getBlue() + 128 )%256
			);
			colorList_.add(color_);
		}

		this.mColorList = new ArrayList( colorList_ );

		return true;
	}


	/**
	 * 
	 */
	public void actionPerformed( final ActionEvent e )
	{
		String strCommand = e.getActionCommand();
	}


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



	/**
	 * 
	 */
	public boolean readProperty( final BufferedReader br ) throws IOException
	{
		SGProperties p = this.readProperties( br );
		if( this.setProperties(p) == false ) return false;
		return true;
	}


	/**
	 * 
	 */
	public abstract SGProperties readProperties( final BufferedReader br ) throws IOException;


	/**
	 * 
	 */
	public boolean setPropertyWithDialog()
	{
		if( this.setProperties( this.getPropertiesFromDialog() ) == false ) return false;

		return true;

	}



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

		return p;
	}


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

		ElementGroupProperties ep = (ElementGroupProperties)p;

		ep.setVisible( this.isVisible() );
		ep.setColorList( new ArrayList( this.mColorList ) );

		return true;
	}


	/**
	 * 
	 */
	protected ElementGroupProperties getPropertiesFromDialog()
	{
		return null;
	}



	/**
	 * 
	 */
	public boolean setProperties( SGProperties p )
	{

		if( ( p instanceof ElementGroupProperties ) == false ) return false;

		ElementGroupProperties ep = (ElementGroupProperties)p;

		final Boolean b = ep.isVisible();
		if( b==null )
		{
			return false;
		}

		final ArrayList cList = ep.getColorList();
		if( cList==null )
		{
			return false;
		}

		this.setVisible( b.booleanValue() );
		this.setColorList( cList );

		return true;		
	}


	/**
	 * 
	 */
	public static class ElementGroupProperties extends SGProperties
	{
//		boolean visible;
//		ArrayList colorList = new ArrayList();

		public static final String[] keys = {
			KEY_VISIBLE, KEY_COLOR_LIST
		};


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

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

			if( ( obj instanceof ElementGroupProperties ) == false )
			{
				return false;
			}

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

			return true;
		}


		public Boolean isVisible()
		{
			final String value = this.getProperty(KEY_VISIBLE);
			return SGUtilityText.getBoolean(value);
		}

		public ArrayList getColorList()
		{
			final String value = this.getProperty(KEY_COLOR_LIST);
			return SGUtilityText.getColorList(value);
		}

		public boolean setVisible( final boolean b )
		{
			this.setProperty( KEY_VISIBLE, new Boolean(b).toString() );
			return true;
		}

		public boolean setColorList( final ArrayList list )
		{
			if( list==null )
			{
				return false;
			}

			String str = SGUtilityText.getColorListString( list );
			if( str==null )
			{
				return false;
			}
			this.setProperty( KEY_COLOR_LIST, str );
			return true;
		}


	}



}

