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

import java.util.ArrayList;
import jp.riken.brain.ni.samuraigraph.base.SGAxis;
import jp.riken.brain.ni.samuraigraph.base.SGDrawingElement;
import jp.riken.brain.ni.samuraigraph.base.SGIFigureElement;
import jp.riken.brain.ni.samuraigraph.base.SGIUndoable;
import jp.riken.brain.ni.samuraigraph.base.SGProperties;
import jp.riken.brain.ni.samuraigraph.base.SGUndoManager;
import jp.riken.brain.ni.samuraigraph.figure.SGElementGroup;
import jp.riken.brain.ni.samuraigraph.figure.SGElementGroupSet;
import org.w3c.dom.Element;



/**
 * The class for the set of drawing elements group used in this package.
 */
public abstract class SGElementGroupSetInFigureElement extends SGElementGroupSet
	implements SGIUndoable
{

	/**
	 *
	 */
	protected String mName = null;

	
	/**
	 * 
	 */
	protected boolean mVisibleInLegendFlag = true;
	
	
	/**
	 * 
	 */
	protected SGAxis mXAxis = null;


	/**
	 * 
	 */
	protected SGAxis mYAxis = null;


	/**
	 * 
	 */
	protected SGAxis mZAxis = null;


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



	/**
	 * 
	 */
	public void dispose()
	{
		super.dispose();
		this.mName = null;
		
		this.mUndoManager.dispose();
		this.mUndoManager = null;

		this.mXAxis = null;
		this.mYAxis = null;
		this.mZAxis = null;
	}


	/**
	 *
	 */
	public boolean setName( final String name )
	{
		this.mName = name;
		return true;
	}


	/**
	 * 
	 * @param b
	 * @return
	 */
	public boolean setVisibleInLegend( final boolean b )
	{
		this.mVisibleInLegendFlag = b;
		return true;
	}
	

	/**
	 * 
	 */
	public String getName()
	{
		return this.mName;
	}


	/**
	 * 
	 * @return
	 */
	public boolean isVisibleInLegend()
	{
		return this.mVisibleInLegendFlag;
	}



	/**
	 * 
	 */
	protected boolean setXAxis( final SGAxis axis )
	{
		this.mXAxis = axis;
		return true;
	}


	/**
	 * 
	 */
	protected boolean setYAxis( final SGAxis axis )
	{
		this.mYAxis = axis;
		return true;
	}


	/**
	 * 
	 */
	protected boolean setZAxis( final SGAxis axis )
	{
		this.mZAxis = axis;
		return true;
	}



				
	/**
	 * 
	 */
	public SGAxis getXAxis()
	{
		return this.mXAxis;
	}


	/**
	 * 
	 */
	public SGAxis getYAxis()
	{
		return this.mYAxis;
	}

		
	/**
	 * 
	 */
	public SGAxis getZAxis()
	{
		return this.mZAxis;
	}



	/**
	 * 
	 */
	public ArrayList getLineGroups()
	{
		ArrayList list = new ArrayList();
		ArrayList dList = this.mDrawingElementGroupList;
		for( int ii=0; ii<dList.size(); ii++ )
		{
			Object obj = dList.get(ii);
			if( obj instanceof SGElementGroupLine )
			{
				list.add(obj);
			}
		}
		return list;
	}


	/**
	 * 
	 */
	public ArrayList getSymbolGroups()
	{
		ArrayList list = new ArrayList();
		ArrayList dList = this.mDrawingElementGroupList;
		for( int ii=0; ii<dList.size(); ii++ )
		{
			Object obj = dList.get(ii);
			if( obj instanceof SGElementGroupSymbol )
			{
				list.add(obj);
			}
		}
		return list;
	}


	/**
	 * 
	 */
	public ArrayList getBarGroups()
	{
		ArrayList list = new ArrayList();
		ArrayList dList = this.mDrawingElementGroupList;
		for( int ii=0; ii<dList.size(); ii++ )
		{
			Object obj = dList.get(ii);
			if( obj instanceof SGElementGroupBar )
			{
				list.add(obj);
			}
		}
		return list;
	}


	/**
	 * 
	 */
	public ArrayList getErrorBarGroups()
	{
		ArrayList list = new ArrayList();
		ArrayList dList = this.mDrawingElementGroupList;
		for( int ii=0; ii<dList.size(); ii++ )
		{
			Object obj = dList.get(ii);
			if( obj instanceof SGElementGroupErrorBar )
			{
				list.add(obj);
			}
		}
		return list;
	}


	/**
	 * 
	 */
	public ArrayList getTickLabelGroups()
	{
		ArrayList list = new ArrayList();
		ArrayList dList = this.mDrawingElementGroupList;
		for( int ii=0; ii<dList.size(); ii++ )
		{
			Object obj = dList.get(ii);
			if( obj instanceof SGElementGroupTickLabel )
			{
				list.add(obj);
			}
		}
		return list;
	}


	/**
	 * 
	 */
	public ArrayList getArrowGroups()
	{
		ArrayList list = new ArrayList();
		ArrayList dList = this.mDrawingElementGroupList;
		for( int ii=0; ii<dList.size(); ii++ )
		{
			Object obj = dList.get(ii);
			if( obj instanceof SGElementGroupArrow )
			{
				list.add(obj);
			}
		}
		return list;
	}


	/**
	 * 
	 * @return
	 */
	public SGElementGroupLine getLineGroup()
	{
		ArrayList list = this.getLineGroups();
		if( list.size()!=0 )
		{
			return (SGElementGroupLine)list.get(0);
		}
		return null;
	}


	/**
	 * 
	 * @return
	 */
	public SGElementGroupSymbol getSymbolGroup()
	{
		ArrayList list = this.getSymbolGroups();
		if( list.size()!=0 )
		{
			return (SGElementGroupSymbol)list.get(0);
		}
		return null;
	}


	/**
	 * 
	 * @return
	 */
	public SGElementGroupBar getBarGroup()
	{
		ArrayList list = this.getBarGroups();
		if( list.size()!=0 )
		{
			return (SGElementGroupBar)list.get(0);
		}
		return null;
	}


	/**
	 * 
	 * @return
	 */
	public SGElementGroupErrorBar getErrorBarGroup()
	{
		ArrayList list = this.getErrorBarGroups();
		if( list.size()!=0 )
		{
			return (SGElementGroupErrorBar)list.get(0);
		}
		return null;
	}


	/**
	 * 
	 * @return
	 */
	public SGElementGroupTickLabel getTickLabelGroup()
	{
		ArrayList list = this.getTickLabelGroups();
		if( list.size()!=0 )
		{
			return (SGElementGroupTickLabel)list.get(0);
		}
		return null;
	}



	/**
	 * 
	 * @return
	 */
	public SGElementGroupArrow getArrowGroup()
	{
		ArrayList list = this.getArrowGroups();
		if( list.size()!=0 )
		{
			return (SGElementGroupArrow)list.get(0);
		}
		return null;
	}



	/**
	 * 
	 */
	public boolean onDrawingElement( final int x, final int y )
	{
		for( int ii=0; ii<this.mDrawingElementGroupList.size(); ii++ )
		{
			SGElementGroup group = (SGElementGroup)this.mDrawingElementGroupList.get(ii);
			SGDrawingElement[] array = group.getDrawingElementArray();
			for( int jj=0; jj<array.length; jj++ )
			{
				if( array[jj].contains(x,y) )
				{
					return true;
				}
			}
		}
		return false;
	}



	/**
	 * 
	 */
	public boolean writeProperty( final Element el )
	{
		el.setAttribute( SGIFigureElement.KEY_DATA_NAME, this.mName );
		el.setAttribute(
			SGIFigureElement.KEY_VISIBLE_IN_LEGEND,
			Boolean.toString( this.mVisibleInLegendFlag )
		);
		return true;
	}

	

	/**
	 * 
	 */
	public SGProperties getProperties()
	{
		ElementGroupSetPropertiesInFigureElement ep = new ElementGroupSetPropertiesInFigureElement();
		if( this.getProperties(ep) == false )
		{
			return null;
		}

		return ep;
	}


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

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

		ElementGroupSetPropertiesInFigureElement ep = (ElementGroupSetPropertiesInFigureElement)p;

		ep.name = new String( this.mName );
		ep.visibleInLegend = this.mVisibleInLegendFlag;

		return true;
	}



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

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

		ElementGroupSetPropertiesInFigureElement ep = (ElementGroupSetPropertiesInFigureElement)p;

		this.setName( ep.name );
		this.setVisibleInLegend( ep.visibleInLegend );

		return true;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isChanged()
	{
		return this.mUndoManager.isChanged();
	}

		
	/**
	 * 
	 */
	public void setChanged( final boolean b )
	{
		this.mUndoManager.setChanged(b);
	}

	public boolean isChangedRoot()
	{
		return this.isChanged();
	}


	//
	private SGUndoManager mUndoManager = new SGUndoManager(this);


	/**
	 * 
	 * @return
	 */
	public SGProperties getMemento()
	{
		return this.getWholeProperties();
	}


	/**
	 * 
	 * @param p
	 * @return
	 */
	public boolean setMemento( SGProperties p )
	{
		return this.setWholeProperties(p);
	}


	/**
	 * 
	 * @return
	 */
	public boolean isUndoable()
	{
		return this.mUndoManager.isUndoable();
	}

	
	/**
	 * 
	 * @return
	 */
	public boolean isRedoable()
	{
		return this.mUndoManager.isRedoable();
	}


	/**
	 * 
	 */
	public boolean setMementoBackward()
	{
		return this.mUndoManager.setMementoBackward();
	}


	/**
	 * 
	 */
	public boolean setMementoForward()
	{
		return this.mUndoManager.setMementoForward();
	}



	/**
	 * 
	 */
	public boolean undo()
	{
		return this.setMementoBackward();
	}

	
	
	/**
	 * 
	 */
	public boolean redo()
	{
		return this.setMementoForward();
	}


	/**
	 * 
	 */
	public boolean updateHistory()
	{
		return this.mUndoManager.updateHistory();
	}


	/**
	 * 
	 */
	public void initUndoBuffer()
	{
		this.mUndoManager.initUndoBuffer();
	}


	/**
	 * 
	 */
	public boolean initPropertiesHistory()
	{
		return this.mUndoManager.initPropertiesHistory();
	}



	/**
	 * 
	 */
	public static class ElementGroupSetPropertiesInFigureElement
		extends ElementGroupSetProperties
	{

		// name of data
		String name;

		// visible in legend
		boolean visibleInLegend;


		int xAxis;
		int yAxis;
		int zAxis;


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



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

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

			if( super.equals(obj) == false ) return false;

			ElementGroupSetPropertiesInFigureElement p = (ElementGroupSetPropertiesInFigureElement)obj;

			if( p.name.equals(this.name) == false ) return false;
			if( p.visibleInLegend!=this.visibleInLegend ) return false;
			if( p.xAxis!=this.xAxis ) return false;
			if( p.yAxis!=this.yAxis ) return false;
			if( p.zAxis!=this.zAxis ) return false;

			return true;

		}


		/**
		 * 
		 */
		public String toString()
		{
			String str = new String("[");
			str += super.toString();
			str += new String("name=" + this.name + ", ");
			str += new String("visibleInLegend=" + this.visibleInLegend + ", ");
			str += new String("]");

			return str;
		}
		
	}


	/**
	 * 
	 */
	public static class ElementGroupSetInVXYGraphProperties
		extends ElementGroupSetPropertiesInFigureElement
	{
		protected float mMagnitudeScalingFactor;
		protected boolean mDirectionInvariant;
		
		ElementGroupSetInVXYGraphProperties()
		{
			super();
		}
		
		/**
		 * 
		 */
		public boolean equals( final Object obj )
		{
			if( ( obj instanceof ElementGroupSetInVXYGraphProperties ) == false )
			{
				return false;
			}

			if( super.equals(obj) == false ) return false;

			ElementGroupSetInVXYGraphProperties p = (ElementGroupSetInVXYGraphProperties)obj;

			if( p.mMagnitudeScalingFactor!=this.mMagnitudeScalingFactor ) return false;
			if( p.mDirectionInvariant!=this.mDirectionInvariant ) return false;

			return true;

		}

	}

}

