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


/**
 * 2次元ベクトル型データのグラフのクラス
 */
public class SGVXYGraphElement extends SGGraphElement
{

	/**
	 *
	 */
	protected final int ARROW_GRAPH = 0;


	/**
	 * コンストラクタ
	 */
	public SGVXYGraphElement()
	{
		super();
	}



	/**
	 *
	 */
	public boolean addData( final SGData data )
	{
		// データのチェック
		if( !(data instanceof SGVXYData) )
		{
			return false;
		}
		SGVXYData dataVXY = (SGVXYData)data;


		// リストに追加
		mDataList.add(data);


		// get axes list
		final SGAxis bAxis = mAxisElement.getAxisInPlane( SGAxisElement.AXIS_HORIZONTAL_1 );
		final SGAxis tAxis = mAxisElement.getAxisInPlane( SGAxisElement.AXIS_HORIZONTAL_2 );
		final SGAxis lAxis = mAxisElement.getAxisInPlane( SGAxisElement.AXIS_PERPENDICULAR_1 );
		final SGAxis rAxis = mAxisElement.getAxisInPlane( SGAxisElement.AXIS_PERPENDICULAR_2 );
		SGAxis axisX = null;
		SGAxis axisY = null;
		if( SGDefaultValues.SCALE_REFERENCE.equals("Left-Bottom") )
		{
			axisX = bAxis;
			axisY = lAxis;
		}
		else if( SGDefaultValues.SCALE_REFERENCE.equals("Left-Top") )
		{
			axisX = tAxis;
			axisY = lAxis;
		}
		else if( SGDefaultValues.SCALE_REFERENCE.equals("Right-Bottom") )
		{
			axisX = bAxis;
			axisY = rAxis;
		}
		else if( SGDefaultValues.SCALE_REFERENCE.equals("Right-Top") )
		{
			axisX = tAxis;
			axisY = rAxis;
		}
		else
		{
			return false;
		}



		//
		// 新規データを作成
		//

		ElementGroupSetInVXYGraph groupSet = new ElementGroupSetInVXYGraph();

		// 名前
		String name = "data"+(this.mGroupSetList.size()+1);
		groupSet.setName(name);

		// 軸
		groupSet.setXAxis(axisX);
		groupSet.setYAxis(axisY);

		// 倍率
		groupSet.setMagnification( this.mMagnification );


		// リストに追加
		this.mGroupSetList.add( groupSet );



		//
		// 新規描画要素の作成
		// デフォルトでは線分の描画要素を作成
		//

		groupSet.addDrawingElementGroup( ARROW_GRAPH );


		repaint();

		return true;
	}




	/**
	 * 
	 */
	public boolean synchronizeToLegendElement( final SGILegendElement lElement )
	{

		boolean flag = super.synchronizeToLegendElement(lElement);
		if( !flag )
		{
			return flag;
		}


		for( int ii=0; ii<mDataList.size(); ii++ )
		{
			ElementGroupSetInVXYGraph groupSet
				= (ElementGroupSetInVXYGraph)this.mGroupSetList.get(ii);
			ArrayList groupList = groupSet.mDrawingElementGroupList;
			groupList.clear();

			SGData data = (SGData)mDataList.get(ii);

			// name of the data
			String name = lElement.getDataName(data);
			groupSet.setName(name);

			// properties of the data
			ArrayList dElementList = lElement.getDrawingElementList(data);
			for( int jj=0; jj<dElementList.size(); jj++ )
			{
				SGDrawingElement dElement = (SGDrawingElement)dElementList.get(jj);
				groupSet.addDrawingElementGroup(dElement);
			}

		}

		this.createAllDrawingElements();


		return flag;
	}



	/**
	 * プロパティダイアログの作成
	 */
	protected boolean createDataDialog()
	{
		return true;
	}




	/**
	 * 
	 */
	public boolean createAllDrawingElements()
	{

		for( int ii=0; ii<this.mGroupSetList.size(); ii++ )
		{
			ElementGroupSetInGraph groupSet = (ElementGroupSetInGraph)this.mGroupSetList.get(ii);

			SGVXYData dataVXY = (SGVXYData)this.mDataList.get(ii);

			ArrayList startRatioList = new ArrayList();
			ArrayList endRatioList = new ArrayList();
			calcLocationOfVXYData(
				dataVXY.getStartArray(), dataVXY.getEndArray(),
				groupSet.mXAxis,groupSet.mYAxis,startRatioList,endRatioList);

			ArrayList groupList = groupSet.mDrawingElementGroupList;
		
			for( int jj=0; jj<groupList.size(); jj++ )
			{
				SGElementGroupVXY group = (SGElementGroupVXY)groupList.get(jj);

				// グループに描画要素を作成させる
				group.createDrawingElement( startRatioList, endRatioList );
			}
		}


		// タイミング要素
		for( int ii=0; ii<this.mTimingElementGroupSetList.size(); ii++ )
		{
			TimingElementGroupSetInGraph groupSet
				= (TimingElementGroupSetInGraph)this.mTimingElementGroupSetList.get(ii);
			this.createTimingElements( groupSet );
		}


		return true;
	}



	/**
	 * 
	 */
	public void paintGraphics2D( final Graphics2D g2d )
	{

		super.paintGraphics2D(g2d);


		// 描画領域のクリッピング
		this.clipGraphArea(g2d);


		// グラフの描画
		for( int ii=0; ii<this.mGroupSetList.size(); ii++ )
		{
			ElementGroupSetInVXYGraph groupSet = (ElementGroupSetInVXYGraph)this.mGroupSetList.get(ii);

			ArrayList groupList = groupSet.mDrawingElementGroupList;

			for( int jj=0; jj<groupList.size(); jj++ )
			{
				SGElementGroup group = (SGElementGroup)groupList.get(jj);
				group.paintElement( g2d );
			}

		}


		// タイミング線の描画
		this.drawTimingElements(g2d);

	}




	/**
	 * 
	 */
	public boolean createDataObject( final BufferedReader br, final SGData data ) throws IOException
	{

		if( !(data instanceof SGVXYData) )
		{
			return false;
		}


		super.createDataObject( br, data );


		String line = null;


		// name of data
		if( (line = br.readLine() ) == null )
		{
			return false;
		}
System.out.println(line);
		if( line.startsWith("name ") )
		{
			line = line.substring("name ".length());
		}
		else
		{
			return false;
		}
		String name = line;


		// configuration of X-axis
		if( (line = br.readLine() ) == null )
		{
			return false;
		}
System.out.println(line);
		if( line.startsWith("configX ") )
		{
			line = line.substring("configX ".length());
		}
		else
		{
			return false;
		}
		int configX = Integer.valueOf(line).intValue();


		// configuration of Y-axis
		if( (line = br.readLine() ) == null )
		{
			return false;
		}
System.out.println(line);
		if( line.startsWith("configY ") )
		{
			line = line.substring("configY ".length());
		}
		else
		{
			return false;
		}
		int configY = Integer.valueOf(line).intValue();


		// construct a SGElementGroupSet object
		ElementGroupSetInVXYGraph groupSet = new ElementGroupSetInVXYGraph();


		// set the name
//		String name = "data"+(this.mGroupSetList.size()+1);
		groupSet.setName(name);


		//
		this.mGroupSetList.add( groupSet );



		// set x- and y-axis
		groupSet.mXAxis = this.mAxisElement.getAxisInCube( configX );
		groupSet.mYAxis = this.mAxisElement.getAxisInCube( configY );


//System.out.println(groupSet.mXAxis);
//System.out.println(groupSet.mYAxis);



		//
		while( true )
		{

			SGElementGroup group = null;
	
			if( (line = br.readLine() ) == null )
			{
				return false;
			}
System.out.println(line);
			if( line.equals("<SGElementGroupArrow>") )
			{
				group = new ElementGroupArrow();
			}
			else if( line.equals("data end") )
			{
				break;
			}
			else
			{
				return false;
			}

			group.mGroupSet = groupSet;
			group.readProperty(br);
			groupSet.mDrawingElementGroupList.add( group );
			group.setMagnification( this.mMagnification );

		}


		return true;
	}




	/**
	 * 
	 */
	class ElementGroupSetInVXYGraph extends ElementGroupSetInGraph
	{

		/**
		 * 
		 */
		protected ElementGroupSetInVXYGraph()
		{
			super();
		}


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


		/**
		 * 
		 */
		public boolean addDrawingElementGroup( final int type )
		{

			SGElementGroupVXY group = null;
			if( type == ARROW_GRAPH )
			{
				group = new ElementGroupArrow();
			}
			else
			{
				throw new Error("");
			}

			group.setMagnification(this.mMagnification);

			this.addDrawingElementGroup(group);

			return true;
		}



		/**
		 * 
		 */
		public boolean addDrawingElementGroup( final SGDrawingElement element )
		{

			SGElementGroupVXY group = null;
			if( element instanceof SGDrawingElementArrow )
			{
				group = new ElementGroupArrow();
			}
			else
			{
				throw new Error("");
			}

			group.setProperty( element );
			group.setMagnification(this.mMagnification);

			this.addDrawingElementGroup(group);

			return true;
		}



		/**
		 * 
		 */
		private boolean addDrawingElementGroup( final SGElementGroupVXY group )
		{

			group.mGroupSet = this;

			// get the list of positions of datas
			ArrayList startRatioList = new ArrayList();
			ArrayList endRatioList = new ArrayList();
			calcLocationOfVXYData(
				((SGVXYData)getData(this)).getStartArray(),
				((SGVXYData)getData(this)).getEndArray(),
				this.mXAxis,
				this.mYAxis,
				startRatioList,
				endRatioList
			);

			// 描画要素の作成
			group.createDrawingElement(startRatioList,endRatioList);


			// 倍率
			group.setMagnification( mMagnification );


			// グループをデータのリストに追加
			this.mDrawingElementGroupList.add( group );


			return true;
		}


		/**
		 * 
		 */
		public void paintGraphics2D( final Graphics2D g2d )
		{
			
		}



		/**
		 * 
		 */
		public boolean createTemporaryPropertyObject()
		{
			return true;
		}



		/**
		 * 
		 */
		protected boolean clickDrawingElements( final MouseEvent e )
		{
			return false;
		}



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

			super.writePropertyOfData(writer);


			// 軸の配置の出力
			int configX = mAxisElement.getConfigurationInCube( this.mXAxis );
			int configY = mAxisElement.getConfigurationInCube( this.mYAxis );
			
			writer.write("configX "+configX+"\n" );
			writer.write("configY "+configY+"\n" );


			// 各データが持つ描画要素群にプロパティを出力させる
			for( int ii=0; ii<this.mDrawingElementGroupList.size(); ii++ )
			{
				SGElementGroup group = (SGElementGroup)this.mDrawingElementGroupList.get(ii);
				group.writePropertyOfData(writer);
			}


			return true;
		}


	}


	/**
	 *
	 */
	class ElementGroupArrow extends SGElementGroupArrow
	{

		/**
		 *
		 */
		protected ElementGroupArrow()
		{
			super();
		}



		/**
		 * 
		 */
		protected boolean setDialogProperty()
		{
			super.setDialogProperty();

			return true;
		}



		/**
		 * 
		 */
		public void actionPerformed(final ActionEvent e)
		{
			super.actionPerformed(e);
		}

	}






}
