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

import org.opengion.fukurou.model.DataModelSorter;

import java.util.List;
import java.util.ArrayList;

/**
 * DBTableModelを継承した TableModelのソート機能の実装クラスです。
 *
 * ViewFormのヘッダーリンクをクリックすると、その項目について再ソートします。
 * これは、データベースではなく、メモリのDBTableModelにソート用のModelを
 * 用意し、そのModelの行番号のみをソートし、行変換を行います。
 * ソートを利用するかどうかは、システムパラメータ の、VIEW_USE_TABLE_SORTER 属性で
 * 指定します。(内部 システムパラメータ では、false 設定)
 * ヘッダー部に表示するリンクは、command=VIEW&amp;h_sortColumns=XXXXX で、カラム名を指定します。
 * ※ h_sortColumns 部は、HybsSystemにて定義しますので一般のJSPでは使用しないで下さい。
 *
 * DBTableModel インターフェースは，データベースの検索結果(Resultset)をラップする
 * インターフェースとして使用して下さい。
 *
 * @og.rev 7.0.1.2 (2018/11/04) 新規登録
 * @og.group テーブル管理
 *
 * @version  7.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK8.0,
 */
public class DBTableModelSorter extends DBTableModelImpl {
	private final DataModelSorter sorter = new DataModelSorter();

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

	/**
	 * DBTableModel を設定し、このオブジェクトを初期化します。
	 *
	 * @og.rev 7.0.1.2 (2018/11/04) 新規登録
	 *
	 * @param   model DBTableModelオブジェクト
	 */
	public void setModel( final DBTableModel model ) {
		final DBTableModelImpl impl = (DBTableModelImpl)model;
		dbColumns		= impl.dbColumns;
		names			= impl.names;
		data			= impl.data;
		rowHeader		= impl.rowHeader;
		columnMap		= impl.columnMap;
		overflow		= impl.overflow;
		numberOfColumns = impl.numberOfColumns;
		consistencyKey  = impl.consistencyKey;

		sorter.setModel( this );
	}

	/**
	 * カラム毎ソートのトップメソッドです。
	 * デフォルトで、昇順ソートを行います。
	 * 最後にソートしたカラムと同一のカラムが指定された場合、昇順と降順を
	 * 反転させて、再度ソートを行います。(シャトルソート)
	 *
	 * @og.rev 7.0.1.2 (2018/11/04) 新規登録
	 *
	 * @param column    カラム番号
	 */
	public void sortByColumn( final int column ) {
		final boolean isNumType = getDBColumn(column).isNumberType();			// 6.4.6.0 (2016/05/27)

		sorter.sortColumn( column,isNumType );
		modelChange();
	}

	/**
	 * カラム毎ソートのトップメソッドです。
	 * ascending フラグ[true:昇順/false:降順]を指定します。
	 *
	 * @og.rev 7.0.1.2 (2018/11/04) 新規登録
	 *
	 * @param column    カラム番号
	 * @param ascending  ソートの方向[true:昇順/false:降順]
	 */
	public void sortByColumn( final int column, final boolean ascending ) {
		// 6.4.4.2 (2016/04/01) contains 判定を行う新しいメソッドを使用します。
		final boolean isNumType = getDBColumn(column).isNumberType();			// 6.4.6.0 (2016/05/27)

		sorter.sortColumn( column,isNumType,ascending );
		modelChange();
	}

	/**
	 * デーブルモデルのデータとヘッダーをソート順に入れ替えます。
	 *
	 * @og.rev 7.0.1.2 (2018/11/04) 新規登録
	 */
	private void modelChange() {
		final int[] idx = sorter.getIndexes();

		final int rowCount = idx.length;

		final List<String[]>	newData		 = new ArrayList<>( rowCount );
		final List<DBRowHeader>	newRowHeader = new ArrayList<>( rowCount );

		for( int row=0; row<rowCount; row++ ) {
			newData.add( row,data.get( idx[row] ) );
			newRowHeader.add( row,rowHeader.get( idx[row] ) );
		}
		data      = newData;
		rowHeader = newRowHeader;
	}

	/**
	 * ソートの方向(昇順:true/降順:false)を取得します。
	 *
	 * @return  ソートの方向 [true:昇順/false:降順]
	 */
	public boolean isAscending() {
		return sorter.isAscending();
	}
}
