
package jp.riken.brain.ni.samuraigraph.data;

import jp.riken.brain.ni.samuraigraph.base.SGData;


/**
 * (x,y)-type data.
 */

public class SGSXYData extends SGData implements SGITwoDimensionalData, Cloneable
{

	/**
	 * Array of x values.
	 */
	private double[] mXValueArray = null;


	/**
	 * Array of y values.
	 */
	private double[] mYValueArray = null;


	/**
	 * Array of lower error values.
	 */
	private double[] mLowerErrorArray = null;


	/**
	 * Array of upper error values.
	 */
	private double[] mUpperErrorArray = null;


	/**
	 * Array of strings.
	 */
	private String[] mStringArray = null;


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


	/**
	 * 
	 * @param xValueArray
	 * @param yValueArray
	 * @param stringArray
	 */
	public SGSXYData(
		double[] xValueArray,
		double[] yValueArray,
		String[] stringArray )
	{
		this( xValueArray, yValueArray, null, null, stringArray );
	}


	/**
	 * 
	 * @param xValueArray
	 * @param yValueArray
	 */
	public SGSXYData(
		final double[] xValueArray,
		final double[] yValueArray )
	{
		this( xValueArray, yValueArray, null, null, null );
	}


	/**
	 * 
	 * @param xValueArray
	 * @param yValueArray
	 * @param lowerErrorArray
	 * @param upperErrorArray
	 * @param stringArray
	 */
	public SGSXYData(
		double[] xValueArray,
		double[] yValueArray,
		double[] lowerErrorArray,
		double[] upperErrorArray,
		String[] stringArray )
	{
		super();

		if( xValueArray==null || yValueArray==null )
		{
			throw new IllegalArgumentException("xValueArray==null || yValueArray==null");
		}

		if( xValueArray.length!=yValueArray.length )
		{
			throw new IllegalArgumentException("xValueArray.length!=yValueArray.length");
		}

		// set x and y values
		this.mXValueArray = (double[])xValueArray.clone();
		this.mYValueArray = (double[])yValueArray.clone();

		if( lowerErrorArray!=null && upperErrorArray!=null )
		{
			if( lowerErrorArray.length!=xValueArray.length )
			{
				throw new IllegalArgumentException("lowerErrorArray.length!=xValueArray.length");
			}

			if( upperErrorArray.length!=xValueArray.length )
			{
				throw new IllegalArgumentException("upperErrorArray.length!=xValueArray.length");
			}

			// set error values
			this.mLowerErrorArray = (double[])lowerErrorArray.clone();
			this.mUpperErrorArray = (double[])upperErrorArray.clone();
		}

		if( stringArray!=null )
		{
			if( stringArray.length!=xValueArray.length )
			{
				throw new IllegalArgumentException("stringArray.length!=xValueArray.length");
			}

			// set strings
			this.mStringArray = (String[])stringArray.clone();
		}

	}



	/**
	 * 
	 * @return
	 */
	public SGSXYData( final SGData data )
	{
		super();
		this.setData( data );
	}


	/**
	 * 
	 */
	public boolean setData( final SGData data )
	{
		if( !(data instanceof SGSXYData) )
		{
			return false;
		}
		
		SGSXYData data_ = (SGSXYData)data;
		this.mXValueArray = data_.mXValueArray;
		this.mYValueArray = data_.mYValueArray;
		this.mLowerErrorArray = data_.mLowerErrorArray;
		this.mUpperErrorArray = data_.mUpperErrorArray;
		this.mStringArray = data_.mStringArray;

		return true;
	}


	/**
	 * 
	 * @return
	 */
	public int getPointsNumber()
	{
		return this.mXValueArray.length;
	}


	/**
	 * 
	 * @return
	 */
	public double getMinValueX()
	{
		double min = Double.MAX_VALUE;
		final int len = this.getPointsNumber();

		for( int ii=0; ii<len; ii++ )
		{
			double x = this.mXValueArray[ii];
			if( x < min )
			{
				min = x;
			}
		}

		return min;
	}


	/**
	 * 
	 * @return
	 */
	public double getMaxValueX()
	{
		double max = - Double.MAX_VALUE;
		final int len = this.getPointsNumber();

		for( int ii=0; ii<len; ii++ )
		{
			double x = mXValueArray[ii];
			if( x > max )
			{
				max = x;
			}
		}

		return max;
	}


	/**
	 * 
	 * @return
	 */
	public double getMinValueY()
	{
		double min = Double.MAX_VALUE;
		final int len = this.getPointsNumber();

		for( int ii=0; ii<len; ii++ )
		{
			double y = mYValueArray[ii];
			if( y < min )
			{
				min = y;
			}
		}

		return min;
	}


	/**
	 * 
	 * @return
	 */
	public double getMaxValueY()
	{
		double max = - Double.MAX_VALUE;
		final int len = this.getPointsNumber();

		for( int ii=0; ii<len; ii++ )
		{
			double y = mYValueArray[ii];
			if( y > max )
			{
				max = y;
			}
		}

		return max;
	}



	/**
	 * 
	 */
	public Double getXValue( final int n )
	{
		return new Double( this.mXValueArray[n] );
	}


	/**
	 * 
	 * @param n
	 * @return
	 */
	public Double getYValue( final int n )
	{
		return new Double( this.mYValueArray[n] );
	}


	/**
	 * 
	 * @param n
	 * @return
	 */
	public Double getLowerErrorValue( final int n )
	{
		if( this.isErrorValueHolding() )
		{
			return new Double( this.mLowerErrorArray[n] );
		}
		else
		{
			return null;
		}
	}


	/**
	 * 
	 * @param n
	 * @return
	 */
	public Double getUpperErrorValue( final int n )
	{
		if( this.isErrorValueHolding() )
		{
			return new Double( this.mUpperErrorArray[n] );
		}
		else
		{
			return null;
		}
	}



	/**
	 * 
	 * @return
	 */
	public boolean isErrorValueHolding()
	{
		return (this.mLowerErrorArray!=null);
	}



	/**
	 * 
	 * @return
	 */
	public boolean isStringArrayHolding()
	{
		return (this.mStringArray!=null);
	}


	/**
	 * 
	 * @param n
	 * @return
	 */
	public String getString( final int n )
	{
		if( this.isStringArrayHolding() )
		{
			return this.mStringArray[n];
		}
		else
		{
			return null;
		}
	}


	/**
	 * 
	 */
	public Object clone()
	{
		try
		{
			return super.clone();
		}
		catch( CloneNotSupportedException ex )
		{
			// this shouldn't happen, since we are Cloneable
			throw new InternalError();
		}
	}


	/**
	 * Calling the clone method.
	 */
	public Object copy()
	{
		return this.clone();
	}


}

