/*
 * 作成日: 2007/08/20
 */
package asandatabasebrowser.view;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.table.AbstractTableModel;

import asandatabasebrowser.Global;
import asandatabasebrowser.AsanDatabaseBrowser;
import asandatabasebrowser.action.ExecuteCommitAction;
import asandatabasebrowser.action.ExecuteQueryAction;
import asandatabasebrowser.action.RecordDeleteAction;
import asandatabasebrowser.action.RecordEditCancelAction;
import asandatabasebrowser.action.RecordExecuteAction;
import asandatabasebrowser.action.RecordInsertAction;
import asandatabasebrowser.action.RecordInsertSelectAction;
import asandatabasebrowser.action.RecordUpdateAction;
import asandatabasebrowser.action.TabAddAction;
import asandatabasebrowser.action.TabRemoveAction;
import asandatabasebrowser.model.DbData;
import asandatabasebrowser.model.DbException;
import asandatabasebrowser.model.TableInfo;

import net.sourceforge.swingx.SxOptionPane;
import net.sourceforge.swingx.SxUtilities;
import net.sourceforge.swingx.jspread.JSpread;
import net.sourceforge.swingx.jspread.JSpreadSelectionEvent;
import net.sourceforge.swingx.jspread.JSpreadSelectionListener;


public class DbTableFrame2 extends JFrame implements IMenuEnable {
	public final TableInfo tableInfo;
//	DbData data;
	final String defaultSql;
	// view
	public final DbTableView tableView;
	DbRecordView recordView = null;
	JTabbedTextArea textarea;
	
	ExecuteQueryAction queryAction;
	Action recordInsertAction;
	Action recordInsertSelectAction;
	Action recordUpdateAction;
	Action recordDeleteAction;
	Action recordEditCancelAction;
	Action recordExecuteAction;
	Action executeCommitAction;
	Action executeRollbackAction;
	Action openSqlFrameAction;
	Action tabAddAction;
	Action tabRemoveAction;
	
	public DbTableFrame2(TableInfo tableInfo) throws DbException {
		assert tableInfo!=null;
		this.tableInfo = tableInfo;
		tableInfo.updateColumnInfoList();
        setIconImage(Global.getImage("/resources/TableView.png"));
 
        defaultSql = "select * from "+tableInfo.getSqlTableName();
        DbData data = tableInfo.db.queryTable(tableInfo, defaultSql, true);
         // ３つのビューを作成。レイアウトする。
       	tableView = new DbTableView(data);
		recordView = new DbRecordView(data.tableInfo.getDatabase());
		recordView.setRecord(tableInfo, null);
		textarea = new JTabbedTextArea(tableInfo.db, new SqlKeyListener());
		textarea.addTextArea("-- ここにwhere句以降を記述してください");
		JSplitPane sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
		sp2.setLeftComponent(tableView);
		sp2.setRightComponent(new JScrollPane(recordView));
		sp2.setOneTouchExpandable(true);
		sp2.setResizeWeight(0.7);
		
		JSplitPane sp1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
		getContentPane().setLayout(new BorderLayout());
		JPanel top = new JPanel(new BorderLayout());
		// SELECT文の前半を作成。選択可能にするため、JLabelではなくJTextFieldに。
		JTextField label = new JTextField(defaultSql);
		label.setEditable(false);
		label.setBorder(null);
		SxUtilities.addPopupMenuMouseListener(label);
		label.setFont(AsanDatabaseBrowser.theApp.doc.getFont());
		
		top.add(label, BorderLayout.NORTH);
		top.add(textarea, BorderLayout.CENTER);
		sp1.setTopComponent(top);
		sp1.setBottomComponent(sp2);
		sp1.setOneTouchExpandable(true);
		sp1.setResizeWeight(0.25);

		this.getContentPane().setLayout(new BorderLayout());
		getContentPane().add(sp1, BorderLayout.CENTER);

		queryAction = new ExecuteQueryAction(this);
		recordInsertAction = new RecordInsertAction(this);
		recordInsertSelectAction = new RecordInsertSelectAction(this);
		recordUpdateAction = new RecordUpdateAction(this);
		recordDeleteAction = new RecordDeleteAction(this);
		recordEditCancelAction = new RecordEditCancelAction(this);
		recordExecuteAction = new RecordExecuteAction(this);
		executeCommitAction = new ExecuteCommitAction(this, tableInfo.db, "commit", null);
		executeRollbackAction = new ExecuteCommitAction(this, tableInfo.db, "rollback", null);
		openSqlFrameAction = new OpenSqlFrameAction(AsanDatabaseBrowser.theApp);
		tabAddAction = new TabAddAction(textarea);
		tabRemoveAction = new TabRemoveAction(textarea);

		// ツールバーを作る
		JToolBar toolbar = new JToolBar();
        toolbar.setFloatable(false);
        toolbar.setRollover(true);
		toolbar.add(queryAction);
		toolbar.addSeparator();
		toolbar.add(recordInsertAction);
		toolbar.add(recordInsertSelectAction);
		toolbar.add(recordUpdateAction);
		toolbar.add(recordDeleteAction);
		toolbar.add(recordEditCancelAction);
        toolbar.addSeparator();
		toolbar.add(recordExecuteAction);
        toolbar.addSeparator();
        toolbar.add(executeCommitAction);
        toolbar.add(executeRollbackAction);
        toolbar.addSeparator();
		toolbar.add(openSqlFrameAction);
        toolbar.addSeparator();
		toolbar.add(tabAddAction);
		toolbar.add(tabRemoveAction);
		this.getContentPane().add(toolbar, BorderLayout.NORTH);
		// 連動
		tableView.addSelectionListener(new TableSelectionListener());
		// 表示。
		setTitle(tableInfo.getSqlTableName()+" ("+data.getRecordCount()+" records)");
		setSize(640, 480);
		//setVisible(true);
		updateActionState();
		// TODO:フォーカスをもう少しうまくする。
        //tableView.grabFocus();
        tableView.getComponent("CellPane").grabFocus();
        System.out.println("FocusCol="+tableView.getFocusColumn()+
        					" FocusRow="+tableView.getFocusRow()+
        					" CurCol="+tableView.getCurrentColumn()+
        					" CurRow="+tableView.getCurrentRow());
	}
	public String getSql() {
		return defaultSql + " " + textarea.getCurrentText();
	}
	public void setData(DbData data) {
		tableView.updateData(data);
		((AbstractTableModel) recordView.getModel()).fireTableDataChanged();
		setTitle(tableInfo.getSqlTableName()+" ("+data.getRecordCount()+" records)");
	}

	/** 再描画する。 */
	public void refresh() {
//		((AbstractTableModel) tableView.getModel()).fireTableStructureChanged();
		((AbstractTableModel) recordView.getModel()).fireTableDataChanged();
	}
    /** メニュー、ツールボタンの有効/無効を切り替える。 */
    public void updateActionState() {
    	System.out.println("updateActionState() enter");
    	// すべてのレコードに対して、
    	boolean isSelectedEditingRecord = false;	// 編集のレコードが選択されているか？
    	boolean existsEditingRecord = false;	// 
    	boolean hasSelect = false;

		boolean[] sel = tableView.getSheet().getSelectionArray(JSpread.ROW);
		DbData data = tableView.data;
		for (int i=0; i<data.getRecordCount(); i++) {
			boolean is_select = sel[i];
			if (data.getMode(i) != DbData.NONE) {
				existsEditingRecord = true;
				if (is_select) {
					isSelectedEditingRecord = true;
				}
			}
			if (is_select) hasSelect = true;
		}

    	queryAction.setEnabled(!existsEditingRecord);
    	recordInsertAction.setEnabled(true);
    	recordInsertSelectAction.setEnabled(hasSelect && ! isSelectedEditingRecord);
    	recordUpdateAction.setEnabled(hasSelect && ! isSelectedEditingRecord);
    	recordDeleteAction.setEnabled(hasSelect && ! isSelectedEditingRecord);
    	recordEditCancelAction.setEnabled(hasSelect && isSelectedEditingRecord);
    	recordExecuteAction.setEnabled(existsEditingRecord);
    	executeCommitAction.setEnabled(true);
    	executeRollbackAction.setEnabled(true);
    	openSqlFrameAction.setEnabled(true);
    	tabAddAction.setEnabled(true);
    	tabRemoveAction.setEnabled(textarea.getTabCount() > 1);
    }	
	/** Shift+Enterが押されたらSQLを実行します。*/
	class SqlKeyListener extends KeyAdapter {
		public void keyReleased(KeyEvent e) {
			//System.out.println(e);
			if (e.getKeyCode() == KeyEvent.VK_ENTER && e.isShiftDown()) {
				queryAction.executeQuery();
			}
		}
	}
	/** テーブルの行が選択されたとき */
	class TableSelectionListener implements JSpreadSelectionListener {
		public void valueChanged(JSpreadSelectionEvent e) {
			//System.out.println(e);
			DbData data = tableView.data;
			int index = e.nextCurRow;
			if (0 <= index && index < data.getRecordCount()) {
				Object[] rec = data.getRecord(index);
				recordView.setRecord(data.tableInfo, rec);
			} else {
				recordView.setRecord(data.tableInfo, null);
			}
			updateActionState();
		}
	}
	class OpenSqlFrameAction extends AbstractAction {
		AsanDatabaseBrowser tools;
		public OpenSqlFrameAction(AsanDatabaseBrowser tools) {
			super("SQLウィンドウ");
			putValue(SHORT_DESCRIPTION, "SQLウィンドウを開きます");
			putValue(LONG_DESCRIPTION, "SQLウィンドウルを開きます");
			putValue(SMALL_ICON, Global.getImageIcon("/resources/SQLView.png"));
			this.tools = tools;
		}
		public void actionPerformed(ActionEvent ev) {
			try {
				String sql = defaultSql + " " + textarea.getCurrentText();
				tools.openSqlFrame(tableInfo.db, sql);
				updateActionState();
			} catch (Exception e) {
				tools.showMessage(DbTableFrame2.this, "テーブルを開くことができません",
						e, SxOptionPane.ERROR_MESSAGE);
			}
		}
	}
}


