/*
 * 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.taglib;

import org.opengion.hayabusa.common.HybsSystemException;
import org.opengion.hayabusa.resource.LabelInterface;
import org.opengion.fukurou.util.StringUtil;

import static org.opengion.fukurou.util.StringUtil.nval ;

/**
 * 画面にメッセージリソースやラベルリソース等のメッセージを表示させるタグです。
 *
 * msg 属性に メッセージリソースのキーを与えることで、 ロケールにあわせたリソースを使用して、
 * 画面に表示します。
 * lbl 属性に ラベルリソース のキーを与えることで、 ロケールにあわせたリソースを使用して、
 * 画面に表示します。
 * 違う値をセットした場合は、 セットした値が、そのまま出力されます。これは、ロケールが
 * 見つからなかった場合の標準の対応方法です。
 * ロケールは、ユーザー情報の lang 属性を初期値で使用し、 セットされていない場合は、
 * リクエスト情報のロケールから取得します。
 * msg 属性を使用する場合、val0 ～ val9 までの引数を使用することができます。これは、
 * メッセージフォーマットの、引数 {0} ～ {9} に対応して割り付けられます。
 * msg 属性とlbl 属性は同時に使用できません。
 *
 * @og.formSample
 * ●形式：&lt;og:message msg="…" val0=[…] … /&gt;
 * ●body：あり
 *
 * ●使用例
 *     &lt;og:message msg=&quot;MSG0032&quot; language=&quot;ja&quot; /&gt;
 *
 *        msg       : MessageResource.properties のキー
 *        language  : ロケール（オプション）
 *
 *     例１）
 *         &lt;og:message msg=&quot;MSG0032&quot; &gt;検索条件&lt;/og:message&gt;
 *
 *        BODY 部分は、無視されます。コメント等に使用できます。
 *        HTMLファイルには、コメント部分は出力されません。
 *
 * @og.group 画面部品
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class MessageTag extends CommonTagSupport {
	//* このプログラムのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "4.0.0 (2005/08/31)" ;

	private static final long serialVersionUID = 4000 ;	// 4.0.0 (2005/01/31)

	private String		comment	= null;
	private String[]	values	= null;
	// 4.0.0 (2005/01/31) メッセージの種類を指定できるようにします。
	private String		type	= "Label" ;	// Label,Short,Tips,Description が指定できます。
	private String		cmdMsg	= null;

	private static final String[] TYPE_LIST = new String[] { "Label","Short","Tips","Description" };

	/**
	 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
	 *
	 * @return  int
	 */
	@Override
	public int doStartTag() {
		return( EVAL_BODY_BUFFERED );	// Body を評価する。（ extends BodyTagSupport 時）
	}

	/**
	 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
	 *
	 * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
	 *
	 * @return  int
	 */
	@Override
	public int doAfterBody() {
		String str = getBodyString();

		if( str != null && str.length() > 0 ) {
			comment = StringUtil.htmlFilter( str );
		}

		return(SKIP_BODY);
	}

	/**
	 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
	 *
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
	 *
	 * @return  int
	 */
	@Override
	public int doEndTag() {
		debugPrint();		// 4.0.0 (2005/02/28)
		jspPrint( makeTag() );

		return(EVAL_PAGE);
	}

	/**
	 * タグリブオブジェクトをリリースします。
	 * キャッシュされて再利用されるので、フィールドの初期設定を行います。
	 *
	 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
	 *
	 */
	@Override
	protected void release2() {
		super.release2();
		comment	= null;
		values	= null;
		type	= "Label" ;	// Label,Short,Tips,Description が指定できます。
		cmdMsg	= null;
	}

	/**
	 * 【TAG】表示用の文字列を指定します。
	 *
	 * @og.rev 4.0.0 (2005/01/31) タイプ別メッセージ情報を返します。
	 * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage > getResource().getLabel )
	 *
	 * @return  変換後の文字列
	 */
	private String makeTag() {
		String val  = null;

		LabelInterface label = getLabelInterface();

		char ch = type.charAt( 0 );	// Label,Short,Tips,Description
		if( label != null ) {
			switch( ch ) {
				case 'L': val = label.getMessage( values ); break;
				case 'S': val = label.getShortLabel(); break;
				case 'T': val = label.getLongLabel(); break;
				case 'D': val = label.getDescription(); break;
				default : break;
			}
		}
		else {
			if( cmdMsg != null ) {
				// cmdMsg = INSERT,COPY,MODIFY,DELETE,null
//				val = getResource().getMessage( cmdMsg );
				val = getResource().getLabel( cmdMsg );
			}
			else {
				val = comment;
			}
		}

		return val;
	}

	/**
	 * 【TAG】コメントを指定します。
	 *
	 * @og.tag
	 * msg 属性でメッセージリソースから読み取りますが,開発途中で
	 * リソース登録を済ましていない状態でコメントを入れる場合に、
	 * 直接コメントをかけるようにします。
	 *
	 * @og.rev 2.2.0.0 (2002/12/17) 中国語（国際化）対応 エンコードの取得方法変更
	 * @og.rev 3.0.0.0 (2002/12/25) StringUtil#changeString 廃止
	 *
	 * @param   cmnt コメント文字列
	 */
	public void setComment( final String cmnt ) {
		comment = cmnt;
	}

	/**
	 * 【TAG】タイプを(Label,Short,Tips,Description)から指定します(初期値：Label)。
	 *
	 * @og.tag
	 * タイプは、ラベル／メッセージリソースのどの情報を取得したいかを指定できます。
	 * 従来のラベル／メッセージは、Label に相当します。
	 * なお、指定は、それぞれの頭文字('L','S','T','D')のみでも可能です。
	 * 初期値は、"Label" です。
	 * ・Label  : ラベル／メッセージ表示
	 * ・Short  : 表形式で使用する短いラベル表示
	 * ・Tips   : ラベルの上にTips表示
	 * ・Description : 概要説明を表示
	 *
	 * @og.rev 4.0.0 (2005/01/31) 新規登録
	 *
	 * @param   tp タイプ文字列('L','S','T','D','B')
	 */
	public void setType( final String tp ) {
		type = nval( getRequestParameter( tp ),type );

		char ch = type.charAt( 0 );	// Label,Short,Tips,Description

		if( "LSTD".indexOf( ch ) < 0 ) {
			String errMsg = "type に、指定不可能な文字が設定されました。type=[" + type
					+ "] TYPE_LIST=[" + StringUtil.array2csv( TYPE_LIST ) + "]";
			throw new HybsSystemException( errMsg );
		}
	}

	/**
	 * 【TAG】メッセージの引数{0}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal0( final String value ) { setValues( 0, value ); }

	/**
	 * 【TAG】メッセージの引数{1}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal1( final String value ) { setValues( 1, value ); }

	/**
	 * 【TAG】メッセージの引数{2}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal2( final String value ) { setValues( 2, value ); }

	/**
	 * 【TAG】メッセージの引数{3}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal3( final String value ) { setValues( 3, value ); }

	/**
	 * 【TAG】メッセージの引数{4}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal4( final String value ) { setValues( 4, value ); }

	/**
	 * 【TAG】メッセージの引数{5}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal5( final String value ) { setValues( 5, value ); }

	/**
	 * 【TAG】メッセージの引数{6}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal6( final String value ) { setValues( 6, value ); }

	/**
	 * 【TAG】メッセージの引数{7}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal7( final String value ) { setValues( 7, value ); }

	/**
	 * 【TAG】メッセージの引数{8}を指定します。
	 *
	 * @og.tag メッセージの引数を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal8( final String value ) { setValues( 8, value ); }

	/**
	 * 【TAG】メッセージの引数{9}を指定します。
	 *
	 * @og.tag メッセージの引数{9}を指定します。
	 *
	 * @param   value メッセージの引数
	 */
	public void setVal9( final String value ) { setValues( 9, value ); }

	/**
	 * メッセージの引数を指定します。
	 *
	 * @param   no    メッセージの引数の配列番号
	 * @param   value メッセージの引数
	 */
	private void setValues( final int no,final String val ) {
		if( values == null ) { values = new String[10]; }
		values[no] = getRequestParameter( val );
	}

	/**
	 * 【TAG】コマンド(INSERT,COPY,MODIFY,DELETE)をセットします。
	 *
	 * @og.tag
	 * コマンドは,HTMLから（get/post)指定されますので,CMD_xxx で設定される
	 * フィールド定数値のいづれかを、指定できます。
	 * コマンド(INSERT,COPY,MODIFY,DELETE)に対応したメッセージを表示します。
	 * INSERT : MSG0044  追加処理を行います。
	 * COPY   : MSG0045  複写処理を行います。
	 * MODIFY : MSG0046  変更処理を行います。
	 * DELETE : MSG0047  削除処理を行います。
	 *
	 * なお、command によるメッセージの自動選択は、msg , lbl ともにセットされていない
	 * 場合にのみ有効になります。
	 *
	 * @og.rev 4.0.0 (2006/11/31) 新規登録
	 *
	 * @param	cmd コマンド（public static final 宣言されている文字列)
	 */
	public void setCommand( final String cmd ) {
		String cmd2 = nval( getRequestParameter( cmd ),null );
		if(      "INSERT".equalsIgnoreCase( cmd2 ) ) { cmdMsg = "MSG0044"; }
		else if( "COPY".equalsIgnoreCase(   cmd2 ) ) { cmdMsg = "MSG0045"; }
		else if( "MODIFY".equalsIgnoreCase( cmd2 ) ) { cmdMsg = "MSG0046"; }
		else if( "DELETE".equalsIgnoreCase( cmd2 ) ) { cmdMsg = "MSG0047"; }
		else { cmdMsg = null; }
	}

	/**
	 * このオブジェクトの文字列表現を返します。
	 * 基本的にデバッグ目的に使用します。
	 *
	 * @return このクラスの文字列表現
	 */
	public String toString() {
		return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
				.println( "VERSION"		,VERSION	)
				.println( "comment"		,comment	)
				.println( "values"		,values		)
				.println( "type"		,type		)
				.println( "TYPE_LIST"	,TYPE_LIST	)
				.println( "Other..."	,getAttributes().getAttribute() )
				.fixForm().toString() ;
	}
}
