package asandatabasebrowser.action;

import java.awt.event.ActionEvent;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.JOptionPane;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import net.sourceforge.swingx.SxOptionPane;

import asandatabasebrowser.AsanDatabaseBrowser;
import asandatabasebrowser.model.DbException;
import asandatabasebrowser.model.FavoriteGroup;
import asandatabasebrowser.model.FavoriteTable;
import asandatabasebrowser.model.SchemaInfo;
import asandatabasebrowser.model.TableInfo;
import asandatabasebrowser.model.TableTypeInfo;
import asandatabasebrowser.model.VvDatabase;
import asandatabasebrowser.view.DbCountDialog;
import asandatabasebrowser.view.DbTreeView;
import asandatabasebrowser.view.FavoriteTree;

/**
 * レコード件数一覧画面
 * @author Yoshinori-Watanabe
 *
 */
public class CountListAction extends AbstractAction {
	AsanDatabaseBrowser tools;
	
	public CountListAction(AsanDatabaseBrowser tools) {
		super("レコード件数");
		putValue(SHORT_DESCRIPTION, 
				"選択されたテーブル、もしくはスキーマ/カタログにある全テーブルのレコード件数を表示します");
		putValue(LONG_DESCRIPTION, 
				"選択されたテーブル、もしくはスキーマ/カタログにある全テーブルのレコード件数を表示します");
		this.tools = tools;
	}

	public void actionPerformed(ActionEvent ev) {
		try {
			// 選択されたTableInfoを集める。
	        ArrayList list = new ArrayList();	// ArrayList<TableInfo>
			if (tools.getTreeFrame().tab.getSelectedIndex() == 0) {
		        // Databaseタブのとき、
				DbTreeView tree = tools.getTreeFrame().getTree();
				TreePath[] paths = tree.getSelectionPaths();
				for (int i=0; i<paths.length; i++) {
					DefaultMutableTreeNode node = (DefaultMutableTreeNode) paths[i].getLastPathComponent();
					Object obj = node.getUserObject();
					if (obj instanceof SchemaInfo) {
						SchemaInfo schema = (SchemaInfo) node.getUserObject();
				        for (int j=0; j<schema.getCount(); j++) {
				        	TableTypeInfo type = schema.getTableTypeInfo(j);
				        	for (int t=0; t<type.getCount(); t++) {
				        		if (! list.contains(type.getTableInfo(t)))
				        			list.add(type.getTableInfo(t));
				        	}
				        }
					} else if (obj instanceof TableTypeInfo) {
			        	TableTypeInfo type = (TableTypeInfo) obj;
			        	for (int t=0; t<type.getCount(); t++) {
			        		if (! list.contains(type.getTableInfo(t)))
			        			list.add(type.getTableInfo(t));
			        	}
					} else if (obj instanceof TableInfo) {
		        		if (! list.contains(obj))
		        			list.add(obj);
					}
				}
			} else {
				// お気に入りタブのとき、
				FavoriteTree tree = tools.getTreeFrame().getFavTree();
				Object[] objs = tree.getSelectionNodeObjects();
				if (objs == null) return;
				ArrayList favlist = new ArrayList();
				// FavoriteTableを集める。
				for (int i=0; i<objs.length; i++) {
					if (objs[i] instanceof FavoriteTable) {
						favlist.add(objs[i]);
					}
				}
				// FavoriteTableがなければ、FavoriteGroup内のFavoriteTableを集める。
				if (favlist.size() == 0) {
					for (int i=0; i<objs.length; i++) {
						if (objs[i] instanceof FavoriteGroup) {
							FavoriteGroup fg = (FavoriteGroup) objs[i];
							for (int g=0; g<fg.getCount(); g++) {
								favlist.add(fg.get(g));
							}
						}
					}
				}
				// TableInfoに変換する。
				for (int i=0; i<favlist.size(); i++) {
					FavoriteTable favtable = (FavoriteTable) favlist.get(i);
					VvDatabase db = tools.doc.getDatabaseFromFavorite(favtable);
					if (db == null) {
						tools.showMessage(tools.getTreeFrame(), 
									"指定されたDBが見つかりません。:"+favtable.dbName, null, 
									SxOptionPane.OK_ONLY_OPTION, SxOptionPane.ERROR_MESSAGE);
						return;
					}
					if (db.getConnection() == null) {
						tools.showMessage(tools.getTreeFrame(), 
								"指定されたDBは接続されていません。:"+favtable.dbName, null, 
								SxOptionPane.OK_ONLY_OPTION, SxOptionPane.ERROR_MESSAGE);
						return;
					}
					TableInfo t = tools.doc.getTableInfoFromFavorite(favtable);
					list.add(t);
				}
			}
						
			// 選択された TableInfo が空ならダメ
			if (list.size() == 0) return;
			// サイズが１ならメッセージボックスで、
			if (list.size() == 1) {
				TableInfo tableInfo = (TableInfo) list.get(0);
				int count = tableInfo.db.getRecordCount(tableInfo);
		        // ダイアログを表示する
				JOptionPane.showMessageDialog(tools.getTreeFrame(), 
						tableInfo.getSqlTableName() + "\n"+ count +" 件",
							"count(*)", JOptionPane.INFORMATION_MESSAGE);
			} else {
				// 複数の時にはダイアログを表示する
				DbCountDialog dialog = new DbCountDialog(tools.getTreeFrame(), list);
				dialog.pack();
				dialog.setVisible(true);				
			}
		}
		catch (DbException e) {
			tools.showMessage(tools.getTreeFrame(), 
					"レコード件数の取得に失敗しました", e, 
					SxOptionPane.OK_ONLY_OPTION, SxOptionPane.ERROR_MESSAGE);
		}
	}
	
}

