/*
 * 作成日: 2005/10/02
 */
package asandatabasebrowser.action;

import java.awt.*;
import java.awt.event.ActionEvent;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;

import asandatabasebrowser.AsanDatabaseBrowser;
import asandatabasebrowser.model.DbException;
import asandatabasebrowser.model.VvDatabase;
import asandatabasebrowser.view.*;

import net.sourceforge.swingx.SxHeavyAction;
import net.sourceforge.swingx.SxOptionPane;
import net.sourceforge.swingx.SxProgressDialog;


/**
 * データベースに接続する。
 * @author Asan
 */
public class DatabaseConnectAction extends SxHeavyAction {
	AsanDatabaseBrowser tools;
	SxProgressDialog progressDialog;
	public DatabaseConnectAction(AsanDatabaseBrowser tools) {
		super("接続(C)");
		putValue(MNEMONIC_KEY, new Integer('C'));
		putValue(SHORT_DESCRIPTION, "データベースに接続");
		putValue(LONG_DESCRIPTION, "データベースに接続");
		this.tools = tools;
	}

    public void actionPerformed(ActionEvent ev) {
    	// 選択されているツリーを取得
    	DbTreeFrame treeFrame = tools.getTreeFrame();
    	DbTreeView tree = tools.getTreeFrame().getTree();
    	VvDatabase db = tree.getSelectedDatabase(false);
    	if (db == null) return;	// DBが選択されていない。
    	// すでに接続されているか？
    	if (db.getConnection() != null) return;

    	// デフォルトのユーザ
    	String user = db.user;
    	String pass = db.password;
    	// 接続時にユーザ名とパスワードを問い合わせるか？
    	if (db.isShowLoginDialog) {
        	ConnectDialog dialog = new ConnectDialog();
    		dialog.setDatabase(db);
            int ret = JOptionPane.showConfirmDialog(treeFrame, 
            	dialog,
                "データベースへの接続", 
                JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.PLAIN_MESSAGE);
 	    	if (ret != JOptionPane.OK_OPTION) return;	// キャンセル
	    	user = dialog.getUser();
	    	pass = dialog.getPass();
    	}
    	// 接続を別スレッドで行う。
    	ConnectThread thread = new ConnectThread(db, user, pass);
		progressDialog = new SxProgressDialog(treeFrame, 
    			"データベースへの接続", thread);
    	progressDialog.setProgress(10,
    			"<html><center>接続中...<br>データベース: "+db.name+
    			"<br>ユーザ名: "+user+"</center></html>");
    	progressDialog.start();		
    }
    
    class ConnectThread extends Thread {
    	VvDatabase db;
    	String user;
    	String pass;
    	ConnectThread(VvDatabase db, String user, String pass) {
    		this.db = db;
    		this.user = user;
    		this.pass = pass;
    	}
    	
    	public void run() {
        	final DbTreeFrame treeFrame = tools.getTreeFrame();
        	setMouseCursor(treeFrame, new Cursor(Cursor.WAIT_CURSOR));

        	try {
        		// ユーザから他の操作が行えないように、ダイアログをモーダルで開く。
        		// このダイアログをイベントディスパッチスレッドから呼ぶことはできない。
        		// なぜなら、イベントディスパッチスレッドでモーダルで開くと、
        		// そのダイアログを閉じない限り、次の処理に行かない。

				// 接続
				db.connect(user, pass);

		    	progressDialog.setProgress(80, "接続完了");
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						try {
							DbTreeView tree = treeFrame.getTree();
				        	DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getSelectionPath().getLastPathComponent();
				        	tree.接続したので枝を作る(node, db);
							treeFrame.updateMainFrame();
						} catch(DbException e) {
							tools.showMessage(treeFrame, 
									"データベースの接続に失敗しました:"+db.name, e, 
									SxOptionPane.OK_ONLY_OPTION, SxOptionPane.ERROR_MESSAGE);
						}
					}
				});
			} catch (DbException e) {
				tools.invokeShowMessage(treeFrame, 
						"データベースの接続に失敗しました:"+db.name, e, 
						SxOptionPane.OK_ONLY_OPTION, SxOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			} finally {
				if (progressDialog != null) progressDialog.dispose();
			}
			setMouseCursor(treeFrame, Cursor.getDefaultCursor());
    	}
    }
	public void updateStatus() {
	}
}

