/*
 * Copyright (c) 2006-2009 OrangeSignal.com All rights reserved.
 */

package jp.sourceforge.orangesignal.ta;

/**
 * プリミティブ型配列の価格データや出来高データを、テクニカル分析用データやローソク足分析用データなどへ変換するユーティリティクラスを提供します。
 * 
 * @author 杉澤 浩二
 */
public final class ArrayDataConverter {

	/**
	 * インスタンス化できない事を強制します。
	 */
	private ArrayDataConverter() {}

	/**
	 * <p>指定されたプリミティブ型配列の価格データをローソク足分析用データへ変換して返します。</p>
	 * このメソッドでは値が <code>0</code> の物を <code>null</code> として変換します。
	 * 
	 * @param price 価格データ
	 * @return ローソク足分析用データ
	 */
	public static Number[] toPrice(final int[] price) {
		final int length = price.length;
		final Number[] results = new Number[length];
		for (int i = 0; i < length; i++) {
			if (price[i] != 0)
				results[i] = price[i];
		}
		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の価格データをローソク足分析用データへ変換して返します。</p>
	 * このメソッドでは値が <code>0</code> の物を <code>null</code> として変換します。
	 * 
	 * @param price 価格データ
	 * @return ローソク足分析用データ
	 */
	public static Number[] toPrice(final long[] price) {
		final int length = price.length;
		final Number[] results = new Number[length];
		for (int i = 0; i < length; i++) {
			if (price[i] != 0)
				results[i] = price[i];
		}
		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の価格データをローソク足分析用データへ変換して返します。</p>
	 * このメソッドでは値が <code>0</code> の物を <code>null</code> として変換します。
	 * 
	 * @param price 価格データ
	 * @return ローソク足分析用データ
	 */
	public static Number[] toPrice(final float[] price) {
		final int length = price.length;
		final Number[] results = new Number[length];
		for (int i = 0; i < length; i++) {
			if (price[i] != 0)
				results[i] = price[i];
		}
		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の価格データをローソク足分析用データへ変換して返します。</p>
	 * このメソッドでは値が <code>0</code> の物を <code>null</code> として変換します。
	 * 
	 * @param price 価格データ
	 * @return ローソク足分析用データ
	 */
	public static Number[] toPrice(final double[] price) {
		final int length = price.length;
		final Number[] results = new Number[length];
		for (int i = 0; i < length; i++) {
			if (price[i] != 0)
				results[i] = price[i];
		}
		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の価格データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>0</code> の物を一つ前の値で置き換えて変換します。
	 * 
	 * @param price 価格データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalPrice(final int[] price) {
		final int length = price.length;
		final Number[] results = new Number[length];

		Number last = null;
		for (int i = 0; i < length; i++) {
			if (price[i] != 0)
				last = price[i];
			results[i] = last;
		}

		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の価格データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>0</code> の物を一つ前の値で置き換えて変換します。
	 * 
	 * @param price 価格データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalPrice(final long[] price) {
		final int length = price.length;
		final Number[] results = new Number[length];

		Number last = null;
		for (int i = 0; i < length; i++) {
			if (price[i] != 0L)
				last = price[i];
			results[i] = last;
		}

		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の価格データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>0</code> の物を一つ前の値で置き換えて変換します。
	 * 
	 * @param price 価格データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalPrice(final float[] price) {
		final int length = price.length;
		final Number[] results = new Number[length];

		Number last = null;
		for (int i = 0; i < length; i++) {
			if (price[i] != 0F)
				last = price[i];
			results[i] = last;
		}

		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の価格データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>0</code> の物を一つ前の値で置き換えて変換します。
	 * 
	 * @param price 価格データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalPrice(final double[] price) {
		final int length = price.length;
		final Number[] results = new Number[length];

		Number last = null;
		for (int i = 0; i < length; i++) {
			if (price[i] != 0D)
				last = price[i];
			results[i] = last;
		}

		return results;
	}

	/**
	 * <p>指定された配列の価格データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>null</code> の物を一つ前の値で置き換えて変換します。
	 * 
	 * @param price 価格データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalPrice(final Number[] price) {
		return toTechnicalPrice(price, 0, price.length);
	}

	/**
	 * <p>指定された配列の価格データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>null</code> の物を一つ前の値で置き換えて変換します。
	 * 
	 * @param price 価格データ
	 * @param start 開始位置
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalPrice(final Number[] price, final int start) {
		return toTechnicalPrice(price, start, price.length);
	}

	/**
	 * <p>指定された配列の価格データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>null</code> の物を一つ前の値で置き換えて変換します。
	 * 
	 * @param price 価格データ
	 * @param start 開始位置
	 * @param end 終了位置
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalPrice(final Number[] price, final int start, final int end) {
		final int _start = Math.max(start, 0);
		final int _end = Math.min(Math.max(end, 0), price.length);
		final Number[] results = new Number[_end - _start];
		Number last = null;
		for (int i = _start; i < _end; i++) {
			if (price[i] != null)
				last = price[i].doubleValue();
			results[i] = last;
		}
		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の出来高データをテクニカル指標計算用データへ変換して返します。</p>
	 * 
	 * @param volume 出来高データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalVolume(final int[] volume) {
		final int length = volume.length;
		final Number[] results = new Number[length];
		for (int i = 0; i < length; i++)
			results[i] = volume[i];
		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の出来高データをテクニカル指標計算用データへ変換して返します。</p>
	 * 
	 * @param volume 出来高データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalVolume(final long[] volume) {
		final int length = volume.length;
		final Number[] results = new Number[length];
		for (int i = 0; i < length; i++)
			results[i] = volume[i];
		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の出来高データをテクニカル指標計算用データへ変換して返します。</p>
	 * 
	 * @param volume 出来高データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalVolume(final float[] volume) {
		final int length = volume.length;
		final Number[] results = new Number[length];
		for (int i = 0; i < length; i++)
			results[i] = volume[i];
		return results;
	}

	/**
	 * <p>指定されたプリミティブ型配列の出来高データをテクニカル指標計算用データへ変換して返します。</p>
	 * 
	 * @param volume 出来高データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalVolume(final double[] volume) {
		final int length = volume.length;
		final Number[] results = new Number[length];
		for (int i = 0; i < length; i++)
			results[i] = volume[i];
		return results;
	}

	/**
	 * <p>指定された数値配列の出来高データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>null</code> の物を <code>0</code> として変換します。
	 * 
	 * @param volume 出来高データ
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalVolume(final Number[] volume) {
		return toTechnicalVolume(volume, 0, volume.length);
	}

	/**
	 * <p>指定された数値配列の出来高データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>null</code> の物を <code>0</code> として変換します。
	 * 
	 * @param volume 出来高データ
	 * @param start 開始位置
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalVolume(final Number[] volume, final int start) {
		return toTechnicalVolume(volume, start, volume.length);
	}

	/**
	 * <p>指定された配列の出来高データをテクニカル指標計算用データへ変換して返します。</p>
	 * このメソッドでは値が <code>null</code> の物を <code>0</code> として変換します。
	 * 
	 * @param volume 出来高データ
	 * @param start 開始位置
	 * @param end 終了位置
	 * @return テクニカル指標計算用データ
	 */
	public static Number[] toTechnicalVolume(final Number[] volume, final int start, final int end) {
		final int _start = Math.max(start, 0);
		final int _end = Math.min(Math.max(end, 0), volume.length);
		final Number[] results = new Number[_end - _start];
		for (int i = _start; i < _end; i++) {
			if (volume[i] == null)
				results[i] = 0;
			else
				results[i] = volume[i].doubleValue();
		}
		return results;
	}

}
