/*
 * 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.html.TableFormatter;
import org.opengion.hayabusa.html.FormatterType;
import org.opengion.fukurou.util.ToString;						// 6.1.1.0 (2015/01/17)

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

/**
 * ヘッダ、フッター、ボディー部のフォーマットを汎用的に定義するタグです。
 *
 * thead,tfoot,tbody に代わる表示フォーマットをカスタマイズするときに使用する親クラスです。
 * このクラス自身がタグとしては表に現れません。
 *
 * @og.formSample
 * ●形式：(タグとしては使われません)
 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
 *
 * @og.rev 3.5.4.0 (2003/11/25) 新規追加
 * @og.rev 3.5.4.2 (2003/12/15) カスタムタグクラスから削除します。(abstract化)
 * @og.rev 4.0.0.0 (2006/01/31) カスタムタグクラスに復活させます。(public化)
 * @og.rev 6.3.4.0 (2015/08/01) TFormatTag.java → TFormatImpl.java
 * @og.group 画面部品
 *
 * @version  4.0
 * @author	 Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
class TFormatImpl extends CommonTagSupport {
	/** このプログラムのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "6.4.2.0 (2016/01/29)" ;
	private static final long serialVersionUID = 642020160129L ;

	private String rowspan		= "2";
	private String noClass		= "false";
	private String usableKey	;
	private String usableList	= "1" ;
	private String itdBody		= "";			// 3.5.6.0 (2004/06/18)
	private String keyBreakClm	;				// 5.7.6.3 (2014/05/23)
	private boolean useTrCut	= true;			// 5.5.0.3 (2012/03/13)

	/**
	 * デフォルトコンストラクター
	 *
	 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
	 */
	public TFormatImpl() { super(); }		// これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。

	/**
	 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
	 *
	 * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
	 *
	 * @return	後続処理の指示( EVAL_BODY_BUFFERED )
	 */
	@Override
	public int doStartTag() {
		// 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
		// 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
		return useTag()
					? EVAL_BODY_BUFFERED		// Body を評価する。( extends BodyTagSupport 時)
					: SKIP_BODY ;				// Body を評価しない
	}

	/**
	 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
	 *
	 * @og.rev 3.5.6.0 (2004/06/18) setItdBody メソッドによる itdBody の登録処理追加
	 * @og.rev 5.1.7.0 (2010/06/01) フォーマットの{&#064;XXXX}の値に[が含まれる場合は、サイニタイズ("\\]\\"に変換)する。
	 * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
	 * @og.rev 5.7.6.3 (2014/05/23) useKeyBreak 属性の追加
	 *
	 * @return	後続処理の指示(EVAL_PAGE)
	 */
	@Override
	public int doEndTag() {
		debugPrint();		// 4.0.0 (2005/02/28)
		// 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
		if( useTag() ) {
			final ViewFormTag viewform = (ViewFormTag)findAncestorWithClass( this,ViewFormTag.class );
			if( viewform == null ) {
				final String errMsg = "<b>" + getTagName() + "タグは、ViewFormTagの内側(要素)に記述してください。</b>";
				throw new HybsSystemException( errMsg );
			}
			// 5.1.7.0 (2010/06/01) フォーマットの{@XXXX}の値に[が含まれる場合は、サイニタイズ("\\]\\"に変換)する。
	//		String bodyFormat = getBodyString();
			final String bodyFormat = getSanitizedBodyString();

			final TableFormatter format = new TableFormatter();
			format.setFormatType( getType() );
			format.setFormat( bodyFormat, useTrCut );	// 5.5.0.3 (2012/03/13)
			format.setRowspan( rowspan );
			format.setNoClass( noClass );
			format.setUsableKey( usableKey );
			format.setUsableList( usableList );
			format.setItdBody( itdBody );				// 3.5.6.0 (2004/06/18)
			format.setKeyBreakClm( keyBreakClm );		// 5.7.6.3 (2014/05/23)
			viewform.addFormatter( format );
		}
		return EVAL_PAGE ;		// ページの残りを評価する。
	}

	/**
	 * タグリブオブジェクトをリリースします。
	 * キャッシュされて再利用されるので、フィールドの初期設定を行います。
	 *
	 * @og.rev 3.5.6.0 (2004/06/18) itdBody 属性の追加
	 * @og.rev 5.7.6.3 (2014/05/23) useTrCut,useKeyBreak 属性の追加
	 *
	 */
	@Override
	protected void release2() {
		super.release2();
		rowspan		= "2";
		noClass		= "false";
		usableKey	= null;
		usableList	= "1" ;
		itdBody		= "";			// 3.5.6.0 (2004/06/18)
		useTrCut	= true;			// 5.7.6.3 (2014/05/23)
		keyBreakClm	= null;			// 5.7.6.3 (2014/05/23)
	}

	/**
	 * 【TAG】表示データを作成する場合のフォーマットの行数(rowspan)をセットします(初期値:2)。
	 *
	 * @og.tag
	 * 表示データを作成する場合のフォーマットの行数をセットします。
	 * 上位の viewFormタグより、こちらが優先されます。
	 *
	 * @param	span フォーマットの行数
	 */
	public void setRowspan( final String span ) {
		rowspan = span;
	}

	/**
	 * 【TAG】カラムのクラス名(VERCHAR2,NUMBER など)を使用しないかどうか[true:未使用/false:使用]を指定します(初期値:false)。
	 *
	 * @og.tag
	 * "true" で、クラス属性を設定しません。これは、ＣＳＳファイルに書かれている属性を
	 * 使用しないことを意味します。
	 * 初期値は、"false" です。
	 *
	 * @param	flag クラス名未使用可否 [true:未使用/false:使用]
	 */
	public void setNoClass( final String flag ) {
		this.noClass = flag;
	}

	/**
	 * このフォーマットのタイプを返します。
	 *
	 * タイプは、"head/body/foot" の中から、指定します。
	 *
	 * @og.rev 3.5.5.8 (2004/05/20) abstract します。
	 *
	 * @return	このフォーマットのタイプを返します。
	 */
	protected FormatterType getType() {
		final String errMsg = "このメソッドは、THead/TBody/TFoot の各サブクラスで実装してください。";
		throw new UnsupportedOperationException( errMsg );
	}

	/**
	 * 【TAG】フォーマットの使用可否を判断するキーとなるカラム名を指定します。
	 *
	 * @og.tag
	 * キーが、usableList に含まれる場合は、このフォームを使用できます。
	 * キー(カラム名)が指定されない場合は、常に使用されます。
	 * ※ 現時点では、BODYタイプのみ使用しています。
	 * ※ この属性は、リクエスト変数処理を行いません。
	 *
	 * @param  key 使用可否判定カラム
	 */
	public void setUsableKey( final String key ) {
		usableKey = key;
	}

	/**
	 * 【TAG】フォーマットの使用可否を判断する文字列リストを指定します(初期値:"1")。
	 *
	 * @og.tag
	 * キーが、この文字列リスト中に存在する場合は、このフォームを使用できます。
	 * この文字列リストは、固定な文字列です。{&#064;XXXX}は使用できますが、[XXXX]は
	 * 使用できません。
	 * 初期値は、"1" です。
	 * ※ 現時点では、BODYタイプのみ使用しています。
	 *
	 * @param  list 使用可否判定リスト
	 */
	public void setUsableList( final String list ) {
		usableList = nval( getRequestParameter(list),usableList );
	}

	/**
	 *  itdフォーマット文字列を設定します。
	 *
	 * itd ボディ部の文字列を指定します。
	 * itd ボディは、繰り返し処理を行います。これを、上位のボディ文字列の中の
	 * HYBS_ITD_MARKER 文字列 と置き換えます。
	 * ※ この属性は、リクエスト変数処理を行いません。
	 *
	 * @og.rev 3.5.6.0 (2004/06/18) itdフォーマット文字列の取り込み
	 *
	 * @param  itd itdフォーマットの文字列
	 */
	public void setItdBody( final String itd ) {
		if( itd != null ) {
			itdBody = itd;
		}
	}

	/**
	 * 【TAG】ここで指定したカラムの値が、キーブレイクした場合、このタグを使用します(初期値:null)。
	 *
	 * @og.tag
	 * usableKey,usableList の様に、予め決められた値の時に、適用されるのではなく、
	 * キーブレイクで 使用可否を指定する為の機能です。
	 * この設定値は、usableKey,usableList とは、独立しているため、それぞれで
	 * 有効になれば、使用されると判断されます。
	 * キーブレイク判定では、最初の1件目は、必ず使用されると判断されます。
	 *
	 * @og.rev 5.7.6.3 (2014/05/23) 新規追加
	 *
	 * @param  kclm  キーブレイクカラム
	 */
	public void setKeyBreakClm( final String kclm ) {
		keyBreakClm = nval( getRequestParameter( kclm ),keyBreakClm );
	}

	/**
	 * 【TAG】 先頭trタグを削除するかどうか[true/false]を指定します(初期値:true)。
	 *
	 * @og.tag
	 * フォーマットの先頭がtrタグの場合は削除する処理がありますが、
	 * CustomDataのような場合では削除したくありません。
	 * falseを指定すると削除処理を行わないようになります。
	 *
	 * @og.rev 5.5.0.3 (2012/03/13) 新規追加
	 *
	 * @param  useFlg  TRタグの削除 [true:削除する/false:削除しない]
	 */
	public void setUseTrCut( final String useFlg ) {
		useTrCut = nval( getRequestParameter( useFlg ),useTrCut );
	}

	/**
	 * このオブジェクトの文字列表現を返します。
	 * 基本的にデバッグ目的に使用します。
	 *
	 * @return このクラスの文字列表現
	 * @og.rtnNotNull
	 */
	@Override
	public String toString() {
		return ToString.title( this.getClass().getName() )
	//			.println( "VERSION"		,VERSION	)
				.println( "rowspan"		,rowspan	)
				.println( "noClass"		,noClass	)
				.println( "usableKey"	,usableKey	)
				.println( "usableList"	,usableList	)
				.println( "itdBody"		,itdBody	)
				.println( "keyBreakClm"	,keyBreakClm)
				.println( "Other..."	,getAttributes().getAttribute() )
				.fixForm().toString() ;
	}
}
