/*
 * Copyright (c) 2008-2009 OrangeSignal.com All rights reserved.
 * 
 * これは Apache ライセンス Version 2.0 (以下、このライセンスと記述) に
 * 従っています。このライセンスに準拠する場合以外、このファイルを使用
 * してはなりません。このライセンスのコピーは以下から入手できます。
 * 
 * http://www.apache.org/licenses/LICENSE-2.0.txt
 * 
 * 適用可能な法律がある、あるいは文書によって明記されている場合を除き、
 * このライセンスの下で配布されているソフトウェアは、明示的であるか暗黙の
 * うちであるかを問わず、「保証やあらゆる種類の条件を含んでおらず」、
 * 「あるがまま」の状態で提供されるものとします。
 * このライセンスが適用される特定の許諾と制限については、このライセンス
 * を参照してください。
 */

package jp.sf.orangesignal.ta.candle.generator;

import java.util.Date;
import java.util.List;

import jp.sf.orangesignal.ta.Step;
import jp.sf.orangesignal.ta.candle.TrendType;

/**
 * 非時系列価格分析データからトレンド情報を処理するトレンドプロセッサーの基底クラスを提供します。
 * 
 * @author 杉澤 浩二
 */
public abstract class StepTrendProcessor implements TrendProcessor {

	/**
	 * 非時系列価格分析データ
	 */
	private final List<Step> data;

	/**
	 * コンストラクタです。
	 * 
	 * @param data 非時系列価格分析データ
	 */
	public StepTrendProcessor(final List<Step> data) {
		this.data = data;
	}

	/**
	 * この実装は非時系列価格分析データ毎に {@link #getTrend(Step)} を呼出し、
	 * 得られたトレンドを非時系列価格分析データの該当日時範囲のローソク足へ設定します。
	 * 
	 * @throws TrendProcessorException ローソク足の日時に <code>null</code> がある場合
	 * @see #getTrend(Step)
	 */
	@Override
	public final void execute(final DefaultCandlestick[] c) throws TrendProcessorException {
		final int len = c.length;	// ローソクの数
		int start = 0;				// ローソク参照開始インデックス

		for (final Step step : data) {
			final TrendType trend = getTrend(step);

			// 該当期間内のローソクへトレンドを設定します。
			for (int i = start; i < len; i++) {
				if (c[i] == null)
					continue;

				final Date date = c[i].getDate();
				if (date == null)
					throw new TrendProcessorException();

				if (step.openDate.compareTo(date) <= 0 && step.closeDate.compareTo(date) >= 0) {
					c[i].trend = trend;
				} else {
					start = i;
					break;
				}
			}
		}
	}

	/**
	 * 非時系列データセット用の値幅情報からトレンドの種類を返します。
	 * 
	 * @param step 非時系列データセット用の値幅情報
	 * @return トレンドの種類
	 */
	protected abstract TrendType getTrend(Step step);

}
