/** 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.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.EmptyBorder;
import com.netscape.management.client.*;
import com.netscape.management.client.util.*;
import com.netscape.management.nmclf.*;

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

public class ActionMonitorPanel extends JPanel {

    static ResourceSet _resource;
    static String _i18nActionAborted, _i18nTooltipInterrupt;

    static {
        _resource = new ResourceSet("com.netscape.management.admserv.config.config");
        _i18nActionAborted = _resource.getString("actionmon", "ActionAborted");
        _i18nTooltipInterrupt = _resource.getString("actionmon", "TooltipInterrupt");
    }

    ThreadGroup _actionTG;
    JPanel _mainPanel;
    JLabel _lblStatus;
    JTextArea _txtStatus;
    ButtonBar _buttonBar;
    JButton _btnStop;
    ActionListener _stopListener = null;
    private static ActionMonitorPanel _activeInstance;
    boolean _multilinedStatus;

    public ActionMonitorPanel() {
        this(false);
    }

    public ActionMonitorPanel(boolean multilinedStatus) {

        //Dimension d = new Dimension(350,250);
        setLayout(new BorderLayout(12, 12));
        // setMinimumSize(d);
        //setPreferredSize(d);
        _multilinedStatus = multilinedStatus;
        createUILayout();
    }

    public static ActionMonitorPanel getActiveInstance() {
        return _activeInstance;
    }

    public boolean isMultilined() {
        return _multilinedStatus;
    }

    private void createUILayout() {
        createButtonBar();
        createMainPanel();
        add(_mainPanel, BorderLayout.CENTER);
        add(_buttonBar, BorderLayout.SOUTH);
    }

    public void createMainPanel() {
        _mainPanel = new JPanel(new BorderLayout());
        if (_multilinedStatus) {
            _txtStatus = new JTextArea(15, 40);
            _txtStatus.setBackground(
                    UIManager.getColor("Button.background")); //_btnStop.getBackground());
                    _txtStatus.setEditable(false);
            _mainPanel.add(new JScrollPane(_txtStatus));
            Dimension d = new Dimension(550, 250);
            setMinimumSize(d);
            setPreferredSize(d);

        } else {
            _mainPanel.add(_lblStatus = new JLabel(" ", JLabel.CENTER));
            Dimension d = new Dimension(350, 250);
            setMinimumSize(d);
            setPreferredSize(d);
        }
    }

    private void createButtonBar() {
        _buttonBar = new ButtonBar(new String[]{ButtonBar.cmdCancel},
                new String[]{ButtonBar._i18nCancelButton} , true);
        _btnStop = _buttonBar.getButton(ButtonBar.cmdCancel);
        _btnStop.setToolTipText(_i18nTooltipInterrupt);
        _buttonBar.addActionListener(_stopAction);
    }


    ActionListener _stopAction = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    ActionMonitorPanel.this.monitorProgressStop(
                            _i18nActionAborted);
                    if (_stopListener != null) {
                        _stopListener.actionPerformed(e);
                    }
                }
            };

    public void monitorProgressStart(String msg, ThreadGroup tg,
            ActionListener stopListener) {
        if (_activeInstance != null)
            _activeInstance.monitorProgressStop("");
        _actionTG = tg;
        _stopListener = stopListener;
        _btnStop.setEnabled(true);
        setActionBusyCursor(true, msg, _mainPanel);
        setStatusText(msg);
        _activeInstance = this;
        //Debug.println("Start Monitor");
    }


    public void setInterruptEnabled(boolean flag) {
        _btnStop.setEnabled(flag);
    }

    public synchronized void monitorProgressStop(String msg) {
        //Debug.println("Stop Monitor");
        if (_actionTG != null &&
                Thread.currentThread().getThreadGroup() != _actionTG) {
            // need to terminate _actionTG
            terminateActionThreadGroup();
        }

        setStatusText(msg);
        _btnStop.setEnabled(false);
        setActionBusyCursor(false, msg, _mainPanel);
        _actionTG = null;
        _activeInstance = null;
    }

    public synchronized void monitorProgressWaitForClose() {
        _btnStop.setLabel(ButtonBar._i18nCloseButton);
        JButtonFactory.initializeMnemonic(_btnStop);
        _btnStop.repaint();
        _btnStop.setToolTipText(null);
        setActionBusyCursor(false, "", _mainPanel);
        _activeInstance = null;
    }

    public void setStatusText(String text) {
        if (_multilinedStatus) {
            _txtStatus.append("\n");
            _txtStatus.append(text);
        } else {
            _lblStatus.setText(text);
        }
    }

    public void setStatusTextSameLIne(String text) {
        if (_multilinedStatus) {
            _txtStatus.append(text);
        } else {
            _lblStatus.setText(text);
        }
    }


    private void terminateActionThreadGroup() {
        Debug.println("Therminate Action Thread Group " +
                _actionTG.activeCount());

        // First interrrupt all active threads
        /*Thread[] threads = new Thread[_actionTG.activeCount()];
        _actionTG.enumerate(threads);
        for (int i=0; i < threads.length; i++) {
            Debug.println("Interrupting " + threads[i].getName());
            threads[i].interrupt();
    }*/
        // Then stop them all after a 0.5 sec delay. The delay is meant to give the
        // interrupted threads a chance to run and do some cleanup
        try {
            Thread.currentThread().sleep(500);
        } catch (Exception e) {}
        _actionTG.stop();
    }

    public void setActionBusyCursor(boolean busy, String text,
            Component c) {
        Cursor cursor = null;
        if (busy) {
            BaseConfigPanel.setProgressIndicator(this, text, -1, 0);
            cursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
        } else {
            BaseConfigPanel.clearProgressIndicator(this);
            cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
        }
        if (_txtStatus != null)
            _txtStatus.setCursor(cursor);
        if (_lblStatus != null)
            _lblStatus.setCursor(cursor);
        if (_btnStop.getParent() != null)
            _btnStop.getParent().setCursor(cursor);
    }
}
