/*
 * $Id: IndexTermBrowserPanel.java,v 1.4 2006/01/26 16:38:10 rampil Exp $
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2005 satoshi akabane(akabane@logical-paradox.org)
 *
 */
package org.logical_paradox.koike.rss.tools.itb;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.logical_paradox.common.swing.WindowPanel;
import org.logical_paradox.koike.rss.tools.DataSourceException;
import org.logical_paradox.koike.rss.tools.itb.search.Query;
import org.logical_paradox.koike.rss.tools.itb.search.QueryRecord;
import org.logical_paradox.koike.rss.tools.itb.search.Select;

/**
 * 索引語ブラウザパネル
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.4 $
 */
public class IndexTermBrowserPanel extends WindowPanel implements ActionListener {
	/** シリアルバージョンUID */
	private static final long serialVersionUID = -7596674902738418508L;

	/** ロガー */
	private static final Log log = LogFactory.getLog(IndexTermBrowserPanel.class);

	/*
	 * GUIプロパティ
	 * これらのフィールドには，indexTermBrowserPanel.termInputField
	 * のようにアクセスする．
	 */
	/** 検索結果テーブル */
	public JTable wordListTable;
	/** 検索結果リスト */
	public IndexTermWordListTableModel wordListTableModel;
	/** 索引語入力フィールド */
	public JTextField termInputField;
	/** rownum開始位置入力フィールド */
	public JTextField rownumFromInputField;
	/** rownum終了位置入力フィールド */
	public JTextField rownumToInputField;
	/** 検索ボタン */
	public JButton btnSearch;

	/** 次ページボタン */
	public JButton btnNextPage;
	/** 前ページボタン */
	public JButton btnPrevPage;

	/** 検索結果数 */
	public JLabel labelTotalRecords;

	/** レコード選択ロジック */
	private Select select;

	/**
	 * コンストラクタ．
	 */
	public IndexTermBrowserPanel() {
		init();
	}
	/**
	 * このパネルを初期化する．
	 */
	protected void init() {
		setLayout(new BorderLayout());

		// 検索条件パネル
		JPanel searchConditionPanel = new JPanel();
		searchConditionPanel.setBorder(BorderFactory.createTitledBorder("search condition"));
		searchConditionPanel.setLayout(new BorderLayout());
		JPanel conditionMainPanel = new JPanel();
		conditionMainPanel.setLayout(new BoxLayout(conditionMainPanel, BoxLayout.X_AXIS));
		conditionMainPanel.add(new JLabel("  term  "));
		termInputField = new JTextField();
		conditionMainPanel.add(termInputField);
		conditionMainPanel.add(new JLabel("  rownum from  "));
		rownumFromInputField = new JTextField();
		conditionMainPanel.add(rownumFromInputField);
		conditionMainPanel.add(new JLabel("  to  "));
		rownumToInputField = new JTextField();
		conditionMainPanel.add(rownumToInputField);

		searchConditionPanel.add(conditionMainPanel, BorderLayout.CENTER);

		btnSearch = new JButton("search");
		btnSearch.addActionListener(this);
		searchConditionPanel.add(btnSearch, BorderLayout.EAST);

		add(searchConditionPanel, BorderLayout.NORTH);

		// 検索結果一覧
		JScrollPane wordListPane = new JScrollPane();
		wordListTableModel = new IndexTermWordListTableModel();
		wordListTable = new JTable(wordListTableModel);
		wordListPane.getViewport().setView(wordListTable);

		add(wordListPane, BorderLayout.CENTER);

		// 前ページ次ページパネル
		JPanel pageSelectionPanel = new JPanel();
		pageSelectionPanel.setLayout(new BorderLayout());
		JPanel pageSelBtnPanel = new JPanel();
		pageSelBtnPanel.setLayout(new GridLayout(1, 2));

		btnNextPage = new JButton("next");
		btnPrevPage = new JButton("prev");
		btnNextPage.setEnabled(false);
		btnPrevPage.setEnabled(false);

		pageSelBtnPanel.add(btnPrevPage);
		pageSelBtnPanel.add(btnNextPage);
		pageSelectionPanel.add(pageSelBtnPanel, BorderLayout.WEST);
		labelTotalRecords = new JLabel(""); 
		pageSelectionPanel.add(labelTotalRecords, BorderLayout.EAST);
		add(pageSelectionPanel, BorderLayout.SOUTH);
	}
	/**
	 * ボタン押下時のイベントハンドラ
	 * @param e イベントオブジェクト
	 */
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == btnSearch) {
			executeSearch();
		}
	}

	/**
	 * 検索を実行する．
	 */
	protected void executeSearch() {
		log.trace("検索を開始します");
		// 検索ボタン押下時
		try {
			// レコード検索ロジックをロード後初期化する．
			select = (Select)Class.forName(BrowserProperties.getProperty("select.class")).newInstance();
			select.open(BrowserProperties.getProperty("select.param.init"));
		} catch(Exception ex) {
			log.error("レコード選択ロジックのインスタンス化に失敗しました:", ex);
		}

		// 検索条件を生成する
		Query query = new Query();
		String term = termInputField.getText().trim();
		String rownumFrom = rownumFromInputField.getText().trim();
		String rownumTo = rownumToInputField.getText().trim();

		// 索引語
		query.setTerm(term);
		// 開始位置
		query.setFrom(rownumFrom.length() == 0 ? Query.NaN : Integer.parseInt(rownumFrom));
		// 終了位置
		query.setTo(rownumTo.length() == 0 ? Query.NaN : Integer.parseInt(rownumTo));

		// 検索実行
		int resultCount = 0;
		QueryRecord[] results = null;
		try {
			resultCount = select.countQuery(query);
			results = select.executeQuery(query);

			log.trace("検索結果数: " + resultCount);

			// 表示系の更新
			labelTotalRecords.setText(resultCount + " 件");
			rownumFromInputField.setText("" + query.getFrom());
			rownumToInputField.setText("" + query.getTo());

			// ボタンの有効性設定
			boolean enablePreviousBtn = query.getFrom() > 0;
			boolean enableNextBtn = resultCount >= query.getTo();
			btnPrevPage.setEnabled(enablePreviousBtn);
			btnNextPage.setEnabled(enableNextBtn);

			btnPrevPage.validate();
			btnNextPage.validate();

			// 検索結果表の設定
			wordListTableModel.setResults(results == null ? new QueryRecord[0] : results);
			wordListTable.revalidate();
		} catch(DataSourceException e) {
			log.error("検索に失敗しました：", e);
		}
	}
	/**
	 * 終了処理．
	 * アプリケーションで使用していた全てのリソースを安全に解放する．
	 */
	public void close() {
		log.trace("終了処理開始");
		if(select != null) {
			try {
				select.close();
			} catch(DataSourceException dse) {
				log.warn("データソース接続の解放に失敗しましたが，無視して処理は続行します：", dse);
			}
		}
		log.trace("終了処理完了");
	}
}
