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

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

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

import jp.sourceforge.orangesignal.ta.candle.TrendType;
import jp.sourceforge.orangesignal.ta.result.Step;


/**
 * 非時系列価格分析データからトレンド情報を処理するトレンドプロセッサーの基底クラスを提供します。
 * 
 * @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 {@link #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);

}
