/*
 * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.tools.jconsole;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.lang.management.*;
import java.lang.reflect.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.text.*;

import java.util.*;
import java.util.List;
import java.util.concurrent.*;

import sun.awt.*;

import static sun.tools.jconsole.Formatter.*;
import static sun.tools.jconsole.Resources.*;
import static sun.tools.jconsole.Utilities.*;


@SuppressWarnings("serial")
class ClassTab extends Tab implements ActionListener {
    PlotterPanel loadedClassesMeter;
    TimeComboBox timeComboBox;
    private JCheckBox verboseCheckBox;
    private HTMLPane details;
    private ClassOverviewPanel overviewPanel;
    private boolean plotterListening = false;

    private static final String loadedPlotterKey        = "loaded";
    private static final String totalLoadedPlotterKey   = "totalLoaded";
    private static final String loadedPlotterName       = Resources.getText("Loaded");
    private static final String totalLoadedPlotterName  = Resources.getText("Total Loaded");
    private static final Color  loadedPlotterColor      = Plotter.defaultColor;
    private static final Color  totalLoadedPlotterColor = Color.red;

    private static final String infoLabelFormat = "ClassTab.infoLabelFormat";

    /*
      Hierarchy of panels and layouts for this tab:

        ClassTab (BorderLayout)

            North:  topPanel (BorderLayout)

                        Center: controlPanel (FlowLayout)
                                    timeComboBox

                        East:   topRightPanel (FlowLayout)
                                    verboseCheckBox

            Center: plotterPanel (BorderLayout)

                        Center: plotter

            South:  bottomPanel (BorderLayout)

                        Center: details
    */

    public static String getTabName() {
        return Resources.getText("Classes");
    }

    public ClassTab(VMPanel vmPanel) {
        super(vmPanel, getTabName());

        setLayout(new BorderLayout(0, 0));
        setBorder(new EmptyBorder(4, 4, 3, 4));

        JPanel topPanel     = new JPanel(new BorderLayout());
        JPanel plotterPanel = new JPanel(new BorderLayout());
        JPanel bottomPanel  = new JPanel(new BorderLayout());

        add(topPanel,     BorderLayout.NORTH);
        add(plotterPanel, BorderLayout.CENTER);
        add(bottomPanel,  BorderLayout.SOUTH);

        JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
        topPanel.add(controlPanel, BorderLayout.CENTER);

        verboseCheckBox = new JCheckBox(Resources.getText("Verbose Output"));
        verboseCheckBox.addActionListener(this);
        verboseCheckBox.setToolTipText(getText("Verbose Output.toolTip"));
        JPanel topRightPanel = new JPanel();
        topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
        topRightPanel.add(verboseCheckBox);
        topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);

        loadedClassesMeter = new PlotterPanel(Resources.getText("Number of Loaded Classes"),
                                              Plotter.Unit.NONE, false);
        loadedClassesMeter.plotter.createSequence(loadedPlotterKey,
                                                  loadedPlotterName,
                                                  loadedPlotterColor,
                                                  true);
        loadedClassesMeter.plotter.createSequence(totalLoadedPlotterKey,
                                                  totalLoadedPlotterName,
                                                  totalLoadedPlotterColor,
                                                  true);
        setAccessibleName(loadedClassesMeter.plotter,
                          getText("ClassTab.loadedClassesPlotter.accessibleName"));
        plotterPanel.add(loadedClassesMeter);

        timeComboBox = new TimeComboBox(loadedClassesMeter.plotter);
        controlPanel.add(new LabeledComponent(Resources.getText("Time Range:"),
                                              getMnemonicInt("Time Range:"),
                                              timeComboBox));

        LabeledComponent.layout(plotterPanel);

        bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Resources.getText("Details")),
                                                  new EmptyBorder(10, 10, 10, 10)));

        details = new HTMLPane();
        setAccessibleName(details, getText("Details"));
        JScrollPane scrollPane = new JScrollPane(details);
        scrollPane.setPreferredSize(new Dimension(0, 150));
        bottomPanel.add(scrollPane, BorderLayout.SOUTH);

    }

    public void actionPerformed(ActionEvent ev) {
        final boolean b = verboseCheckBox.isSelected();
        workerAdd(new Runnable() {
            public void run() {
                ProxyClient proxyClient = vmPanel.getProxyClient();
                try {
                    proxyClient.getClassLoadingMXBean().setVerbose(b);
                } catch (UndeclaredThrowableException e) {
                    proxyClient.markAsDead();
                } catch (IOException ex) {
                    // Ignore
                }
            }
        });
    }


    public SwingWorker<?, ?> newSwingWorker() {
        final ProxyClient proxyClient = vmPanel.getProxyClient();

        if (!plotterListening) {
            proxyClient.addWeakPropertyChangeListener(loadedClassesMeter.plotter);
            plotterListening = true;
        }

        return new SwingWorker<Boolean, Object>() {
            private long clCount, cuCount, ctCount;
            private boolean isVerbose;
            private String detailsStr;
            private long timeStamp;

            public Boolean doInBackground() {
                try {
                    ClassLoadingMXBean classLoadingMBean = proxyClient.getClassLoadingMXBean();

                    clCount = classLoadingMBean.getLoadedClassCount();
                    cuCount = classLoadingMBean.getUnloadedClassCount();
                    ctCount = classLoadingMBean.getTotalLoadedClassCount();
                    isVerbose = classLoadingMBean.isVerbose();
                    detailsStr = formatDetails();
                    timeStamp = System.currentTimeMillis();

                    return true;
                } catch (UndeclaredThrowableException e) {
                    proxyClient.markAsDead();
                    return false;
                } catch (IOException e) {
                    return false;
                }
            }

            protected void done() {
                try {
                    if (get()) {
                        loadedClassesMeter.plotter.addValues(timeStamp, clCount, ctCount);

                        if (overviewPanel != null) {
                            overviewPanel.updateClassInfo(ctCount, clCount);
                            overviewPanel.getPlotter().addValues(timeStamp, clCount);
                        }

                        loadedClassesMeter.setValueLabel(clCount + "");
                        verboseCheckBox.setSelected(isVerbose);
                        details.setText(detailsStr);
                    }
                } catch (InterruptedException ex) {
                } catch (ExecutionException ex) {
                    if (JConsole.isDebug()) {
                        ex.printStackTrace();
                    }
                }
            }

            private String formatDetails() {
                String text = "<table cellspacing=0 cellpadding=0>";

                long time = System.currentTimeMillis();
                String timeStamp = formatDateTime(time);
                text += newRow(Resources.getText("Time"), timeStamp);
                text += newRow(Resources.getText("Current classes loaded"), justify(clCount, 5));
                text += newRow(Resources.getText("Total classes loaded"),   justify(ctCount, 5));
                text += newRow(Resources.getText("Total classes unloaded"), justify(cuCount, 5));

                return text;
            }
        };
    }


    OverviewPanel[] getOverviewPanels() {
        if (overviewPanel == null) {
            overviewPanel = new ClassOverviewPanel();
        }
        return new OverviewPanel[] { overviewPanel };
    }

    private static class ClassOverviewPanel extends OverviewPanel {
        ClassOverviewPanel() {
            super(getText("Classes"), loadedPlotterKey, loadedPlotterName, null);
        }

        private void updateClassInfo(long total, long loaded) {
            long unloaded = (total - loaded);
            getInfoLabel().setText(getText(infoLabelFormat, loaded, unloaded, total));
        }
    }
}
