/*
 * Copyright (c) 2000, 2006, 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.
 *
 * 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.jvm.hotspot.ui;

import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.ui.table.*;
import sun.jvm.hotspot.ui.tree.*;

/** Lists objects along with their types */

public class ObjectListPanel extends SAPanel {
  private ObjectListTableModel dataModel;
  private JTable             table;
  private java.util.List     elements;
  private HeapProgressThunk  thunk;
  private boolean            checkedForArrays;
  private boolean            hasArrays;
  private int                numColumns;
  // For changing the text of the "Compute Liveness" button
  private JButton            livenessButton;
  private ActionListener     livenessButtonListener;
  private static final String showLivenessText = "Show Liveness";

  /** Takes a List<Oop> in constructor, and an optional
      HeapProgressThunk used if computing liveness */
  public ObjectListPanel(java.util.List els,
                         HeapProgressThunk thunk) {
    super();

    elements = els;
    this.thunk = thunk;
    computeNumColumns();

    setLayout(new BorderLayout());

    dataModel = new ObjectListTableModel();

    table = new JTable(dataModel);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    JTableHeader header = table.getTableHeader();
    header.setDefaultRenderer(new SortHeaderCellRenderer(header, dataModel));
    header.addMouseListener(new SortHeaderMouseAdapter(table, dataModel));

    JScrollPane scrollPane = new JScrollPane(table);
    add(scrollPane, BorderLayout.CENTER);

    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    Box box = Box.createHorizontalBox();
    box.add(Box.createGlue());
    JButton button = new JButton("Inspect");
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          fireShowInspector();
        }
      });
    box.add(button);

    box.add(Box.createHorizontalStrut(20));

    // Liveness button
    button = new JButton();
    livenessButton = button;
    if (VM.getVM().getRevPtrs() == null) {
      button.setText("Compute Liveness");
      livenessButtonListener = new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            fireComputeLiveness();
          }
        };
    } else {
      button.setText("Show Liveness Path");
      livenessButtonListener = new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            fireShowLiveness();
          }
        };
    }
    button.addActionListener(livenessButtonListener);
    box.add(button);
    box.add(Box.createGlue());
    panel.add(box);
    add(panel, BorderLayout.SOUTH);
  }

  //--------------------------------------------------------------------------------
  // Internals only below this point
  //

  private static class AddressWrapper implements Comparable {
    private Address address;

    private AddressWrapper(Address address) {
      this.address = address;
    }

    public String toString() {
      return address.toString();
    }

    public int compareTo(Object o) {
      AddressWrapper wrapper = (AddressWrapper) o;
      Address addr = wrapper.address;
      if (AddressOps.lessThan(address, addr)) return -1;
      if (AddressOps.greaterThan(address, addr)) return 1;
      return 0;
    }
  }

  private class ObjectListTableModel extends SortableTableModel {
    public ObjectListTableModel() {
      // Set the rows
      this.elements = ObjectListPanel.this.elements;
      setComparator(new ObjectListComparator(this));
    }

    public int getColumnCount() { return numColumns;      }
    public int getRowCount()    { return elements.size(); }
    public String getColumnName(int col) {
      switch (col) {
      case 0:
        return "Address";
      case 1:
        return "Oop";
      case 2:
        if (hasArrays) {
          return "Length";
        } else {
          return "Class Description";
        }
      case 3:
        if (hasArrays) {
          return "Class Description";
        } else if (VM.getVM().getRevPtrs() != null) {
          return "Liveness";
        }
      case 4:
        if (hasArrays && (VM.getVM().getRevPtrs() != null)) {
          return "Liveness";
        }
      }
      throw new RuntimeException("Index " + col + " out of bounds");
    }

    public Object getValueAt(int row, int col) {
      Oop oop = (Oop) elements.get(row);
      return getValueForColumn(oop, col);
    }

    public Object getValueForColumn(Oop oop, int col) {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();

      switch (col) {
      case 0:
        return new AddressWrapper(oop.getHandle());
      case 1:
        oop.printValueOn(new PrintStream(bos));
        break;
      case 2:
        if (hasArrays) {
          if (oop instanceof Array) {
            return new Long(((Array) oop).getLength());
          }
          return null;
        } else {
          oop.getKlass().printValueOn(new PrintStream(bos));
          break;
        }
      case 3:
        if (hasArrays) {
          oop.getKlass().printValueOn(new PrintStream(bos));
          break;
        } else {
          if (VM.getVM().getRevPtrs() != null) {
            if (VM.getVM().getRevPtrs().get(oop) != null) {
              return "Alive";
            } else {
              return "Dead";
            }
          }
        }
      case 4:
        if (hasArrays) {
          if (VM.getVM().getRevPtrs() != null) {
            if (VM.getVM().getRevPtrs().get(oop) != null) {
              return "Alive";
            } else {
              return "Dead";
            }
          }
        }
      default:
        throw new RuntimeException("Column " + col + " out of bounds");
      }

      return bos.toString();
    }

    private class ObjectListComparator extends TableModelComparator {
      public ObjectListComparator(ObjectListTableModel model) {
        super(model);
      }

      /**
       * Returns the value for the comparing object for the
       * column.
       *
       * @param obj Object that was passed for Comparator
       * @param column the column to retrieve
       */
      public Object getValueForColumn(Object obj, int column) {
        ObjectListTableModel omodel = (ObjectListTableModel)model;
        return omodel.getValueForColumn((Oop) obj, column);
      }
    }
  }

  private void fireShowInspector() {
    int i = table.getSelectedRow();
    if (i < 0) {
      return;
    }

    Oop oop = (Oop) elements.get(i);

    for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
      SAListener listener = (SAListener) iter.next();
      listener.showInspector(new OopTreeNodeAdapter(oop, null));
    }
  }

  private void fireComputeLiveness() {
    final Runnable cutoverButtonRunnable = new Runnable() {
        public void run() {
          livenessButton.removeActionListener(livenessButtonListener);
          livenessButtonListener = null;
          livenessButton.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                fireShowLiveness();
              }
            });
          computeNumColumns();
          livenessButton.setEnabled(true);
          livenessButton.setText(showLivenessText);
          dataModel.fireTableStructureChanged();
        }
      };


    if (VM.getVM().getRevPtrs() != null) {
      cutoverButtonRunnable.run();
    } else {
      final WorkerThread worker = new WorkerThread();
      worker.invokeLater(new Runnable() {
          public void run() {
            try {
              ReversePtrsAnalysis rev = new ReversePtrsAnalysis();
              if (thunk != null) {
                rev.setHeapProgressThunk(thunk);
              }
              rev.run();
              cutoverButtonRunnable.run();
            } finally {
              worker.shutdown();
            }
          }
        });
    }
  }

  private void fireShowLiveness() {
    if (VM.getVM().getRevPtrs() == null) {
      return;
    }

    int i = table.getSelectedRow();
    if (i < 0) {
      return;
    }

    Oop oop = (Oop) elements.get(i);
    LivenessPathList list = LivenessAnalysis.computeAllLivenessPaths(oop);
    if (list == null) {
      return; // dead object
    }

    for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
      SAListener listener = (SAListener) iter.next();
      listener.showLiveness(oop, list);
    }
  }

  private void checkForArrays() {
    if (checkedForArrays) return;
    checkedForArrays = true;
    for (Iterator iter = elements.iterator(); iter.hasNext(); ) {
      if (iter.next() instanceof Array) {
        hasArrays = true;
        return;
      }
    }
  }

  private void computeNumColumns() {
    checkForArrays();
    numColumns = 3;
    if (hasArrays)        ++numColumns;
    if (VM.getVM().getRevPtrs() != null)  ++numColumns;
  }
}
