package asandatabasebrowser.view;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;

import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import net.sourceforge.swingx.SxAction;
import asandatabasebrowser.AsanDatabaseBrowser;
import asandatabasebrowser.Global;
import asandatabasebrowser.action.AboutAction;
import asandatabasebrowser.action.AsanDebugAction;
import asandatabasebrowser.action.CloseAllFrameAction;
import asandatabasebrowser.action.CountListAction;
import asandatabasebrowser.action.CreateDdlAction;
import asandatabasebrowser.action.DatabaseAddAction;
import asandatabasebrowser.action.DatabaseConnectAction;
import asandatabasebrowser.action.DatabaseDeleteAction;
import asandatabasebrowser.action.DatabaseDisconnectAction;
import asandatabasebrowser.action.DatabaseMetadataAction;
import asandatabasebrowser.action.DatabasePropertyAction;
import asandatabasebrowser.action.DatabaseRefreshAction;
import asandatabasebrowser.action.EnterAction;
import asandatabasebrowser.action.ExitAction;
import asandatabasebrowser.action.NodeDownAction;
import asandatabasebrowser.action.NodeUpAction;
import asandatabasebrowser.action.OpenDatabaseDefinitionAction;
import asandatabasebrowser.action.OpenExecuteFrameAction;
import asandatabasebrowser.action.OpenSqlFrameAction;
import asandatabasebrowser.action.OpenTableAction;
import asandatabasebrowser.action.OpenTableDefinitionAction;
import asandatabasebrowser.action.OptionAction;
import asandatabasebrowser.action.SqlLogViewAction;
import asandatabasebrowser.model.FavoriteTable;
import asandatabasebrowser.model.TableInfo;
import asandatabasebrowser.model.VvDatabase;


/** DBの中身をツリー上に表示する. */
public class DbTreeFrame extends JFrame {
	final AsanDatabaseBrowser tools;
    DbTreeView tree = null;
    public FavoriteTree favTree;
    public final JTabbedPane tab;
    Action databaseAddAction;
    Action databaseDeleteAction;
    public Action databaseConnectAction;
    Action databaseDisconnectAction;
    Action databasePropertyAction;
    Action databaseMetadataAction;
    Action databaseRefreshAction;
    Action exitAction;
    Action openSqlFrameAction;
    Action openExecuteFrameAction;
    public Action openTableAction;
    Action countListAction;
    Action closeAllFrameAction;
    Action sqlLogViewAction;
    Action optionAction;
    Action createDdlAction;
    Action enterAction;
    Action openTableDefinitionAction;
    Action openDatabaseDefinitionAction;
    SxAction nodeUpAction;
    SxAction nodeDownAction;
    
    public DbTreeFrame(AsanDatabaseBrowser tools) {
        super(AsanDatabaseBrowser.TITLE);
		setIconImage(Global.getImage("/resources/database.png"));
        this.tools = tools;
        tree = new DbTreeView(tools);
        this.getContentPane().setLayout(new BorderLayout());
        this.tab = new JTabbedPane(JTabbedPane.BOTTOM);
        tab.addTab("Database", Global.rootIcon, new JScrollPane(tree));
        favTree = new FavoriteTree(tools);
        tab.addTab("お気に入り", Global.favoriteIcon, new JScrollPane(favTree));
        this.getContentPane().add(tab, BorderLayout.CENTER);

        databaseAddAction = new DatabaseAddAction(tools); 
        databaseDeleteAction = new DatabaseDeleteAction(tools);
        databaseConnectAction = new DatabaseConnectAction(tools);  
        databaseDisconnectAction = new DatabaseDisconnectAction(tools);
        databasePropertyAction = new DatabasePropertyAction(tools);
        databaseMetadataAction = new DatabaseMetadataAction(tools);
        databaseRefreshAction = new DatabaseRefreshAction(tools);
        exitAction = new ExitAction(tools);
        openSqlFrameAction = new OpenSqlFrameAction(tools);
        openExecuteFrameAction = new OpenExecuteFrameAction(tools, tree);
        openTableAction = new OpenTableAction(tools);
        countListAction = new CountListAction(tools);
        closeAllFrameAction = new CloseAllFrameAction(tools);
        sqlLogViewAction = new SqlLogViewAction();
        optionAction = new OptionAction(tools);
        createDdlAction = new CreateDdlAction(tools);
        enterAction = new EnterAction();
        openTableDefinitionAction = new OpenTableDefinitionAction(tools);
        openDatabaseDefinitionAction = new OpenDatabaseDefinitionAction(tools);
        nodeUpAction = new NodeUpAction();
        nodeDownAction = new NodeDownAction();
        
        JToolBar toolbar = new JToolBar(AsanDatabaseBrowser.TITLE);
        toolbar.setFloatable(false);
        toolbar.setRollover(true);
        //toolbar.add(databaseAddAction);
        //toolbar.addSeparator();
        toolbar.add(databaseConnectAction);
        toolbar.add(databaseDisconnectAction);
        toolbar.addSeparator();
        toolbar.add(openTableAction);
        toolbar.add(openSqlFrameAction);
        toolbar.add(openExecuteFrameAction);
        toolbar.addSeparator();
        toolbar.add(nodeUpAction);
        toolbar.add(nodeDownAction);
        //toolbar.add(countListAction);
        //toolbar.add(new AboutAction(this));
        //toolbar.add(new EnableFilterAction(tools));
        this.getContentPane().add(toolbar, BorderLayout.NORTH);

        JMenuBar menubar = new JMenuBar();
        JMenu databaseMenu = new JMenu("データベース(D)");
        databaseMenu.setMnemonic('D');
        databaseMenu.add(databaseAddAction);
        databaseMenu.add(databaseDeleteAction);
        databaseMenu.addSeparator();
        databaseMenu.add(databaseConnectAction);
        databaseMenu.add(databaseDisconnectAction);
        databaseMenu.addSeparator();
        databaseMenu.add(databaseMetadataAction);
        databaseMenu.add(databasePropertyAction);
        databaseMenu.add(databaseRefreshAction);
        databaseMenu.addSeparator();
        databaseMenu.add(exitAction);
        menubar.add(databaseMenu);
//        JMenu viewMenu = new JMenu("表示(V)");
//        viewMenu.setMnemonic('V');
//        viewMenu.add(new JMenuItem(new EnableFilterAction(tools,"日本語",true)));
//        viewMenu.add(new JMenuItem(new EnableFilterAction(tools,"English", false)));
//        menubar.add(viewMenu);
        JMenu windowMenu = new JMenu("ウィンドウ(W)");
        windowMenu.setMnemonic('W');
        windowMenu.add(openTableAction);
        windowMenu.add(openSqlFrameAction);
        windowMenu.add(openExecuteFrameAction);
        windowMenu.addSeparator();
        windowMenu.add(new JCheckBoxMenuItem(sqlLogViewAction));
        windowMenu.addSeparator();
        //windowMenu.add(countListAction);
        //windowMenu.add(openTableDefinitionAction);
        //windowMenu.add(openDatabaseDefinitionAction);
        //windowMenu.addSeparator();
        windowMenu.add(closeAllFrameAction);
        windowMenu.addSeparator();
        windowMenu.add(optionAction);
        menubar.add(windowMenu);
        JMenu helpMenu = new JMenu("ヘルプ(H)");
        helpMenu.setMnemonic('H');
        if (System.getProperty("debug") != null) {
        	helpMenu.add(new AsanDebugAction());
        	helpMenu.addSeparator();
        }
        helpMenu.add(new AboutAction(this));
        menubar.add(helpMenu);
        this.setJMenuBar(menubar);
        
        // Databaseツリービューで Enter を押したときにDBに接続します。
        InputMap inputmap = tree.getInputMap();
        ActionMap actionmap = tree.getActionMap();
        inputmap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
        actionmap.put("enter", enterAction);
//        inputmap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Event.ALT_MASK), "databaseProperty");
//        actionmap.put("databaseProperty", databasePropertyAction);
        // お気に入りツリービューで Enter を押したとき
        inputmap = favTree.getInputMap();
        actionmap = favTree.getActionMap();
        actionmap.put("enter", enterAction);
        inputmap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
        
        
        this.setSize(300, 480);
        //this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        tree.grabFocus();
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				//System.out.println(e);
				AsanDatabaseBrowser.theApp.exitInstance();
			}
	        /**  ウィンドウが最小化された状態から通常の状態に変更されたときに呼び出されます。*/
			public void windowDeiconified(WindowEvent e) {
				System.out.println("windowDeiconified() "+e);
	        	List list = AsanDatabaseBrowser.theApp.getFrameList();
	        	for (int i=0; i<list.size(); i++) {
	        		JFrame frame = (JFrame) list.get(i);
	        		frame.setExtendedState(Frame.NORMAL);
	        	}
	        	SqlLogView logView = AsanDatabaseBrowser.theApp.logView;
	        	if (logView.isVisible()) {
	        		logView.setExtendedState(Frame.NORMAL);
	        	}
			}
	        /** ウィンドウが通常の状態から最小化された状態に変更されたときに呼び出されます。 */
	        public void windowIconified(WindowEvent e) {
				System.out.println("windowIconified() "+e);
	        	List list = AsanDatabaseBrowser.theApp.getFrameList();
	        	for (int i=0; i<list.size(); i++) {
	        		JFrame frame = (JFrame) list.get(i);
	        		frame.setExtendedState(Frame.ICONIFIED);
	        	}
	        	SqlLogView logView = AsanDatabaseBrowser.theApp.logView;
	        	if (logView.isVisible()) {
	        		logView.setExtendedState(Frame.ICONIFIED);
	        	}
	        }
	    });
		tab.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				updateMainFrame();
			}
		});
    }
    public DbTreeView getTree() { return tree; }
    public FavoriteTree getFavTree() { return favTree; }
    /** 再描画する。 */
    public void refresh() {
        ((DefaultTreeModel) tree.getModel()).reload();
        tree.updateUI();
//      ((AbstractTableModel) recordView.getModel()).fireTableDataChanged();
		updateMainFrame();
    }
    
    /** メニュー、ツールボタンの有効/無効を切り替える。 */
    public void updateMainFrame() {
        //databaseAddAction;
    	VvDatabase database = tree.getSelectedDatabase(true);
        if (tab.getSelectedIndex() == 0) {
        	databaseAddAction.setEnabled(true);
            databaseDeleteAction.setEnabled(database!=null && database.getConnection() == null);
            databaseConnectAction.setEnabled(database!=null && database.getConnection() == null);
            databaseDisconnectAction.setEnabled(database!=null && database.getConnection() != null);
            databasePropertyAction.setEnabled(database!=null);
            databaseMetadataAction.setEnabled(database!=null && database.getConnection() != null);
            databaseRefreshAction.setEnabled(database!=null && database.getConnection() != null);
	        TableInfo table = tree.getSelectedTableInfo();
	        openTableAction.setEnabled(table!=null);
	        openSqlFrameAction.setEnabled(table!=null);
	        openExecuteFrameAction.setEnabled(database != null && database.getConnection() != null);
	        openTableDefinitionAction.setEnabled(table!=null);
	        openDatabaseDefinitionAction.setEnabled(database != null && database.getConnection() != null);
	        TreePath path = tree.getSelectionPath();
	        countListAction.setEnabled(path!=null && path.getPathCount() >= 3);
        } else {
        	boolean isFavTable = favTree.getSelectionNodeObject() instanceof FavoriteTable;
        	databaseAddAction.setEnabled(false);
            databaseDeleteAction.setEnabled(false);
            databaseConnectAction.setEnabled(false);
            databaseDisconnectAction.setEnabled(false);
            databasePropertyAction.setEnabled(false);
            databaseMetadataAction.setEnabled(false);
            databaseRefreshAction.setEnabled(false);
	        openTableAction.setEnabled(isFavTable);
	        openSqlFrameAction.setEnabled(isFavTable);
	        openExecuteFrameAction.setEnabled(isFavTable);
	        openTableDefinitionAction.setEnabled(isFavTable);
	        openDatabaseDefinitionAction.setEnabled(isFavTable);
	        countListAction.setEnabled(isFavTable);
        }
        nodeUpAction.updateStatus();
        nodeDownAction.updateStatus();
        closeAllFrameAction.setEnabled(tools.getFrameList().size() > 0);
        // タイトルに'*'をつける。
        setTitle(AsanDatabaseBrowser.TITLE+(tools.doc.isModified() ? " *":""));
    }
}

