/*
 * Copyright (c) 2004, 2007, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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));
        }
    }
}
