/*
 * Copyright 1997-2007 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.swing.plaf.basic;

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

import sun.swing.*;

/**
 * BasicTableHeaderUI implementation
 *
 * @author Alan Chung
 * @author Philip Milne
 */
public class BasicTableHeaderUI extends TableHeaderUI {

    private static Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);

//
// Instance Variables
//

    /** The JTableHeader that is delegating the painting to this UI. */
    protected JTableHeader header;
    protected CellRendererPane rendererPane;

    // Listeners that are attached to the JTable
    protected MouseInputListener mouseInputListener;

    // The column header over which the mouse currently is.
    private int rolloverColumn = -1;

    // The column that should be highlighted when the table header has the focus.
    private int selectedColumnIndex = 0; // Read ONLY via getSelectedColumnIndex!

    private static FocusListener focusListener = new FocusListener() {
        public void focusGained(FocusEvent e) {
            repaintHeader(e.getSource());
        }

        public void focusLost(FocusEvent e) {
            repaintHeader(e.getSource());
        }

        private void repaintHeader(Object source) {
            if (source instanceof JTableHeader) {
                JTableHeader th = (JTableHeader)source;
                BasicTableHeaderUI ui =
                   (BasicTableHeaderUI)BasicLookAndFeel.
                                        getUIOfType(th.getUI(),
                                            BasicTableHeaderUI.class);
                if (ui == null) {
                    return;
                }

                th.repaint(th.getHeaderRect(ui.getSelectedColumnIndex()));
            }
        }
    };

    /**
     * This inner class is marked &quot;public&quot; due to a compiler bug.
     * This class should be treated as a &quot;protected&quot; inner class.
     * Instantiate it only within subclasses of BasicTableUI.
     */
    public class MouseInputHandler implements MouseInputListener {

        private int mouseXOffset;
        private Cursor otherCursor = resizeCursor;

        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() % 2 == 1 &&
                    SwingUtilities.isLeftMouseButton(e)){
                JTable table = header.getTable();
                RowSorter sorter;
                if (table != null && (sorter = table.getRowSorter()) != null) {
                    int columnIndex = header.columnAtPoint(e.getPoint());
                    if (columnIndex != -1) {
                        columnIndex = table.convertColumnIndexToModel(
                                            columnIndex);
                        sorter.toggleSortOrder(columnIndex);
                    }
                }
            }
        }

        private TableColumn getResizingColumn(Point p) {
            return getResizingColumn(p, header.columnAtPoint(p));
        }

        private TableColumn getResizingColumn(Point p, int column) {
            if (column == -1) {
                 return null;
            }
            Rectangle r = header.getHeaderRect(column);
            r.grow(-3, 0);
            if (r.contains(p)) {
                return null;
            }
            int midPoint = r.x + r.width/2;
            int columnIndex;
            if( header.getComponentOrientation().isLeftToRight() ) {
                columnIndex = (p.x < midPoint) ? column - 1 : column;
            } else {
                columnIndex = (p.x < midPoint) ? column : column - 1;
            }
            if (columnIndex == -1) {
                return null;
            }
            return header.getColumnModel().getColumn(columnIndex);
        }

        public void mousePressed(MouseEvent e) {
            header.setDraggedColumn(null);
            header.setResizingColumn(null);
            header.setDraggedDistance(0);

            Point p = e.getPoint();

            // First find which header cell was hit
            TableColumnModel columnModel = header.getColumnModel();
            int index = header.columnAtPoint(p);

            if (index != -1) {
                // The last 3 pixels + 3 pixels of next column are for resizing
                TableColumn resizingColumn = getResizingColumn(p, index);
                if (canResize(resizingColumn, header)) {
                    header.setResizingColumn(resizingColumn);
                    if( header.getComponentOrientation().isLeftToRight() ) {
                        mouseXOffset = p.x - resizingColumn.getWidth();
                    } else {
                        mouseXOffset = p.x + resizingColumn.getWidth();
                    }
                }
                else if (header.getReorderingAllowed()) {
                    TableColumn hitColumn = columnModel.getColumn(index);
                    header.setDraggedColumn(hitColumn);
                    mouseXOffset = p.x;
                }
            }

            if (header.getReorderingAllowed()) {
                int oldRolloverColumn = rolloverColumn;
                rolloverColumn = -1;
                rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);
            }
        }

        private void swapCursor() {
            Cursor tmp = header.getCursor();
            header.setCursor(otherCursor);
            otherCursor = tmp;
        }

        public void mouseMoved(MouseEvent e) {
            if (canResize(getResizingColumn(e.getPoint()), header) !=
                (header.getCursor() == resizeCursor)) {
                swapCursor();
            }
            updateRolloverColumn(e);
       }

        public void mouseDragged(MouseEvent e) {
            int mouseX = e.getX();

            TableColumn resizingColumn  = header.getResizingColumn();
            TableColumn draggedColumn  = header.getDraggedColumn();

            boolean headerLeftToRight = header.getComponentOrientation().isLeftToRight();

            if (resizingColumn != null) {
                int oldWidth = resizingColumn.getWidth();
                int newWidth;
                if (headerLeftToRight) {
                    newWidth = mouseX - mouseXOffset;
                } else  {
                    newWidth = mouseXOffset - mouseX;
                }
                mouseXOffset += changeColumnWidth(resizingColumn, header,
                                                  oldWidth, newWidth);
            }
            else if (draggedColumn != null) {
                TableColumnModel cm = header.getColumnModel();
                int draggedDistance = mouseX - mouseXOffset;
                int direction = (draggedDistance < 0) ? -1 : 1;
                int columnIndex = viewIndexForColumn(draggedColumn);
                int newColumnIndex = columnIndex + (headerLeftToRight ? direction : -direction);
                if (0 <= newColumnIndex && newColumnIndex < cm.getColumnCount()) {
                    int width = cm.getColumn(newColumnIndex).getWidth();
                    if (Math.abs(draggedDistance) > (width / 2)) {
                        JTable table = header.getTable();

                        mouseXOffset = mouseXOffset + direction * width;
                        header.setDraggedDistance(draggedDistance - direction * width);

                        //Cache the selected column.
                        int selectedIndex = table.convertColumnIndexToModel(
                                                        getSelectedColumnIndex());

                        //Now do the move.
                        cm.moveColumn(columnIndex, newColumnIndex);

                        //Update the selected index.
                        selectColumn(
                            table.convertColumnIndexToView(selectedIndex),
                            false);

                        return;
                    }
                }
                setDraggedDistance(draggedDistance, columnIndex);
            }

            updateRolloverColumn(e);
        }

        public void mouseReleased(MouseEvent e) {
            setDraggedDistance(0, viewIndexForColumn(header.getDraggedColumn()));

            header.setResizingColumn(null);
            header.setDraggedColumn(null);

            updateRolloverColumn(e);
        }

        public void mouseEntered(MouseEvent e) {
            updateRolloverColumn(e);
        }

        public void mouseExited(MouseEvent e) {
            int oldRolloverColumn = rolloverColumn;
            rolloverColumn = -1;
            rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);
        }
//
// Protected & Private Methods
//

        private void setDraggedDistance(int draggedDistance, int column) {
            header.setDraggedDistance(draggedDistance);
            if (column != -1) {
                header.getColumnModel().moveColumn(column, column);
            }
        }
    }

//
//  Factory methods for the Listeners
//

    /**
     * Creates the mouse listener for the JTableHeader.
     */
    protected MouseInputListener createMouseInputListener() {
        return new MouseInputHandler();
    }

//
//  The installation/uninstall procedures and support
//

    public static ComponentUI createUI(JComponent h) {
        return new BasicTableHeaderUI();
    }

//  Installation

    public void installUI(JComponent c) {
        header = (JTableHeader)c;

        rendererPane = new CellRendererPane();
        header.add(rendererPane);

        installDefaults();
        installListeners();
        installKeyboardActions();
    }

    /**
     * Initialize JTableHeader properties, e.g. font, foreground, and background.
     * The font, foreground, and background properties are only set if their
     * current value is either null or a UIResource, other properties are set
     * if the current value is null.
     *
     * @see #installUI
     */
    protected void installDefaults() {
        LookAndFeel.installColorsAndFont(header, "TableHeader.background",
                                         "TableHeader.foreground", "TableHeader.font");
        LookAndFeel.installProperty(header, "opaque", Boolean.TRUE);
    }

    /**
     * Attaches listeners to the JTableHeader.
     */
    protected void installListeners() {
        mouseInputListener = createMouseInputListener();

        header.addMouseListener(mouseInputListener);
        header.addMouseMotionListener(mouseInputListener);
        header.addFocusListener(focusListener);
    }

    /**
     * Register all keyboard actions on the JTableHeader.
     */
    protected void installKeyboardActions() {
        InputMap keyMap = (InputMap)DefaultLookup.get(header, this,
                "TableHeader.ancestorInputMap");
        SwingUtilities.replaceUIInputMap(header,
                                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap);
        LazyActionMap.installLazyActionMap(header, BasicTableHeaderUI.class,
                "TableHeader.actionMap");
    }

// Uninstall methods

    public void uninstallUI(JComponent c) {
        uninstallDefaults();
        uninstallListeners();
        uninstallKeyboardActions();

        header.remove(rendererPane);
        rendererPane = null;
        header = null;
    }

    protected void uninstallDefaults() {}

    protected void uninstallListeners() {
        header.removeMouseListener(mouseInputListener);
        header.removeMouseMotionListener(mouseInputListener);

        mouseInputListener = null;
    }

    /**
     * Unregisters default key actions.
     */
    protected void uninstallKeyboardActions() {
        SwingUtilities.replaceUIInputMap(header, JComponent.WHEN_FOCUSED, null);
        SwingUtilities.replaceUIActionMap(header, null);
    }

    /**
     * Populates TableHeader's actions.
     */
    static void loadActionMap(LazyActionMap map) {
        map.put(new Actions(Actions.TOGGLE_SORT_ORDER));
        map.put(new Actions(Actions.SELECT_COLUMN_TO_LEFT));
        map.put(new Actions(Actions.SELECT_COLUMN_TO_RIGHT));
        map.put(new Actions(Actions.MOVE_COLUMN_LEFT));
        map.put(new Actions(Actions.MOVE_COLUMN_RIGHT));
        map.put(new Actions(Actions.RESIZE_LEFT));
        map.put(new Actions(Actions.RESIZE_RIGHT));
        map.put(new Actions(Actions.FOCUS_TABLE));
    }

//
// Support for mouse rollover
//

    /**
     * Returns the index of the column header over which the mouse
     * currently is. When the mouse is not over the table header,
     * -1 is returned.
     *
     * @see #rolloverColumnUpdated(int, int)
     * @return the index of the current rollover column
     * @since 1.6
     */
    protected int getRolloverColumn() {
        return rolloverColumn;
    }

    /**
     * This method gets called every time the rollover column in the table
     * header is updated. Every look and feel supporting rollover effect
     * in table header should override this method and repaint the header.
     *
     * @param oldColumn the index of the previous rollover column or -1 if the
     * mouse was not over a column
     * @param newColumn the index of the new rollover column or -1 if the mouse
     * is not over a column
     * @see #getRolloverColumn()
     * @see JTableHeader#getHeaderRect(int)
     * @since 1.6
     */
    protected void rolloverColumnUpdated(int oldColumn, int newColumn) {
    }

    private void updateRolloverColumn(MouseEvent e) {
        if (header.getDraggedColumn() == null &&
            header.contains(e.getPoint())) {

            int col = header.columnAtPoint(e.getPoint());
            if (col != rolloverColumn) {
                int oldRolloverColumn = rolloverColumn;
                rolloverColumn = col;
                rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);
            }
        }
    }

//
// Support for keyboard and mouse access
//
    private int selectNextColumn(boolean doIt) {
        int newIndex = getSelectedColumnIndex();
        if (newIndex < header.getColumnModel().getColumnCount() - 1) {
            newIndex++;
            if (doIt) {
                selectColumn(newIndex);
            }
        }
        return newIndex;
    }

    private int selectPreviousColumn(boolean doIt) {
        int newIndex = getSelectedColumnIndex();
        if (newIndex > 0) {
            newIndex--;
            if (doIt) {
                selectColumn(newIndex);
            }
        }
        return newIndex;
    }

    /**
     * Selects the specified column in the table header. Repaints the
     * affected header cells and makes sure the newly selected one is visible.
     */
    void selectColumn(int newColIndex) {
        selectColumn(newColIndex, true);
    }

    void selectColumn(int newColIndex, boolean doScroll) {
        Rectangle repaintRect = header.getHeaderRect(selectedColumnIndex);
        header.repaint(repaintRect);
        selectedColumnIndex = newColIndex;
        repaintRect = header.getHeaderRect(newColIndex);
        header.repaint(repaintRect);
        if (doScroll) {
            scrollToColumn(newColIndex);
        }
        return;
    }
    /**
     * Used by selectColumn to scroll horizontally, if necessary,
     * to ensure that the newly selected column is visible.
     */
    private void scrollToColumn(int col) {
        Container container;
        JTable table;

        //Test whether the header is in a scroll pane and has a table.
        if ((header.getParent() == null) ||
            ((container = header.getParent().getParent()) == null) ||
            !(container instanceof JScrollPane) ||
            ((table = header.getTable()) == null)) {
            return;
        }

        //Now scroll, if necessary.
        Rectangle vis = table.getVisibleRect();
        Rectangle cellBounds = table.getCellRect(0, col, true);
        vis.x = cellBounds.x;
        vis.width = cellBounds.width;
        table.scrollRectToVisible(vis);
    }

    private int getSelectedColumnIndex() {
        int numCols = header.getColumnModel().getColumnCount();
        if (selectedColumnIndex >= numCols && numCols > 0) {
            selectedColumnIndex = numCols - 1;
        }
        return selectedColumnIndex;
    }

    private static boolean canResize(TableColumn column,
                                     JTableHeader header) {
        return (column != null) && header.getResizingAllowed()
                                && column.getResizable();
    }

    private int changeColumnWidth(TableColumn resizingColumn,
                                  JTableHeader th,
                                  int oldWidth, int newWidth) {
        resizingColumn.setWidth(newWidth);

        Container container;
        JTable table;

        if ((th.getParent() == null) ||
            ((container = th.getParent().getParent()) == null) ||
            !(container instanceof JScrollPane) ||
            ((table = th.getTable()) == null)) {
            return 0;
        }

        if (!container.getComponentOrientation().isLeftToRight() &&
                !th.getComponentOrientation().isLeftToRight()) {
                JViewport viewport = ((JScrollPane)container).getViewport();
                int viewportWidth = viewport.getWidth();
                int diff = newWidth - oldWidth;
                int newHeaderWidth = table.getWidth() + diff;

                /* Resize a table */
                Dimension tableSize = table.getSize();
                tableSize.width += diff;
                table.setSize(tableSize);

                /* If this table is in AUTO_RESIZE_OFF mode and
                 * has a horizontal scrollbar, we need to update
                 * a view's position.
                 */
                if ((newHeaderWidth >= viewportWidth) &&
                    (table.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF)) {
                    Point p = viewport.getViewPosition();
                    p.x = Math.max(0, Math.min(newHeaderWidth - viewportWidth,
                                               p.x + diff));
                    viewport.setViewPosition(p);
                    return diff;
            }
        }
        return 0;
    }

//
// Baseline
//

    /**
     * Returns the baseline.
     *
     * @throws NullPointerException {@inheritDoc}
     * @throws IllegalArgumentException {@inheritDoc}
     * @see javax.swing.JComponent#getBaseline(int, int)
     * @since 1.6
     */
    public int getBaseline(JComponent c, int width, int height) {
        super.getBaseline(c, width, height);
        int baseline = -1;
        TableColumnModel columnModel = header.getColumnModel();
        for(int column = 0; column < columnModel.getColumnCount();
            column++) {
            TableColumn aColumn = columnModel.getColumn(column);
            Component comp = getHeaderRenderer(column);
            Dimension pref = comp.getPreferredSize();
            int columnBaseline = comp.getBaseline(pref.width, height);
            if (columnBaseline >= 0) {
                if (baseline == -1) {
                    baseline = columnBaseline;
                }
                else if (baseline != columnBaseline) {
                    baseline = -1;
                    break;
                }
            }
        }
        return baseline;
    }

//
// Paint Methods and support
//

    public void paint(Graphics g, JComponent c) {
        if (header.getColumnModel().getColumnCount() <= 0) {
            return;
        }
        boolean ltr = header.getComponentOrientation().isLeftToRight();

        Rectangle clip = g.getClipBounds();
        Point left = clip.getLocation();
        Point right = new Point( clip.x + clip.width - 1, clip.y );
        TableColumnModel cm = header.getColumnModel();
        int cMin = header.columnAtPoint( ltr ? left : right );
        int cMax = header.columnAtPoint( ltr ? right : left );
        // This should never happen.
        if (cMin == -1) {
            cMin =  0;
        }
        // If the table does not have enough columns to fill the view we'll get -1.
        // Replace this with the index of the last column.
        if (cMax == -1) {
            cMax = cm.getColumnCount()-1;
        }

        TableColumn draggedColumn = header.getDraggedColumn();
        int columnWidth;
        Rectangle cellRect = header.getHeaderRect(ltr ? cMin : cMax);
        TableColumn aColumn;
        if (ltr) {
            for(int column = cMin; column <= cMax ; column++) {
                aColumn = cm.getColumn(column);
                columnWidth = aColumn.getWidth();
                cellRect.width = columnWidth;
                if (aColumn != draggedColumn) {
                    paintCell(g, cellRect, column);
                }
                cellRect.x += columnWidth;
            }
        } else {
            for(int column = cMax; column >= cMin; column--) {
                aColumn = cm.getColumn(column);
                columnWidth = aColumn.getWidth();
                cellRect.width = columnWidth;
                if (aColumn != draggedColumn) {
                    paintCell(g, cellRect, column);
                }
                cellRect.x += columnWidth;
            }
        }

        // Paint the dragged column if we are dragging.
        if (draggedColumn != null) {
            int draggedColumnIndex = viewIndexForColumn(draggedColumn);
            Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex);

            // Draw a gray well in place of the moving column.
            g.setColor(header.getParent().getBackground());
            g.fillRect(draggedCellRect.x, draggedCellRect.y,
                               draggedCellRect.width, draggedCellRect.height);

            draggedCellRect.x += header.getDraggedDistance();

            // Fill the background.
            g.setColor(header.getBackground());
            g.fillRect(draggedCellRect.x, draggedCellRect.y,
                       draggedCellRect.width, draggedCellRect.height);

            paintCell(g, draggedCellRect, draggedColumnIndex);
        }

        // Remove all components in the rendererPane.
        rendererPane.removeAll();
    }

    private Component getHeaderRenderer(int columnIndex) {
        TableColumn aColumn = header.getColumnModel().getColumn(columnIndex);
        TableCellRenderer renderer = aColumn.getHeaderRenderer();
        if (renderer == null) {
            renderer = header.getDefaultRenderer();
        }

        boolean hasFocus = !header.isPaintingForPrint()
                           && (columnIndex == getSelectedColumnIndex())
                           && header.hasFocus();
        return renderer.getTableCellRendererComponent(header.getTable(),
                                                aColumn.getHeaderValue(),
                                                false, hasFocus,
                                                -1, columnIndex);
    }

    private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) {
        Component component = getHeaderRenderer(columnIndex);
        rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
                            cellRect.width, cellRect.height, true);
    }

    private int viewIndexForColumn(TableColumn aColumn) {
        TableColumnModel cm = header.getColumnModel();
        for (int column = 0; column < cm.getColumnCount(); column++) {
            if (cm.getColumn(column) == aColumn) {
                return column;
            }
        }
        return -1;
    }

//
// Size Methods
//

    private int getHeaderHeight() {
        int height = 0;
        boolean accomodatedDefault = false;
        TableColumnModel columnModel = header.getColumnModel();
        for(int column = 0; column < columnModel.getColumnCount(); column++) {
            TableColumn aColumn = columnModel.getColumn(column);
            boolean isDefault = (aColumn.getHeaderRenderer() == null);

            if (!isDefault || !accomodatedDefault) {
                Component comp = getHeaderRenderer(column);
                int rendererHeight = comp.getPreferredSize().height;
                height = Math.max(height, rendererHeight);

                // Configuring the header renderer to calculate its preferred size
                // is expensive. Optimise this by assuming the default renderer
                // always has the same height as the first non-zero height that
                // it returns for a non-null/non-empty value.
                if (isDefault && rendererHeight > 0) {
                    Object headerValue = aColumn.getHeaderValue();
                    if (headerValue != null) {
                        headerValue = headerValue.toString();

                        if (headerValue != null && !headerValue.equals("")) {
                            accomodatedDefault = true;
                        }
                    }
                }
            }
        }
        return height;
    }

    private Dimension createHeaderSize(long width) {
        TableColumnModel columnModel = header.getColumnModel();
        // None of the callers include the intercell spacing, do it here.
        if (width > Integer.MAX_VALUE) {
            width = Integer.MAX_VALUE;
        }
        return new Dimension((int)width, getHeaderHeight());
    }


    /**
     * Return the minimum size of the header. The minimum width is the sum
     * of the minimum widths of each column (plus inter-cell spacing).
     */
    public Dimension getMinimumSize(JComponent c) {
        long width = 0;
        Enumeration enumeration = header.getColumnModel().getColumns();
        while (enumeration.hasMoreElements()) {
            TableColumn aColumn = (TableColumn)enumeration.nextElement();
            width = width + aColumn.getMinWidth();
        }
        return createHeaderSize(width);
    }

    /**
     * Return the preferred size of the header. The preferred height is the
     * maximum of the preferred heights of all of the components provided
     * by the header renderers. The preferred width is the sum of the
     * preferred widths of each column (plus inter-cell spacing).
     */
    public Dimension getPreferredSize(JComponent c) {
        long width = 0;
        Enumeration enumeration = header.getColumnModel().getColumns();
        while (enumeration.hasMoreElements()) {
            TableColumn aColumn = (TableColumn)enumeration.nextElement();
            width = width + aColumn.getPreferredWidth();
        }
        return createHeaderSize(width);
    }

    /**
     * Return the maximum size of the header. The maximum width is the sum
     * of the maximum widths of each column (plus inter-cell spacing).
     */
    public Dimension getMaximumSize(JComponent c) {
        long width = 0;
        Enumeration enumeration = header.getColumnModel().getColumns();
        while (enumeration.hasMoreElements()) {
            TableColumn aColumn = (TableColumn)enumeration.nextElement();
            width = width + aColumn.getMaxWidth();
        }
        return createHeaderSize(width);
    }

    private static class Actions extends UIAction {
        public static final String TOGGLE_SORT_ORDER =
            "toggleSortOrder";
        public static final String SELECT_COLUMN_TO_LEFT =
            "selectColumnToLeft";
        public static final String SELECT_COLUMN_TO_RIGHT =
            "selectColumnToRight";
        public static final String MOVE_COLUMN_LEFT =
            "moveColumnLeft";
        public static final String MOVE_COLUMN_RIGHT =
            "moveColumnRight";
        public static final String RESIZE_LEFT =
            "resizeLeft";
        public static final String RESIZE_RIGHT =
            "resizeRight";
        public static final String FOCUS_TABLE =
            "focusTable";

        public Actions(String name) {
            super(name);
        }

        public boolean isEnabled(Object sender) {
            if (sender instanceof JTableHeader) {
                JTableHeader th = (JTableHeader)sender;
                TableColumnModel cm = th.getColumnModel();
                if (cm.getColumnCount() <= 0) {
                    return false;
                }

                String key = getName();
                BasicTableHeaderUI ui =
                    (BasicTableHeaderUI)BasicLookAndFeel.getUIOfType(th.getUI(),
                                                      BasicTableHeaderUI.class);
                if (ui != null) {
                    if (key == MOVE_COLUMN_LEFT) {
                        return th.getReorderingAllowed()
                            && maybeMoveColumn(true, th, ui, false);
                    } else if (key == MOVE_COLUMN_RIGHT) {
                        return th.getReorderingAllowed()
                            && maybeMoveColumn(false, th, ui, false);
                    } else if (key == RESIZE_LEFT ||
                               key == RESIZE_RIGHT) {
                        return canResize(cm.getColumn(ui.getSelectedColumnIndex()), th);
                    } else if (key == FOCUS_TABLE) {
                        return (th.getTable() != null);
                    }
                }
            }
            return true;
        }

        public void actionPerformed(ActionEvent e) {
            JTableHeader th = (JTableHeader)e.getSource();
            BasicTableHeaderUI ui =
                (BasicTableHeaderUI)BasicLookAndFeel.
                                        getUIOfType(th.getUI(),
                                            BasicTableHeaderUI.class);
            if (ui == null) {
                return;
            }

            String name = getName();
            if (TOGGLE_SORT_ORDER == name) {
                JTable table = th.getTable();
                RowSorter sorter = table.getRowSorter();
                if (sorter != null) {
                    int columnIndex = ui.getSelectedColumnIndex();
                    columnIndex = table.convertColumnIndexToModel(
                                                      columnIndex);
                    sorter.toggleSortOrder(columnIndex);
                }
            } else if (SELECT_COLUMN_TO_LEFT == name) {
                if (th.getComponentOrientation().isLeftToRight()) {
                    ui.selectPreviousColumn(true);
                } else {
                    ui.selectNextColumn(true);
                }
            } else if (SELECT_COLUMN_TO_RIGHT == name) {
                if (th.getComponentOrientation().isLeftToRight()) {
                    ui.selectNextColumn(true);
                } else {
                    ui.selectPreviousColumn(true);
                }
            } else if (MOVE_COLUMN_LEFT == name) {
                moveColumn(true, th, ui);
            } else if (MOVE_COLUMN_RIGHT == name) {
                moveColumn(false, th, ui);
            } else if (RESIZE_LEFT == name) {
                resize(true, th, ui);
            } else if (RESIZE_RIGHT == name) {
                resize(false, th, ui);
            } else if (FOCUS_TABLE == name) {
                JTable table = th.getTable();
                if (table != null) {
                    table.requestFocusInWindow();
                }
            }
        }

        private void moveColumn(boolean leftArrow, JTableHeader th,
                                BasicTableHeaderUI ui) {
            maybeMoveColumn(leftArrow, th, ui, true);
        }

        private boolean maybeMoveColumn(boolean leftArrow, JTableHeader th,
                                        BasicTableHeaderUI ui, boolean doIt) {
            int oldIndex = ui.getSelectedColumnIndex();
            int newIndex;

            if (th.getComponentOrientation().isLeftToRight()) {
                newIndex = leftArrow ? ui.selectPreviousColumn(doIt)
                                     : ui.selectNextColumn(doIt);
            } else {
                newIndex = leftArrow ? ui.selectNextColumn(doIt)
                                     : ui.selectPreviousColumn(doIt);
            }

            if (newIndex != oldIndex) {
                if (doIt) {
                    th.getColumnModel().moveColumn(oldIndex, newIndex);
                } else {
                    return true; // we'd do the move if asked
                }
            }

            return false;
        }

        private void resize(boolean leftArrow, JTableHeader th,
                            BasicTableHeaderUI ui) {
            int columnIndex = ui.getSelectedColumnIndex();
            TableColumn resizingColumn =
                th.getColumnModel().getColumn(columnIndex);

            th.setResizingColumn(resizingColumn);
            int oldWidth = resizingColumn.getWidth();
            int newWidth = oldWidth;

            if (th.getComponentOrientation().isLeftToRight()) {
                newWidth = newWidth + (leftArrow ? -1 : 1);
            } else {
                newWidth = newWidth + (leftArrow ? 1 : -1);
            }

            ui.changeColumnWidth(resizingColumn, th, oldWidth, newWidth);
        }
    }
}  // End of Class BasicTableHeaderUI
