// ============================================================================
// File:               $File$
//
// Project:            
//
// Purpose:            
//
// Author:             Rammi
//
// Copyright Notice:   (c) 2008  Rammi (rammi@caff.de)
//                     This code is in the public domain.
//                     Use at own risk.
//                     No guarantees given.
//
// Latest change:      $Date$
//
// History:	       $Log$
//=============================================================================
package de.caff.asteroid.analysis;

import de.caff.asteroid.FrameInfo;
import de.caff.asteroid.FrameListener;
import de.caff.asteroid.GameData;
import de.caff.i18n.I18n;
import de.caff.util.Tools;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.UIResource;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.util.Collection;

/**
 *  Display the keys associated with an key frame info.
 *
 *  This class is part of a solution for a
 *  <a href="http://www.heise.de/ct/creativ/08/02/details/">competition by the German computer magazine c't</a>.
 */
public class KeyInfoDisplay
        extends JPanel
        implements GameData
{
  static {
    I18n.addAppResourceBase("de.caff.asteroid.analysis.resources.KeyInfoDisplay");
  }

  /** Show a boolean as a checkbox. */
  private static class BooleanRenderer extends JCheckBox implements TableCellRenderer, UIResource
  {
      private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

      public BooleanRenderer() {
          super();
          setHorizontalAlignment(JLabel.CENTER);
          setBorderPainted(true);
      }

      public Component getTableCellRendererComponent(JTable table, Object value,
                                                     boolean isSelected, boolean hasFocus, int row, int column) {
          if (isSelected) {
              setForeground(table.getSelectionForeground());
              super.setBackground(table.getSelectionBackground());
          }
          else {
              setForeground(table.getForeground());
              setBackground(table.getBackground());
          }
          setSelected((value != null && ((Boolean)value).booleanValue()));

          if (hasFocus) {
              setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
          } else {
              setBorder(noFocusBorder);
          }

          return this;
      }
  }
  /** Boolean renderer. */
  private static final BooleanRenderer KEY_RENDERER = new BooleanRenderer();

  /** The columns in the table. */
  private static final String[] COLUMNS = {
    I18n.getString("colPing"),
    I18n.getString("colTimestamp"),
    I18n.getString("colTimeToFrame"),
    I18n.getString("colButtonFire"),
    I18n.getString("colButtonHyper"),
    I18n.getString("colButtonThrust"),
    I18n.getString("colButtonLeft"),
    I18n.getString("colButtonRight"),
    I18n.getString("colButtonStart")
  };
  /** The table with the keys. */
  private JTable keyTable;

  /**
   *  Constructor.
   *  @param timeLine timeline
   */
  public KeyInfoDisplay(final TimeLine timeLine)
  {
    setLayout(new BorderLayout());
    keyTable = new JTable();
    keyTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);   // initially
    add(new JScrollPane(keyTable), BorderLayout.CENTER);
    setMinimumSize(new Dimension(400, 100));
    setPreferredSize(getMinimumSize());

    setFrom(timeLine.getCurrentInfo());
    timeLine.addFrameListener(new FrameListener() {
      public void frameReceived(FrameInfo frame)
      {
        setFrom(timeLine.getCurrentInfo());
      }
    });
    setBorder(BorderFactory.createTitledBorder(I18n.getString("brdButtons")));
  }

  /**
   *  Set table from frame info.
   *  @param info the frame info
   */
  private void setFrom(FrameKeyInfo info)
  {
    if (info != null) {
      Collection<FrameKeyInfo.ButtonInfo> buttons = info.getButtons();
      Object[][] data = new Object[buttons.size()][NR_BUTTONS + 2 + 1];
      int row = 0;
      for (FrameKeyInfo.ButtonInfo buttonInfo: buttons) {
        // Ping, timestamp, delta timestamp, FIRE, HYPER, THRUST, LEFT, RIGHT, START
        data[row][0] = Tools.byteToUnsigned(buttonInfo.getPingID());
        data[row][1] = buttonInfo.getTimestamp();
        data[row][2] = buttonInfo.getTimestamp() - info.getFrameInfo().getReceiveTime();
        data[row][3] = Boolean.valueOf(buttonInfo.getButtons().isFirePressed());
        data[row][4] = buttonInfo.getButtons().isHyperspacePressed();
        data[row][5] = buttonInfo.getButtons().isThrustPressed();
        data[row][6] = buttonInfo.getButtons().isLeftPressed();
        data[row][7] = buttonInfo.getButtons().isRightPressed();
        data[row][8] = buttonInfo.getButtons().isStartPressed();
        ++row;
      }
      keyTable.setModel(new DefaultTableModel(data, COLUMNS));
      for (int c = 3;  c < COLUMNS.length;  ++c) {
        keyTable.getColumnModel().getColumn(c).setCellRenderer(KEY_RENDERER);
      }
      if (keyTable.getAutoResizeMode() != JTable.AUTO_RESIZE_OFF) {
        keyTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        for (int c = 0;  c < COLUMNS.length;  ++c) {
          keyTable.sizeColumnsToFit(c);
        }
      }
    }
  }
}
