// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.resource.cre;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import org.infinity.datatype.DecNumber;
import org.infinity.datatype.HexNumber;
import org.infinity.datatype.ResourceRef;
import org.infinity.gui.ToolTipTableCellRenderer;
import org.infinity.gui.ViewFrame;
import org.infinity.icon.Icons;
import org.infinity.resource.Resource;
import org.infinity.resource.ResourceFactory;
import org.infinity.resource.StructEntry;
final class ViewerItems extends JPanel implements ActionListener, ListSelectionListener, TableModelListener
{
private final InventoryTableModel tableModel = new InventoryTableModel();
private final JButton bOpen;
private final JTable table;
private final List<StructEntry> slots = new ArrayList<StructEntry>();
ViewerItems(CreResource cre)
{
super(new BorderLayout(0, 3));
List<Item> items = new ArrayList<Item>();
HexNumber slots_offset = (HexNumber)cre.getAttribute(CreResource.CRE_OFFSET_ITEM_SLOTS);
for (int i = 0; i < cre.getFieldCount(); i++) {
StructEntry entry = cre.getField(i);
if (entry instanceof Item)
items.add((Item)entry);
else if (entry.getOffset() >= slots_offset.getValue() + cre.getOffset() &&
entry instanceof DecNumber
&& !entry.getName().equals(CreResource.CRE_SELECTED_WEAPON_SLOT)
&& !entry.getName().equals(CreResource.CRE_SELECTED_WEAPON_ABILITY))
slots.add(entry);
}
for (int i = 0; i < slots.size(); i++) {
DecNumber slot = (DecNumber)slots.get(i);
if (slot.getValue() >= 0 && slot.getValue() < items.size()) {
Item item = items.get(slot.getValue());
ResourceRef itemRef = (ResourceRef)item.getAttribute(Item.CRE_ITEM_RESREF);
tableModel.addEntry(slot.getName(), itemRef);
}
else
tableModel.addEntry(slot.getName(), null);
}
table = new JTable(tableModel);
table.setDefaultRenderer(Object.class, new ToolTipTableCellRenderer());
table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(this);
table.getColumnModel().getColumn(0).setMaxWidth(175);
table.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 2 && table.getSelectedRowCount() == 1) {
ResourceRef ref = (ResourceRef)tableModel.getValueAt(table.getSelectedRow(), 2);
if (ref != null) {
Resource res = ResourceFactory.getResource(
ResourceFactory.getResourceEntry(ref.getResourceName()));
new ViewFrame(getTopLevelAncestor(), res);
}
}
}
});
JScrollPane scroll = new JScrollPane(table);
bOpen = new JButton("View/Edit", Icons.getIcon(Icons.ICON_ZOOM_16));
bOpen.addActionListener(this);
// bOpen.setEnabled(tableModel.getRowCount() > 0);
table.getSelectionModel().setSelectionInterval(0, 0);
add(new JLabel("Items"), BorderLayout.NORTH);
add(scroll, BorderLayout.CENTER);
add(bOpen, BorderLayout.SOUTH);
cre.addTableModelListener(this);
}
// --------------------- Begin Interface ActionListener ---------------------
@Override
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == bOpen) {
ResourceRef ref = (ResourceRef)tableModel.getValueAt(table.getSelectedRow(), 1);
if (ref != null) {
Resource res = ResourceFactory.getResource(
ResourceFactory.getResourceEntry(ref.getResourceName()));
new ViewFrame(getTopLevelAncestor(), res);
}
}
}
// --------------------- End Interface ActionListener ---------------------
// --------------------- Begin Interface ListSelectionListener ---------------------
@Override
public void valueChanged(ListSelectionEvent event)
{
if (table.getSelectedRow() == -1)
bOpen.setEnabled(false);
else
bOpen.setEnabled(tableModel.getValueAt(table.getSelectedRow(), 1) != null);
}
// --------------------- End Interface ListSelectionListener ---------------------
// --------------------- Begin Interface TableModelListener ---------------------
@Override
public void tableChanged(TableModelEvent event)
{
if (event.getType() == TableModelEvent.UPDATE) {
CreResource cre = (CreResource)event.getSource();
Object changed = cre.getField(event.getFirstRow());
if (slots.contains(changed)) {
List<Item> items = new ArrayList<Item>();
for (int i = 0; i < cre.getFieldCount(); i++) {
StructEntry entry = cre.getField(i);
if (entry instanceof Item)
items.add((Item)entry);
}
table.clearSelection();
tableModel.clear();
for (int i = 0; i < slots.size(); i++) {
DecNumber slot = (DecNumber)slots.get(i);
if (slot.getValue() >= 0 && slot.getValue() < items.size()) {
Item item = items.get(slot.getValue());
ResourceRef itemRef = (ResourceRef)item.getAttribute(Item.CRE_ITEM_RESREF);
tableModel.addEntry(slot.getName(), itemRef);
}
else
tableModel.addEntry(slot.getName(), null);
}
tableModel.fireTableDataChanged();
table.getSelectionModel().setSelectionInterval(0, 0);
}
}
}
// --------------------- End Interface TableModelListener ---------------------
// -------------------------- INNER CLASSES --------------------------
private static final class InventoryTableModel extends AbstractTableModel
{
private final List<InventoryTableEntry> list = new ArrayList<InventoryTableEntry>();
private InventoryTableModel()
{
}
private void clear()
{
list.clear();
}
private void addEntry(String slot, ResourceRef item)
{
list.add(new InventoryTableEntry(slot, item));
}
@Override
public int getRowCount()
{
return list.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
InventoryTableEntry entry = list.get(rowIndex);
return (columnIndex == 0) ? entry.slot : entry.item;
}
@Override
public int getColumnCount()
{
return 2;
}
@Override
public String getColumnName(int column)
{
return (column == 0) ? "Slot" : "Item";
}
}
private static final class InventoryTableEntry
{
private final String slot;
private final ResourceRef item;
private InventoryTableEntry(String slot, ResourceRef item)
{
this.slot = slot;
this.item = item;
}
}
}