/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.io;

import java.awt.Color;

/**
 * ValueMarkOverColors は、ChartDataset で設定される ValueMark用の色管理クラスです。
 * JFreeChart の個別属性を管理しているデータ管理クラスです。
 * このクラスは、JFreeChart に特化した、値の判定ロジックのみを提供していますので、
 * パッケージスコープでの提供になります。
 *
 * マーカーラインの値と、超過時のShape色を配列で指定します。
 *
 * マーカーラインを使用する場合に、そのラインを超えない色、超える色を指定します。
 * この色の指定は、マーカーラインの色やマーカーラインの設定値の個数＋１に
 * なります。つまり、色１：設定値１：色２：設定値２：色３ となります。
 * 色１は、設定値１より小さい場合に使用され、色２は、設定値１より大きく、
 * 設定値２より小さい場合、色３は、設定値２より大きい場合になります。
 *
 * Shape色は、java.awt.Color クラスのオブジェクトで指定します。
 * BLACK , BLUE , CYAN , DARK_GRAY , GRAY , GREEN , LIGHT_GRAY ,
 * MAGENTA , ORANGE , PINK , RED , WHITE , YELLOW , (PURPLE) が指定できます。
 * また、#XXXXXX形式の16bitRGB表記 でも指定可能です。
 * values と、あわせて設定する必要があります。
 * どちらかが、指定されていない場合は、エラーになります。
 *
 * @og.rev 4.1.0.1(2008/01/19) ChartDataset クラスから独立
 *
 * @version  0.9.0	2007/06/21
 * @author	 Kazuhiko Hasegawa
 * @since	 JDK1.1,
 */
class ValueMarkOverColors {
	private final double[]	markValues	;		// doubleの配列
	private final Color[]	markOverColors;		// マーカーラインの超過色
	private final Color		markColor;			// 動的マーカーライン色
	private final int		dynamicOCadrs;		// 動的マーカーライン色

	/**
	 * コンストラクター
	 *
	 * マーカーラインの値と、超過時のShape色を配列で指定します。
	 *
	 * マーカーラインを使用する場合に、そのラインを超えない色、超える色を指定します。
	 * この色の指定は、マーカーラインの色やマーカーラインの設定値の個数＋１に
	 * なります。つまり、色１：設定値１：色２：設定値２：色３ となります。
	 * 色１は、設定値１より小さい場合に使用され、色２は、設定値１より大きく、
	 * 設定値２より小さい場合、色３は、設定値２より大きい場合になります。
	 *
	 * Shape色は、java.awt.Color クラスのオブジェクトで指定します。
	 * BLACK , BLUE , CYAN , DARK_GRAY , GRAY , GREEN , LIGHT_GRAY ,
	 * MAGENTA , ORANGE , PINK , RED , WHITE , YELLOW , (PURPLE) が指定できます。
	 * また、#XXXXXX形式の16bitRGB表記 でも指定可能です。
	 * values と、あわせて設定する必要があります。
	 * どちらかが、指定されていない場合は、エラーになります。
	 *
	 * @og.rev 4.1.0.1(2008/01/19) 新規追加
	 *
	 * @param   values double[] マーカーラインの値配列
	 * @param   overColors Color[] マーカーラインの超過時のShape色配列
	 * @param   dynMarkColor Color 動的なマーカーラインを使用時の動的ライン色
	 * @param	dynOCadrs	動的なマーカーラインの基準番号
	 */
	public ValueMarkOverColors( final double[]	values ,
								final Color[]	overColors ,
								final Color		dynMarkColor ,
								final int		dynOCadrs ) {
		markValues		= values;
		markOverColors	= overColors;
		markColor		= dynMarkColor;
		dynamicOCadrs	= dynOCadrs;

		if( markValues == null || markOverColors == null ||
			markValues.length + 1 != overColors.length ||
			markValues.length < 1 ) {

			final String errMsg = "ValueMarkOverColors が構築できません。\n"
						+ " markValues が null か、markOverColors が null か、"
						+ " markValuesの個数＋１が、overColorsの個数に合致しません。" ;
			System.out.println( errMsg );
			throw new RuntimeException( errMsg );
		}
	}

	/**
	 * 動的マーカーラインのライン色を返します。
	 *
	 * 動的マーカーラインのライン色は、ChartDataset クラスの markValues
	 * 属性で、"G"  という文字列を設定されたアドレスが、使用されます。
	 *
	 * @og.rev 4.1.0.1(2008/01/19) 新規追加
	 *
	 * @return	Color 動的マーカーラインのライン色
	 */
	protected Color getDynamicColor() {
		return markColor;
	}

	/**
	 * コンストラクタで指定された設定値配列と比べて、合致するShape色を返します。
	 * 動的なオーバーカラー(useDynamicOverColor)を使用しない場合のメソッドです。
	 *
	 * @og.rev 4.1.0.1(2008/01/19) 新規追加
	 *
	 * @param	value     double マーカーラインと比較する値
	 *
	 * @return	Color 指定の値に対する Shape色
	 */
	protected Color getColor( final double value ) {
		return getColor( value,markValues[0] );
	}

	/**
	 * コンストラクタで指定された設定値配列と比べて、合致するShape色を返します。
	 * 動的なオーバーカラー(useDynamicOverColor)を使用する場合のメソッドです。
	 * ここでは、動的閾値の比較対照を、引数で指定します。
	 *
	 * @og.rev 4.1.1.0 (2008/02/04) 新規追加
	 *
	 * @param	value  double マーカーラインと比較する値
	 * @param	minNum Number 最下位の動的マーカーライン値
	 *
	 * @return	Color 指定の値に対する Shape色
	 */
	protected Color getColor( final double value, final Number minNum ) {
		Color rtnclr = null;

		double minVal = 0.0 ;
		if( minNum != null ) {
			minVal = minNum.doubleValue();
		}
		rtnclr = getColor( value,minVal );

		return rtnclr;
	}

	/**
	 * コンストラクタで指定された設定値配列と比べて、合致するShape色を返します。
	 * 動的なオーバーカラー(useDynamicOverColor)を使用する場合のメソッドです。
	 * ここでは、動的閾値の比較対照を、引数で指定します。
	 *
	 * 内部ロジック説明：
	 *  ・閾値[0]の値と比較して、下の場合は、色[0]を返す。(確定)
	 *  ・閾値[N-1]の値と比較して、上の場合は、色[N]を返す。(確定)
	 *  ・閾値[N-2]の値と比較して、上の場合は、色[N-1]を返す。(確定)
	 *  ・閾値[1]の値と比較して、上の場合は、色[2]を返す。(確定)
	 *  ・閾値[0]の値と比較して、上の場合は、色[1]を返す。(確定)
	 * 閾値のアドレスが、動的オーバーカラー(dynamicOCadrs)の場合は、
	 * 引数の markValue が、動的閾値として、閾値配列の代わりに使用されます。
	 *
	 * @og.rev 4.1.1.0 (2008/02/04) 新規追加
	 * @og.rev 4.1.1.0 (2008/02/21) dynamicOCadrs を考慮した処理を行う
	 *
	 * @param	value     double マーカーラインと比較する値
	 * @param	markValue double マーカーライン値
	 *
	 * @return	Color 指定の値に対する Shape色
	 */
	private Color getColor( final double value,final double markValue ) {
		Color rtnclr = null;

		if( dynamicOCadrs >= 0 ) {
			markValues[dynamicOCadrs] = markValue ;
		}

		// 閾値[0]の値と比較して、下の場合は、色[0]を返す
		if( value < markValues[0] ) {
			rtnclr = markOverColors[0];
		}
		else {
			// 閾値[N-1]の値と比較して、上の場合は、色[N]を返す。(確定)
			for( int i=markValues.length-1; i>=0; i-- ) {
				if( value >= markValues[i] ) {
					rtnclr = markOverColors[i+1];
					break;
				}
			}
		}
		return rtnclr;
	}
}
