/*
 * AccountComponent.java
 *
 * Status: Functional
 *
 * Todo list:
 *   Add a MouseAdapter to switch to journal view on double-click.
 *   Add a ComboBox to jump to other accounts.
 *   Add a Button to Edit.
 */

package gui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;

import finance.Account;
import finance.AccountEntry;

import static finance.Account.DataModel.DATE_COL;
import static finance.Account.DataModel.DESC_COL;
import static finance.Account.DataModel.DEBIT_COL;
import static finance.Account.DataModel.CREDIT_COL;
import static finance.Account.DataModel.BALANCE_COL;
import static finance.Account.DataModel.COLUMN_COUNT;

/**
 * The user interface component for {@link Account Account}s.
 */
public final class AccountComponent extends JPanel
 {
  private static class CellRenderer extends JLabel implements TableCellRenderer
   {
    protected static Border selectedBorder = BorderFactory.createMatteBorder(1, 0, 1, 0, SystemColor.textHighlight);
    protected static Border unselectedBorder = BorderFactory.createEmptyBorder(1, 0, 1, 0);


    public CellRenderer()
     {
      super();
      setOpaque(true);
     }


    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
     {
      if(isSelected)
        setBorder(selectedBorder);
      else
        setBorder(unselectedBorder);

      setBackground(row % 2 == 0 ? Constants.bgRowEven : Constants.bgRowOdd);
      setFont(table.getFont());

      if(column >= DEBIT_COL)
        setHorizontalAlignment(SwingConstants.RIGHT);
      else
        setHorizontalAlignment(SwingConstants.LEFT);

      if(value instanceof AccountEntry)
       {
        AccountEntry entry = (AccountEntry)value;
        switch(column)
         {
          case DATE_COL:
            setText(Constants.dateShort.format(entry.getDate()));
            break;
          case DESC_COL:
            setText(entry.getDescription());
            break;
          case DEBIT_COL:
            setText(entry.getDebit());
            break;
          case CREDIT_COL:
            setText(entry.getCredit());
            break;
          case BALANCE_COL:
            if(entry.getBalanceType() != entry.getBalance().getType())
              setBackground(Constants.bgBalanceAbnormal);
            setText(entry.getBalanceString());
            break;
          default:
            setText("");
            break;
         }
       }
      else
       { setText(""); }

      return this;
     }
   }


  JTable table = null;
  /** The {@code Account} interfaced to by this {@code AccountComponent}. */
  Account account = null;


  /**
   * Constructs a new {@code AccountComponent}.
   *
   * @param account the {@code Account} interfaced to by this {@code
   * AccountComponent}.
   */
  public AccountComponent(Account account)
   {
    this.account = account;

    setLayout(new GridLayout(1, 1));

    table = new JTable(account.getDataModel());
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    table.getTableHeader().setReorderingAllowed(false);
    for(int i=0; i<table.getColumnCount(); i++)
     {
      TableColumn column = table.getColumnModel().getColumn(i);
      column.setCellRenderer(new CellRenderer());
      column.setResizable(false);
     }
    setColumnWidths();
    add(new JScrollPane(table));
    table.scrollRectToVisible(table.getCellRect(table.getRowCount()-1, 0, true));
   }


  /**
   * Called by the constructor to set the column widths for the table.
   */
  private void setColumnWidths()
   {
    java.util.Date date = null;
    String dateString = "26 Nov 2005";
    try
     {
      date = Constants.dateShort.parse("26 Nov 2005");
      dateString = Constants.dateShort.format(date);
     }
    catch(Exception ignored)
     { }
    String numberString = "$90,000.00";
    int dateWidth = 0;
    int numberWidth = 0;
    TableColumn column = null;

    try
     {
      Graphics2D g = Main.instance.getGraphicsConfiguration().createCompatibleImage(1, 1).createGraphics();
      dateWidth = (int)table.getFont().getStringBounds(dateString, g.getFontRenderContext()).getWidth();
      numberWidth = (int)table.getFont().getStringBounds(numberString, g.getFontRenderContext()).getWidth();
     }
    catch(Exception e)
     { return; }

    dateWidth *= 1.3;
    numberWidth *= 1.3;

    column = table.getColumnModel().getColumn(DATE_COL);
    column.setMinWidth(dateWidth);
    column.setMaxWidth(dateWidth);

    column = table.getColumnModel().getColumn(DEBIT_COL);
    column.setMinWidth(numberWidth);
    column.setMaxWidth(numberWidth);
    column = table.getColumnModel().getColumn(CREDIT_COL);
    column.setMinWidth(numberWidth);
    column.setMaxWidth(numberWidth);
    column = table.getColumnModel().getColumn(BALANCE_COL);
    column.setMinWidth(numberWidth);
    column.setMaxWidth(numberWidth);
   }
 }
