/*
 * The MIT License
 *
 * Copyright 2013 Dra0211.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package kinugasa.ui;

import java.awt.Color;
import java.awt.Graphics2D;
import kinugasa.object.Model;
import kinugasa.util.TimeCounter;

/**
 * 選択肢を表示するメッセージウインドウの、
 * 選択されているラベルに適用するエフェクトのアルゴリズムを定義します.
 * <br>
 * このモデルクラスは選択肢が「現在選択中であること」をプレイヤーに示すエフェクトを提供します。<br>
 * 伝統的な方法としてはハイライトや矢印を表示する方法があります。このクラスでは1文字のスペースだけを
 * 任意の色でハイライトするプリセットを提供します。<br>
 * <br>
 *
 * @version 1.0.0 - 2012/11/23_21:56:07.<br>
 * @author Dra0211<br>
 * <br>
 */
public abstract class ChoiceEffect extends Model {

	private static final long serialVersionUID = -3642532507764357135L;

	/**
	 * テキストラベルlabelに選択中であることを示すエフェクトを描画します.
	 * このエフェクトはラベルの描画後に呼ばれる点に注意してください。<br>
	 * 通常の不透明な色による上書きはラベルのテキストを隠します。<br>
	 *
	 * @param g     書き込むグラフィックスコンテキストが送信されます。<br>
	 * @param label 選択中のラベルが送信されます。<br>
	 */
	public abstract void draw(Graphics2D g, TextLabel label);

	@Override
	public ChoiceEffect clone() {
		return (ChoiceEffect) super.clone();
	}

	/**
	 * 選択中ラベルの先頭1文字だけを任意の色でハイライトするモデルを作成して返します.
	 *
	 * @param color　ハイライトする色を指定します。通常は半透明な色を送信します。<br>
	 *
	 * @return 指定した色の選択エフェクトを作成して返します。<br>
	 */
	public static ChoiceEffect craeteSingleCharChoiceEffect(Color color) {
		return new SingleCharEffect(color);
	}

	/**
	 * 選択中ラベルの先頭1文字だけを任意の色でハイライトするモデルを作成して返します.
	 *
	 * @param color　    ハイライトする色を指定します。通常は半透明な色を送信します。<br>
	 * @param blinkRate 点滅間隔を指定します。isReachingがtrueを返すときのみエフェクトが描画されます。<br>
	 *
	 * @return 指定した色と点滅間隔の選択エフェクトを作成して返します。<br>
	 */
	public static ChoiceEffect craeteSingleCharChoiceEffect(Color color, TimeCounter blinkRate) {
		return new SingleCharEffect(color, blinkRate);
	}

	/**
	 * 1文字だけにハイライトエフェクトかける選択エフェクトの実装です.
	 * <br>
	 * このモデルはハイライトの点滅間隔を持ちます。<br>
	 * <br>
	 *
	 * @author dra0211 ( <a href="mailto:d0211@live.jp">d0211@live.jp</a>&nbsp;).<br>
	 * @version 1.0.0 - 2012/11/23_21:56:07.<br>
	 * <br>
	 */
	private static final class SingleCharEffect extends ChoiceEffect {

		private static final long serialVersionUID = -3270758183562208632L;

		/**
		 * 新しいモデルを作成します.
		 * このコンストラクタでは点滅はせず、常にハイライトが有効になります。<br>
		 *
		 * @param color ハイライトの色を指定します。<br>
		 */
		SingleCharEffect(Color color) {
			this.color = color;
			blinkTime = TimeCounter.TRUE;
		}

		/**
		 * 新しいモデルを作成します.
		 *
		 * @param color     ハイライトの色を指定します。<br>
		 * @param blinkTime 点滅間隔を指定します。<br>
		 */
		SingleCharEffect(Color color, TimeCounter blinkTime) {
			this.blinkTime = blinkTime;
			this.color = color;
		}
		/** 点滅間隔を表すタイムカウンタです. */
		private TimeCounter blinkTime;
		/** ハイライトの色です. */
		private Color color;

		@Override
		public void draw(Graphics2D g, TextLabel label) {
			if (!blinkTime.isReaching()) {
				return;
			}
			g.setColor(color);
			float x = label.getX() - 3;
			float y = label.getY() + 3;
			float w = label.getLabelModel().getFontSize() + 3;
			float h = label.getLabelModel().getFontSize();
			g.fillRect((int) x, (int) y, (int) w, (int) h);
		}

		@Override
		public ChoiceEffect clone() {
			SingleCharEffect cf = (SingleCharEffect) super.clone();
			cf.blinkTime = this.blinkTime.clone();
			return cf;
		}
	};
}
