/*
 * 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.HybsSystem;
import org.opengion.hayabusa.html.ViewCrossTableParam;

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

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

/**
 * viewタグの viewFormType が HTMLCrossTable の場合にパラメータを設定します。
 *
 * クロス集計を行う、ViewForm_HTMLCrossTable クラスに対して、各種パラメータを
 * 設定します。
 * パラメータが設定されていない場合は、ViewCrossTableParam の初期値が使用されます。
 * (パラメータを使用するには、viewタグのuseParam 属性をtrueに設定する必要があります。)
 *
 * SELECT文は、CROSS集計機能を利用して求めます。そのときのフォーマットは、
 * ヘッダー1..N,縦,横,計1..N になります。<br/>
 * ヘッダー部は、複数指定できますが、デフォルトではヘッダーNがキーブレイクすると
 * 合計用のヘッダーが挿入されます。また、ヘッダーは、前段と同じ値の場合は、表示しません。
 * 合計は、複数並べることができますが、sumNumber で指定しておく必要があります。
 *
 * 各属性は、{&#064;XXXX} 変数が使用できます。
 * これは、ServletRequest から、XXXX をキーに値を取り出し,この変数に割り当てます。
 * つまり、このXXXXをキーにリクエストすれば、この変数に値をセットすることができます。
 *
 * http://localhost/query.jsp?KEY1=VLA1&amp;KEY2=VAL2
 *
 * のようなリクエストで、{&#064;KEY1} とすれば、 VAL1 がセットされます。
 *
 * @og.formSample
 * ●形式：&lt;og:crossParam breakColumn="ZZZ" noGroupColumns="AAA,BBB" sumNumber="2" /&gt;
 * ●body：なし
 *
 * ●使用例
 *     ViewFormTag の viewFormType が、HTMLCrossTable の場合に使用します。
 *     useParam 属性を設定しておかないと、使用されません。
 *     &lt;og:view
 *         viewFormType = &quot;HTMLCrossTable&quot;
 *         command      = &quot;{&#064;command}&quot;
 *         startNo      = &quot;0&quot;
 *         pageSize     = &quot;20&quot;
 *         <b>useParam     = &quot;true&quot;</b>
 *     &gt;
 *         &lt;og:crossParam
 *             breakColumn    = "ZZZ"
 *             noGroupColumns = "AAA,BBB"
 *             cubeXColumn    = "CUBE_X"
 *             cubeYColumn    = "CUBE_Y"
 *             shokeiLabel    = "SHOKEI"
 *             gokeiLabel     = "GOKEI"
 *             sumNumber      = "2"
 *             cubeSortType   = "NUMBER"
 *             gokeiSortDir   = "false"
 *        /&gt;
 *     &lt;/og:view &gt;
 *
 *     breakColumn     : ブレークによりヘッダー部を出力させるカラム名
 *     noGroupColumns  : カラム値を前段と比較して同じ場合でも表示させるカラム名
 *     cubeXColumn     : CUBE計算の１つ目（X）カラムを指定
 *     cubeYColumn     : CUBE計算の２つ目（Y）カラムを指定
 *     sumNumber       : 合計値のカラム数（初期値１）
 *     shokeiLabel     : 列小計のカラムに表示するラベルID(初期値：SHOKEI)
 *     gokeiLabel      : 列合計のカラムに表示するラベルID(初期値：GOKEI)
 *     cubeSortType    : CUBE Y の列ヘッダーのソート方式を指定[STRING/NUMBER/LOAD]
 *     gokeiSortDir    : 合計行のソート有無とその方向（正方向/逆方向）を指定[true/false/null]
 *
 * @og.group 画面表示
 *
 * @version  4.0
 * @author	 Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class ViewCrossParamTag extends ViewParamTag {
	//* このプログラムの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)

	/**
	 * 【TAG】ブレークによりヘッダー部を出力させるカラム名をセットします(初期値:ヘッダーN)。
	 *
	 * @og.tag
	 * CROSS集計で求めたフォーマットは、『ヘッダー1..N,縦,横,計1..N 』です。<br/>
	 * ヘッダー部は、複数指定できますが、デフォルトではヘッダーNがキーブレイクすると
	 * 合計用のヘッダーが挿入されます。
	 * このヘッダーNそのものが、集計フィールドでなく、単なる属性の場合は、
	 * キーブレイクして欲しくない為、breakColumn="ヘッダーN-1" を指定します。
	 * 初期値は、"ヘッダーN" です。
	 *
	 * @param	clm ブレークさせるカラム名
	 */
	public void setBreakColumn( final String clm ) {
		putParam( ViewCrossTableParam.BREAK_COLUMN_KEY,
				  nval( getRequestParameter( clm ),null ) );
	}

	/**
	 * 【TAG】カラム値を前段と比較して同じ場合でも表示させるカラム名
	 *
	 * @og.tag
	 * CROSS集計で求めたフォーマットは、『ヘッダー1..N,縦,横,計1..N 』です。<br/>
	 * ヘッダー部は、キーブレイクする都度、ヘッダーを出力します。それまでは、
	 * 各ヘッダーの値が、前段（同一カラムの先の値）と同じ場合は、空白にします。
	 * こうする事で、値のグループ化が一目で判ります。（初期設定）<br/>
	 * このヘッダーが、集計フィールドでなく、単なる属性の場合は、
	 * 空白ではなく、値として表示したい為、グループ化しない事を指定します。
	 *
	 * @param	clms グループ化（空白化）したくないカラム（カンマ区切り）
	 */
	public void setNoGroupColumns( final String clms ) {
		putParam( ViewCrossTableParam.NO_GROUP_COLUMNS_KEY,
				  nval( getRequestParameter( clms ),null ) );
	}

	/**
	 * 【TAG】合計値のカラム数（初期値:１）
	 *
	 * @og.tag
	 * CROSS集計で求めたフォーマットは、『ヘッダー1..N,縦,横,計1..N 』です。<br/>
	 *  合計は、複数並べることができますが、sumNumber で指定しておく必要があります。
	 * 初期値は、1 です。
	 *
	 * @param	no 合計値のカラム数（初期値１）
	 */
	public void setSumNumber( final String no ) {
		putParam( ViewCrossTableParam.SUM_NUMBER_KEY,
				  nval( getRequestParameter( no ),"1" ) );
	}

	/**
	 * 【TAG】列小計のカラムに表示するラベルIDを指定します(初期値:空文字列)。
	 *
	 * @og.tag
	 * 各列の小計のラベルIDを登録します。登録する文字列は、ラベルリソースに
	 * 定義しておいて下さい。
	 * 初期値は、空文字列（""）です。
	 *
	 * @og.rev 3.7.1.1 (2005/05/31) 初期値を "SHOKEI" に設定します。
	 *
	 * @param	id 列小計のカラムに表示するラベルID
	 */
	public void setShokeiLabel( final String id ) {
		String label = nval( getRequestParameter( id ),"SHOKEI" );
		putParam( ViewCrossTableParam.SHOKEI_LABEL_KEY, getLabel( label ) );
	}

	/**
	 * 【TAG】列合計のカラムに表示するラベルIDを指定します(初期値:空文字列)。
	 *
	 * @og.tag
	 * 各列の合計のラベルIDを登録します。登録する文字列は、ラベルリソースに
	 * 定義しておいて下さい。
	 * 初期値は、空文字列（""）です。
	 *
	 * @og.rev 3.7.1.1 (2005/05/31) 初期値を "GOKEI" に設定します。
	 *
	 * @param	id 列合計のカラムに表示するラベルID
	 */
	public void setGokeiLabel( final String id ) {
		String label = nval( getRequestParameter( id ),"GOKEI" );
		putParam( ViewCrossTableParam.GOKEI_LABEL_KEY, getLabel( label ) );
	}

	/**
	 * 【TAG】クロス集計結果の DBTableModel をセーブするセッションキーワードを指定します。
	 *
	 * @og.tag
	 * 検索のみの場合は、何も設定しません。EXCEL等外部にクロス集計の形で
	 * 取り出したい場合に、設定します。
	 * "DEFAULT" という文字列を指定すると、内部では、HybsSystem.TBL_MDL_KEY が
	 * 設定されます。（DEFAULT という文字列に設定されるわけではありません。）
	 * なお、DEFAULT を使用する場合は、検索結果の DBTbleModel をつぶすことになります
	 * ので、NEXT 等は使えません。DBTableModel のデータを利用した forward 等も
	 * 使用できませんので、十分ご注意ください。
	 * DEFAULT 以外の文字列の場合は、指定した文字列そのものがキーになります。
	 * 他のセッションキーと同じにすると動作が不安定になりますので、使用する場合は、
	 * "CROSS_TABLE_SAVE_KEY" を推奨致します。
	 * 指定しない場合は、セッションにセーブされません。（検索されたまま）
	 *
	 * @param	id sessionに登録する時の ID
	 */
	public void setSaveTableId( final String id ) {
		String tableId = nval( getRequestParameter( id ),null );
		if( "DEFAULT".equals( tableId ) ) {
			tableId = HybsSystem.TBL_MDL_KEY;
		}
		putParam( "saveTableId", tableId );
	}

	/**
	 * 【TAG】CUBE計算の１つ目（X）カラムを指定します。
	 *
	 * @og.tag
	 * 列方向のキーとなるカラム名を指定します。
	 * 初期値は、互換性の関係より、sumNumber より逆計算します。
	 *
	 * @og.rev 3.5.5.9 (2004/06/07) 新規追加
	 *
	 * @param	cubeX 列合計のカラムに表示するラベルID
	 */
	public void setCubeXColumn( final String cubeX ) {
		putParam( ViewCrossTableParam.CUBE_X_COLUMN_KEY,
				  nval( getRequestParameter( cubeX ),null ) );
	}

	/**
	 * 【TAG】CUBE計算の２つ目（Y）カラムを指定します。
	 *
	 * @og.tag
	 * 行方向のキーとなるカラム名を指定します。
	 * 初期値は、互換性の関係より、sumNumber より逆計算します。
	 *
	 * @og.rev 3.5.5.9 (2004/06/07) 新規追加
	 *
	 * @param	cubeY 列合計のカラムに表示するラベルID
	 */
	public void setCubeYColumn( final String cubeY ) {
		putParam( ViewCrossTableParam.CUBE_Y_COLUMN_KEY,
				  nval( getRequestParameter( cubeY ),null ) );
	}

	/**
	 * 【TAG】CUBE Y の列ヘッダーのソート方式を指定します(初期値:LOAD)。
	 *
	 * @og.tag
	 * CUBEのヘッダーに対応するカラム列をソート表示する場合の方式を指定します。
	 * 種類として、STRING,NUMBER,LOAD,があります。
	 * 初期値（指定無し）は、LOAD（取り込み順にセット）です。
	 *
	 * @og.rev 3.5.6.3 (2004/07/12) 新規追加
	 *
	 * @param	cubeSortType CUBE Y の列ヘッダーのソート方式[STRING,NUMBER,LOAD]
	 */
	public void setCubeSortType( final String cubeSortType ) {
		putParam( ViewCrossTableParam.CUBE_SORT_TYPE_KEY,
				  nval( getRequestParameter( cubeSortType ),null ) );
	}

	/**
	 * 【TAG】合計行のソート有無とその方向（正方向/逆方向）を指定します[true/false/null](初期値:null)。
	 *
	 * @og.tag
	 * 最も最後の合計カラムにソートを行うかどうか、その時の方向を指定します。
	 * true/false 以外の文字列では、ソートを行いません。trueは、正方向（昇順）で、
	 * falseが逆方向（降順）になります。
	 * 初期値（指定無し）は、ソートしない（null)です。
	 *
	 * @og.rev 3.5.6.3 (2004/07/12) 新規追加
	 *
	 * @param	gokeiSortDir 合計行のソート有無とその方向（正方向/逆方向）[true/false/null]
	 */
	public void setGokeiSortDir( final String gokeiSortDir ) {
		putParam( ViewCrossTableParam.GOKEI_SORT_DIR_KEY,
				  nval( getRequestParameter( gokeiSortDir ),null ) );
	}

	/**
	 * タグの名称を、返します。
	 * 自分自身のクラス名より、自動的に取り出せないため、このメソッドをオーバーライドします。
	 *
	 * @og.rev 4.0.0 (2005/01/31) 新規追加
	 *
	 * @return  タグの名称
	 */
	protected String getTagName() {
		return "crossParam" ;
	}

	/**
	 * シリアライズ用のカスタムシリアライズ書き込みメソッド
	 *
	 * @og.rev 4.0.0 (2006/09/31) 新規追加
	 * @serialData
	 *
	 * @param strm ObjectOutputStream
	 */
	private void writeObject( final ObjectOutputStream strm ) throws IOException {
		strm.defaultWriteObject();
	}

	/**
	 * シリアライズ用のカスタムシリアライズ読み込みメソッド
	 *
	 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
	 *
	 * @og.rev 4.0.0 (2006/09/31) 新規追加
	 * @serialData
	 *
	 * @param strm ObjectInputStream
	 * @see #release2()
	 */
	private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
		strm.defaultReadObject();
	}

	/**
	 * 【TAG】ヘッダーカラムにレンデラー、エディターを適用するかを指定します。（初期値:false)
	 *
	 * @og.tag
	 * ヘッダーカラムにレンデラー、エディターを適用するかを指定します。
	 * trueが指定された場合は、ヘッダー部分の値そのものをカラム名として扱います。
	 * リソースが存在しない場合は、ラベルのみを各カラムの値で置き換えます。
	 * 初期値（指定無し）は、レンデラー、エディターを適用しない（false)です。
	 *
	 * @og.rev 4.0.0.0 (2007/11/27) 新規追加
	 *
	 * @param useHeaderColumn ヘッダーカラムにレンデラー、エディターを適用するかどうか
	 */
	public void setUseHeaderColumn( final String useHeaderColumn ) {
		putParam( "useHeaderColumn",
				  nval( getRequestParameter( useHeaderColumn ),"false" ) );
	}
}
