/*
 * 作成日: 2007/07/17
 */
package asandatabasebrowser.action;

import java.awt.event.ActionEvent;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;

import javax.swing.SwingUtilities;

import asandatabasebrowser.Global;
import asandatabasebrowser.AsanDatabaseBrowser;
import asandatabasebrowser.model.DbData;
import asandatabasebrowser.model.FavoriteTable;
import asandatabasebrowser.model.VvDatabase;
import asandatabasebrowser.view.DbDatabaseDefinitionFrame;

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

/**
 * データベース定義を開く.
 * 
 * @author Asan
 */
public class OpenDatabaseDefinitionAction extends SxHeavyAction {
	final AsanDatabaseBrowser tools;
	SxProgressDialog progressDialog;
	public OpenDatabaseDefinitionAction(AsanDatabaseBrowser tools) {
		super("データベース定義を開く");
		putValue(SHORT_DESCRIPTION, "データベース定義を開きます");
		putValue(LONG_DESCRIPTION, "データベース定義を開きます");
		putValue(SMALL_ICON, Global.getImageIcon("/resources/DatabaseDefinition.png"));
		this.tools = tools;
	}
	public void actionPerformed(ActionEvent e) {
		// 選択されたテーブル情報を取得する。
		VvDatabase db = null;
		int index = tools.getTreeFrame().tab.getSelectedIndex();
		if (index == 0) {
	    	db = tools.getTreeFrame().getTree().getSelectedDatabase(true);
		} else {
			Object obj = tools.getTreeFrame().getFavTree().getSelectionNodeObject();
			if (obj instanceof FavoriteTable) {
				FavoriteTable favtable = (FavoriteTable) obj;
				db = tools.doc.getDatabaseFromFavorite(favtable);
				if (db == null) {
					tools.showMessage(tools.getTreeFrame(),
							"指定されたデータベースがありません。:"+favtable.dbName, null, 
							SxOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		}
		if (db == null) return;	// 選択されていないとき
		if (db.getConnection() == null) {
			tools.showMessage(tools.getTreeFrame(),
					"データベースに接続されていません。:"+db.name, null, 
					SxOptionPane.ERROR_MESSAGE);
			return;
		}
		// 重い処理
		HeavyThread thread = new HeavyThread(db);
		progressDialog = new SxProgressDialog(tools.getTreeFrame(), 
    			"データベース定義の取得", thread, 0, 12);		// 12個
    	progressDialog.start();
	}

	class HeavyThread extends Thread {
		VvDatabase db;
		HeavyThread(VvDatabase db) {
			this.db = db;
		}
		public void run() {
			final ArrayList list = new ArrayList();
			DatabaseMetaData meta = db.getMetaData();
			
			int prog = 0;
	    	progressDialog.setProgress(prog++, "Catalogs");
	    	if (progressDialog.isAbort()) return;
	    	try {
				ResultSet rs = meta.getCatalogs();
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"Catalogs", data});
			} catch (Exception e) {
				list.add(new Object[] {"Catalogs", e});
			}
	    	
			progressDialog.setProgress(prog++, "Schemas");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getSchemas();
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"Schemas", data});
			} catch (Exception e) {
				list.add(new Object[] {"Schemas", e});
			}
	    	
			progressDialog.setProgress(prog++, "TableTypes");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getTableTypes();
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"TableTypes", data});
			} catch (Exception e) {
				list.add(new Object[] {"TableTypes", e});
			}		
			
	    	progressDialog.setProgress(prog++, "TypeInfo");
	    	if (progressDialog.isAbort()) return;
	    	try {
				ResultSet rs = meta.getTypeInfo();
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"TypeInfo", data});
			} catch (Exception e) {
				list.add(new Object[] {"TypeInfo", e});
			}		

	    	progressDialog.setProgress(prog++, "Attributes");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getAttributes(null, null, null, null);
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"Attributes", data});
			} catch (java.lang.UnsupportedOperationException ex) {
				list.add(new Object[] {"Attributes", ex});
			} catch (Exception e) {
				list.add(new Object[] {"Attributes", e});
			}
			
	    	progressDialog.setProgress(prog++, "Procedures");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getProcedures(null, null, null);
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"Procedures", data});
			} catch (Exception e) {
				list.add(new Object[] {"Procedures", e});
			}		

	    	progressDialog.setProgress(prog++, "ProcedureColumns");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getProcedureColumns(null, null, null, null);
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"ProcedureColumns", data});
			} catch (RuntimeException e) {
				list.add(new Object[] {"ProcedureColumns", e});
			} catch (Exception e) {
				list.add(new Object[] {"ProcedureColumns", e});
			}

	    	progressDialog.setProgress(prog++, "CrossReference");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getCrossReference(null, null, null, null, null, null);
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"CrossReference", data});
			} catch (Exception e) {
				list.add(new Object[] {"CrossReference", e});
			}				
				
	    	progressDialog.setProgress(prog++, "SuperTables");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getSuperTables(null, null, null);
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"SuperTables", data});
			} catch (java.lang.UnsupportedOperationException e) {
				list.add(new Object[] {"SuperTables", e});
			} catch (Exception e) {
				list.add(new Object[] {"SuperTables", e});
			}				

	    	progressDialog.setProgress(prog++, "SuperTypes");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getSuperTypes(null, null, null);
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"SuperTypes", data});
			} catch (java.lang.UnsupportedOperationException e) {
				list.add(new Object[] {"SuperTypes", e});
			} catch (Exception e) {
				list.add(new Object[] {"SuperTypes", e});
			}				

	    	progressDialog.setProgress(prog++, "Tables");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getTables(null, null, null, null);
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"Tables", data});
			} catch (Exception e) {
				list.add(new Object[] {"Tables", e});
			}				

	    	progressDialog.setProgress(prog++, "UDTs");
	    	if (progressDialog.isAbort()) return;
			try {
				ResultSet rs = meta.getUDTs(null, null, null, null);
				DbData data = new DbData(db.createResultSetInfo(rs), db.getRecordList(rs));
				list.add(new Object[] {"UDTs", data});
			} catch (java.lang.UnsupportedOperationException ex) {
				list.add(new Object[] {"UDTs", ex});
			} catch (Exception e) {
				list.add(new Object[] {"UDTs", e});
			}
			progressDialog.dispose();
			// イベントディスパッチスレッドでフォームを開く
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					tools.openFrame(new DbDatabaseDefinitionFrame(
							db.name, 
							Global.getImage("/resources/DatabaseDefinition.png"),
							list));
				}
			});
		}		
	}
	public void updateStatus() {
	}
}
