/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc.  Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * END COPYRIGHT BLOCK **/
package com.netscape.management.admserv.config;

import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import com.netscape.management.client.util.*;
import com.netscape.management.nmclf.*;

/**
  *
  * @version 0.1 11/28/97
  * @author miodrag@netscape.com
  */


/**
 * A tabbed pane which contains multiple PluginConfigPanels and behaves itself like
 * a PluginConfigPanel. It supports immediate or lazy creation mode of panels.
 * If the lazy creation mode is selected, a panel is created the first time its tab is
 * clicked.
 */
public abstract class TabbedConfigPanel extends PluginConfigPanel {

    /**
     * Creation modes : immediate (default) or lazy
     */
    public static final int IMMEDIATE_CREATE = 0;
    public static final int LAZY_CREATE = 1;

    int _createMode = IMMEDIATE_CREATE;

    Vector _tabs = new Vector();
    JTabbedPane _tabbedPane;
    public static Object _notCreatedTab;
    EditMonitor _editMonitor;


    /**
     * Constructors
     */
    public TabbedConfigPanel() {
        this(IMMEDIATE_CREATE);
    }

    public TabbedConfigPanel(int createMode) {
        _createMode = createMode;
        setLayout(new BorderLayout());
        setBorder(new EmptyBorder(0, 0, 0, 0));

        _tabbedPane = new JTabbedPane();
        try {
            _tabbedPane.setTabLayoutPolicy(_tabbedPane.SCROLL_TAB_LAYOUT);
        }
        catch (Throwable ignore) {
             //setTabLayoutPolicy is a JDK1.4 call, allow older JVMs
        }
        add(_tabbedPane, BorderLayout.CENTER);
        if (_createMode == LAZY_CREATE) {
            _tabbedPane.addChangeListener(_tabListener);
        }
    }


    /**
      * Return a vector of tab panels
      */
    public Vector getTabs() {
        return _tabs;
    }

    /**
      * Listen for tab selection changes
      */
    ChangeListener _tabListener = new ChangeListener() {
                public void stateChanged(ChangeEvent e) {
                    tabSelected(_tabbedPane.getSelectedIndex());
                }
            };

    /**
     * Callback when tab is selected. Create a tab if not already created
     * (lazy mode)
     */
    protected void tabSelected(int idx) {
        if (_tabs.elementAt(idx) == _notCreatedTab) {
            BaseConfigPanel bcp = BaseConfigPanel.getInstance(_tabbedPane);
            if (bcp != null)
                bcp.monitorLongAction(new CreateTabAction(idx));
            else
                (new CreateTabAction(idx)).run();
        } else {
            // Enable help button a for loaded tab
            enableHelpButton(true);
        }

    }

    /**
      * Create a new tab (lazy mode)
      */
    class CreateTabAction implements Runnable {
        int idx;
        public CreateTabAction(int idx) {
            this.idx = idx;
        }
        public void run() {
            setActionCursor(
                    Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            enableHelpButton(false);
            IPluginConfigPanel tab = lazyModeCreateTab(idx);

            try {
                tab.initialize();
            } catch (ConfigPanelException e) {
                ConfigErrorDialog.showDialog(_tabbedPane, e);
                return;
            }
            finally { setActionCursor(
                    Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            } tab.registerEditComponents(_editMonitor);
            _tabs.setElementAt(tab, idx);
            enableHelpButton(true);

            JPanel p = tab.getPanel();
            int insetH = SuiLookAndFeel.HORIZ_WINDOW_INSET;
            int insetV = SuiLookAndFeel.VERT_WINDOW_INSET;
            p.setBorder(new EmptyBorder(insetV, insetH, insetV, insetH));
            JScrollPane scrollPane = new JScrollPane(tab.getPanel());
            scrollPane.setBorder(BorderFactory.createEmptyBorder());
            _tabbedPane.setComponentAt(idx, scrollPane);

        }
    }


    /**
      * Add a tab to the panel
      */
    public void addTab(String title, ImageIcon icon,
            IPluginConfigPanel tab) {
        _tabs.addElement(tab);
        JPanel p = tab.getPanel();
        int insetH = SuiLookAndFeel.HORIZ_WINDOW_INSET;
        int insetV = SuiLookAndFeel.VERT_WINDOW_INSET;
        p.setBorder(new EmptyBorder(insetV, insetH, insetV, insetH));
        JScrollPane scrollPane = new JScrollPane(p);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        _tabbedPane.addTab(title, icon, scrollPane);
    }

    /**
      * Reserve a tab do not create it (lazy mode)
      */
    public int lazyModeReserveTab(String title, ImageIcon icon) {
        _tabbedPane.addTab(title, icon, new JLabel(" "));
        _tabs.addElement(_notCreatedTab);
        return _tabs.size() - 1;
    }

    /**
      * If lazy creation is selected this method must be overriden to create a panel
      * when a tab is clicked for the  first time.
      */
    public IPluginConfigPanel lazyModeCreateTab(int idx) {
        throw new Error("Not implemented"); // must be overriden if lazy mode used
    }

    // By default, tabbed panels do not have a title
    // Implements IpluginConfigPanel.getTitleText()
    public String getTitleText() {
        return null;
    }

    // Implements IpluginConfigPanel.initialize()
    public void initialize() throws ConfigPanelException {
        for (int i = 0; i < _tabs.size(); i++) {
            if (_tabs.elementAt(i) == _notCreatedTab)
                continue;
            IPluginConfigPanel tab = (IPluginConfigPanel)_tabs.elementAt(i);
            tab.initialize();
        }

        //Debug.println("tab count = " + _tabbedPane.getTabCount() + " " + Thread.currentThread().getName());
        _tabbedPane.setSelectedIndex(0);
        _tabbedPane.validate();
        _tabbedPane.repaint();
    }

    // Implements IpluginConfigPanel.setDataModel()
    public void setDataModel(IConfigDataModel dataModel)
            throws ConfigPanelException {
        for (int i = 0; i < _tabs.size(); i++) {
            if (_tabs.elementAt(i) == _notCreatedTab)
                continue;
            IPluginConfigPanel tab = (IPluginConfigPanel)_tabs.elementAt(i);
            tab.setDataModel(dataModel);
        }
    }

    // Implements IpluginConfigPanel.registerEditComponents()
    public void registerEditComponents(EditMonitor monitor) {
        _editMonitor = monitor;
        for (int i = 0; i < _tabs.size(); i++) {
            if (_tabs.elementAt(i) == _notCreatedTab)
                continue;
            IPluginConfigPanel tab = (IPluginConfigPanel)_tabs.elementAt(i);
            tab.registerEditComponents(monitor);
        }
    }

    // implements IpluginConfigPanel.resetContent()
    public void resetContent() throws ConfigPanelException {
        for (int i = 0; i < _tabs.size(); i++) {
            if (_tabs.elementAt(i) == _notCreatedTab)
                continue;
            IPluginConfigPanel tab = (IPluginConfigPanel)_tabs.elementAt(i);
            tab.resetContent();
        }
    }

    // Implements IpluginConfigPanel.applyChanges()
    public void applyChanges() throws ConfigPanelException {
        for (int i = 0; i < _tabs.size(); i++) {
            if (_tabs.elementAt(i) == _notCreatedTab)
                continue;
            IPluginConfigPanel tab = (IPluginConfigPanel)_tabs.elementAt(i);
            tab.applyChanges();
        }
    }

    // implements IpluginConfigPanel.showHelp()
    public void showHelp() {
        IPluginConfigPanel tab = (IPluginConfigPanel)_tabs.elementAt(
                _tabbedPane.getSelectedIndex());
        if (tab != _notCreatedTab) {
            tab.showHelp();
        }
    }

    /**
      * Change the cursor on the top-most window
      */
    protected void setActionCursor(Cursor cursor) {
        Component c = _tabbedPane;
        while (c != null &&
                ! (c instanceof JFrame || c instanceof JDialog)) {
            c = c.getParent();
        }
        if (c != null) {
            c.setCursor(cursor);
        }
    }

    /**
      * Change the state of the help button on the base panel's button bar
      */
    protected void enableHelpButton(boolean flag) {
        BaseConfigPanel bcp = BaseConfigPanel.getInstance(_tabbedPane);
        if (bcp != null) {
            if (bcp.getCommandButtonBar() != null) {
                JButton helpButton = bcp.getCommandButtonBar().getButton(
                        ButtonBar.cmdHelp);
                helpButton.setEnabled(flag);
            }
        }
    }
}
