/*
 * 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.fukurou.util.ToString;						// 6.1.1.0 (2015/01/17)
import org.opengion.fukurou.util.StringUtil;					// 7.0.5.0 (2019/09/09)

// import static org.opengion.fukurou.util.StringUtil.nval;		// 7.0.5.0 (2019/09/09) static import をやめます。

/**
 * 左右分割スクロール処理を行う、View を設定します。
 *
 * BODY部に記述された Viewタグに対して、左右分割情報を追記設定します。
 * Viewタグの左側には、このタグで指定された fixDisplay のカラムを columnDisplay に
 * 設定するとともに、このタグで指定された numberType をセットします。
 * (初期値は、numberType="sequence" です。)
 * Viewタグの右側には、fixDisplay のカラムを noDisplay のカラムに設定するとともに、
 * command="VIEW" , noMessage="true" , useSelectedRow="false" , numberType="delete"
 * をセットします。(既存の設定値があれば、それに追記されます。)
 *
 * @og.formSample
 * ●形式：&lt;og:splitView  fixDisplay="CLM,NAME_JA"&gt;&lt;og:view ・・・  /&gt;&lt;/og:splitView&gt;
 * ●body：あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{&#064;XXXX} は解析しません)
 *
 * ●Tag定義：
 *   &lt;og:splitView
 *       fixDisplay          【TAG】固定するカラム名を、CSV形式(CSV形式)で設定します
 *       useSplit            【TAG】左右分割する場合は、trueを、分割せずに、BODYのviewタグだけ使用する場合は、false をセットします。
 *       caseKey             【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
 *       caseVal             【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
 *       caseNN              【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
 *       caseNull            【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
 *       caseIf              【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
 *   &gt;   ... Body ...
 *   &lt;/og:splitView&gt;
 *
 * ●使用例
 *    &lt;og:splitView fixDisplay="CLM,NAME_JA"&gt;
 *      &lt;og:view
 *          viewFormType    = "HTMLTable"
 *          command         = "{&#064;command}"
 *          checked         = "{&#064;checked}"
 *          startNo         = "{&#064;startNo}"
 *          pageSize        = "{&#064;pageSize}"
 *          noWritable      = "{&#064;noWritable}"
 *          columnWritable  = "{&#064;columnWritable}"
 *      /&gt;
 *    &lt;/og:splitView&gt;
 *
 * @og.rev 5.3.0.0 (2010/12/01) 新規作成
 * @og.group 画面部品
 *
 * @version  4.0
 * @author	 Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class SplitViewTag extends CommonTagSupport {
	/** このプログラムのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "7.0.5.0 (2019/09/09)" ;
	private static final long serialVersionUID = 705020190909L ;

	private static final String SPLIT_A =
				  "<style type=\"text/css\">#GantBody div tr { height:22px; }</style>"				+ CR
				+ "<table id=\"GantBody\" border=\"0px\" cellpadding=\"0px\" cellspacing=\"0px\"" 	+ CR
				+ "       frame=\"box\" rules=\"all\" style=\"margin:0px;padding:0px;\">"			+ CR
				+ "  <tr style=\"margin:0px;padding:0px;\">"										+ CR
				+ "    <td valign=\"top\" style=\"margin:0px; padding:0px;\" >"						+ CR
				+ "      <div id=\"X1\" style=\"overflow-x:hidden; overflow-y:hidden;\" >"			+ CR ;

	private static final String SPLIT_B =
				  "      </div>"													+ CR
				+ "    </td>"														+ CR
				+ "    <td valign=\"top\" style=\"margin:0px; padding:0px;\">"		+ CR
				+ "      <div id=\"X2\" style=\"position:absolute; overflow-x:hidden; overflow-y:hidden;\" >" + CR ;

	private static final String SPLIT_C =
				  "       </div>"		+ CR
				+ "    </td>"			+ CR
				+ "  </tr>"				+ CR
				+ "</table>"			+ CR ;

	private String	fixDisplay		;
	private boolean useSplit		= true;		// 左右分割のON/OFFﾌﾗｸﾞ

	private boolean firstStepFlag	= true;		// BODY部の view 処理の制御

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

	/**
	 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
	 *
	 * @og.rev 6.9.5.0 (2018/04/23) 左右分割に、使用をON/OFFするﾌﾗｸﾞを追加
	 *
	 * @return	後続処理の指示( EVAL_BODY_INCLUDE )
	 */
	@Override
	public int doStartTag() {
		// 6.9.5.0 (2018/04/23) 左右分割に、使用をON/OFFするﾌﾗｸﾞを追加
		if( useTag() ) {
			if( useSplit ) {
				firstStepFlag = true;
				// EVAL_BODY_BUFFERED ではなく、Viewなので、INCLUDE 処理します。
				jspPrint( SPLIT_A );
			}
			return EVAL_BODY_INCLUDE ;		// Body インクルード( extends TagSupport 時)
		}
		return SKIP_BODY ;					// Body を評価しない

//		firstStepFlag = true;
//		// EVAL_BODY_BUFFERED ではなく、Viewなので、INCLUDE 処理します。
//		jspPrint( SPLIT_A );
//		return EVAL_BODY_INCLUDE ;					// Body インクルード( extends TagSupport 時)
	}

	/**
	 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
	 *
	 * @og.rev 6.9.5.0 (2018/04/23) 左右分割に、使用をON/OFFするﾌﾗｸﾞを追加
	 *
	 * @return	後続処理の指示(SKIP_BODY)
	 */
	@Override
	public int doAfterBody() {
		// 6.9.5.0 (2018/04/23) 左右分割に、使用をON/OFFするﾌﾗｸﾞを追加
		if( useSplit ) {
			if( firstStepFlag ) {
				firstStepFlag = false;

				jspPrint( SPLIT_B );
				// EVAL_BODY_INCLUDE なので、コンテンツの取得ではなく、処理のみ実行されます。
				return EVAL_BODY_BUFFERED ;	// ボディーを再評価( extends BodyTagSupport 時)
			}
			else {
				jspPrint( SPLIT_C );
				return SKIP_BODY ;			// Body を評価しない
			}
		}
		return SKIP_BODY ;					// Body を評価しない

//		if( firstStepFlag ) {
//			firstStepFlag = false;
//
//			jspPrint( SPLIT_B );
//			return EVAL_BODY_BUFFERED ;	// ボディーを再評価( extends BodyTagSupport 時)
//		}
//		else {
//			jspPrint( SPLIT_C );
//			return SKIP_BODY ;			// Body を評価しない
//		}
	}

	/**
	 * タグリブオブジェクトをリリースします。
	 * キャッシュされて再利用されるので、フィールドの初期設定を行います。
	 *
	 */
	@Override
	protected void release2() {
		super.release2();
		fixDisplay = null;
		useSplit   = true;
	}

	/**
	 * 【TAG】固定するカラム名を、CSV形式(CSV形式)で設定します。
	 *
	 * @og.tag
	 * Viewタグの左側(固定部)には、このタグで指定された fixDisplay のカラムを
	 * columnDisplay に設定します。
	 * Viewタグの右側には、fixDisplay のカラムを noDisplay のカラムに設定します。
	 * 既存の設定値(noDisplay)があれば、それに追記されます。
	 *
	 * @og.rev 7.0.5.0 (2019/09/09) StringUtil#nvalCsv(String,String) で、CSV形式の文字列を正規化します。
	 *
	 * @param   clms 固定するカラム名(CSV形式)
	 */
	public void setFixDisplay( final String clms ) {
//		fixDisplay = nval( getRequestParameter( clms ),fixDisplay );
		fixDisplay = StringUtil.nvalCsv( getRequestParameter( clms ),fixDisplay );		// 7.0.5.0 (2019/09/09)
	}

	/**
	 * 固定するカラム名を、CSV形式(CSV形式)で取得します。
	 *
	 * これは、BODY部に記述された、viewタグからアクセスされるメソッドです。
	 * 設定されていない場合は、null です。
	 *
	 * @return	固定するカラム名(CSV形式)
	 */
	protected String getFixDisplay() {
		return fixDisplay ;
	}

	/**
	 * 【TAG】左右分割機能の ON/OFF を設定します(初期値=true:左右分割を使用する)。
	 *
	 * @og.tag
	 * 左右分割する場合は、trueを、分割せずに、BODYのviewタグだけ使用する場合は、false をセットします。
	 * BODYも含めての使用を制御する場合は、case属性(caseKey , caseVal , caseNN , caseNull , caseIf)を、
	 * 使用してください。
	 * 初期値は、true:左右分割を使用する です。
	 *
	 * @og.rev 6.9.5.0 (2018/04/23) 左右分割に、使用をON/OFFするﾌﾗｸﾞを追加
	 * @og.rev 7.0.5.0 (2019/09/09) static import をやめます。
	 *
	 * @param   flag 左右分割機能の ON/OFF [true:左右分割/false:BODYのみ表示]
	 */
	public void setUseSplit( final String flag ) {
//		useSplit = nval( getRequestParameter( flag ),useSplit );
		useSplit = StringUtil.nval( getRequestParameter( flag ),useSplit );		// 7.0.5.0 (2019/09/09) static import をやめます。
	}

	/**
	 * 左右分割機能の ON/OFF を取得します。
	 *
	 * 左右分割する場合は、trueを、分割せずに、BODYのviewタグだけ使用する場合は、false がセットされています。
	 * これは、BODY部に記述された、viewタグからアクセスされるメソッドです。
	 * falseの場合は、viewタグで、左右分割処理を行わないようにします。
	 *
	 * @og.rev 6.9.5.0 (2018/04/23) 左右分割に、使用をON/OFFするﾌﾗｸﾞを追加
	 *
	 * @return	左右分割機能の ON/OFF[true:左右分割/false:BODYのみ表示]
	 */
	protected boolean isUseSplit() {
		return useSplit ;
	}

	/**
	 * BODY部の view 処理の制御を行うためのフラグを返します。
	 *
	 * 左右分割を行うには、Viewタグを２回出力する必要があります。
	 * ここでは isFirstStep="true" が１回目(左側:固定部)で、false が
	 * 右側(可変部)になるように、View側で制御します。
	 *
	 * @return	BODY部の view 処理の制御(true:１回目 / false:２回目)
	 */
	protected boolean isFirstStep() {
		return firstStepFlag ;
	}

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