
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.SGIGraphElement;
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 org.w3c.dom.Element;



/**
 * The class for the set of drawing elements group used in this package.
 */
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 boolean setName( final String name )
	{
		this.mName = new String( name );
		return true;
	}


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

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


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



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


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


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



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


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

		
	/**
	 * 
	 */
	public SGAxis getZAxis()
	{
		return 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;
	}



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


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


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


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


	/**
	 * 
	 * @return
	 */
	public SGElementGroupTickLabel getTickLabelGroup()
	{
		ArrayList list = this.getTickLabelGroups();
		if( list.size()!=0 )
		{
			return (SGElementGroupTickLabel)list.get(0);
		}
		else
		{
			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.mDrawingElementArray;
			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( SGIGraphElement.KEY_DATA_NAME, this.mName );
		el.setAttribute(
			SGIGraphElement.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.mName = new String( ep.name );
		this.mVisibleInLegendFlag = ep.visibleInLegend;

		return true;
	}



	/**
	 * 
	 */
	protected boolean mChangedFlag = false;


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

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



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


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


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


//	/**
//	 * 
//	 * @return
//	 */
//	protected ArrayList mElementGroupSetPropertyHistoryList = new ArrayList();
//
//
//	/**
//	 * 
//	 * @return
//	 */
//	protected int mElementGroupSetStateCounter = 0;
//
//
//	/**
//	 * 現在、状態が履歴のどの位置にあるのかを示すカウンタ
//	 */
//	private int mCurrentStateCounter = 0;
//
//
//	/**
//	 * アンドゥ対象オブジェクトの履歴リスト
//	 */
//	protected ArrayList mUndoableObjectHistoryList = new ArrayList();


	/**
	 * アンドゥを行う
	 */
	public boolean undo()
	{
		return this.mUndoManager.undo();

//		this.mElementGroupSetStateCounter--;
//
//		WholeProperties p
//			= (WholeProperties)this.mElementGroupSetPropertyHistoryList.get(
//				this.mElementGroupSetStateCounter);
//
//		this.setWholeProperties(p);
//
//		return true;
	}


	/**
	 * リドゥを行う
	 */
	public boolean redo()
	{
		return this.mUndoManager.redo();

//		this.mElementGroupSetStateCounter++;
//
//		WholeProperties p
//			= (WholeProperties)this.mElementGroupSetPropertyHistoryList.get(
//				this.mElementGroupSetStateCounter);
//
//		this.setWholeProperties(p);
//
//		return true;
	}



	/**
	 * アンドゥ操作を依頼する
	 */
	public boolean onUndo()
	{
		return this.undo();
	}

	
	
	/**
	 * リドゥ操作を依頼する
	 */
	public boolean onRedo()
	{
		return this.redo();
	}


//	/**
//	 * オブジェクトの履歴を更新する
//	 * @return
//	 */
//	public boolean updateObjectHistory( final SGIUndoable obj )
//	{
//		return this.mUndoManager.updateObjectHistory(obj);
//
////		ArrayList objList = new ArrayList();
////		objList.add(obj);
////		boolean flag = this.updateObjectHistory(objList);
////		if( !flag )
////		{
////			return false;
////		}
////
////		return true;
//	}



//	/**
//	 * オブジェクトの履歴を更新する
//	 */
//	public boolean updateObjectHistory( final ArrayList objList )
//	{
//		return this.mUndoManager.updateObjectHistory(objList);
//
////		ArrayList list = new ArrayList();
////		for( int ii=0; ii<this.mCurrentStateCounter; ii++ )
////		{
////			Object obj = this.mUndoableObjectHistoryList.get(ii);
////			list.add(obj);
////		}
////		list.add( new ArrayList(objList) );
////
////		this.mUndoableObjectHistoryList = list;
////		this.mCurrentStateCounter++;
////
////		return true;
//	}



	/**
	 * 履歴の更新の実行。アンドゥ対象の操作が行われたときに、真っ先に呼ばれる。
	 */
	public boolean updateHistory()
	{
		if( this.mChangedFlag )
		{
			this.mUndoManager.updateThisObjectHistory();
			this.setChanged(false);
			this.mUndoManager.updateObjectHistory( this );
		}

		return true;
	}



//	/**
//	 * 
//	 */
//	public boolean updateThisObjectHistory()
//	{
//		return this.mUndoManager.updateHistory();
//
////		// フィギュアのプロパティ履歴を更新
////		this.mElementGroupSetStateCounter++;
////		this.addElementGroupSetPropertyHistory( (WholeProperties)this.getWholeProperties() );
////
////		return true;
//	}



//	/**
//	 * 
//	 * @return
//	 */
//	protected boolean addElementGroupSetPropertyHistory( WholeProperties p )
//	{
//		ArrayList list = new ArrayList();
//		for( int ii=0; ii<this.mElementGroupSetStateCounter; ii++ )
//		{
//			list.add( this.mElementGroupSetPropertyHistoryList.get(ii) );
//		}
//		list.add(p);
//
//		this.mElementGroupSetPropertyHistoryList = list;
//
//		return true;
//	}



	/**
	 * 
	 */
	public boolean initPropertiesHistory()
	{
		return this.mUndoManager.initPropertiesHistory();
		
//		this.addElementGroupSetPropertyHistory( (WholeProperties)this.getWholeProperties() );
//		return true;
	}


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

		// name of data
		String name;

		// visible in legend
		boolean visibleInLegend;


		/**
		 * 
		 *
		 */
		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;

			return true;

		}


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

			return str;
		}
		
	}


}

