/*
 * Copyright (c) 1997, 2007, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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();
    }

    /**
     * Initializes JTableHeader properties such as 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 when a rollover column in the table
     * header is updated. Every look and feel that supports a rollover effect
     * in a 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) {
        // 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
