/*
 * Copyright 1997-2005 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 sun.swing.DefaultLookup;
import sun.swing.UIAction;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.plaf.*;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;

import java.awt.Component;
import java.awt.Container;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Insets;
import java.awt.Graphics;
import java.awt.event.*;
import java.io.Serializable;
import java.awt.Toolkit;
import java.awt.ComponentOrientation;

/**
 * A default L&F implementation of ScrollPaneUI.
 *
 * @author Hans Muller
 */
public class BasicScrollPaneUI
    extends ScrollPaneUI implements ScrollPaneConstants
{
    protected JScrollPane scrollpane;
    protected ChangeListener vsbChangeListener;
    protected ChangeListener hsbChangeListener;
    protected ChangeListener viewportChangeListener;
    protected PropertyChangeListener spPropertyChangeListener;
    private MouseWheelListener mouseScrollListener;

    /**
     * PropertyChangeListener installed on the vertical scrollbar.
     */
    private PropertyChangeListener vsbPropertyChangeListener;

    /**
     * PropertyChangeListener installed on the horizontal scrollbar.
     */
    private PropertyChangeListener hsbPropertyChangeListener;

    private Handler handler;

    /**
     * State flag that shows whether setValue() was called from a user program
     * before the value of "extent" was set in right-to-left component
     * orientation.
     */
    private boolean setValueCalled = false;


    public static ComponentUI createUI(JComponent x) {
        return new BasicScrollPaneUI();
    }

    static void loadActionMap(LazyActionMap map) {
        map.put(new Actions(Actions.SCROLL_UP));
        map.put(new Actions(Actions.SCROLL_DOWN));
        map.put(new Actions(Actions.SCROLL_HOME));
        map.put(new Actions(Actions.SCROLL_END));
        map.put(new Actions(Actions.UNIT_SCROLL_UP));
        map.put(new Actions(Actions.UNIT_SCROLL_DOWN));
        map.put(new Actions(Actions.SCROLL_LEFT));
        map.put(new Actions(Actions.SCROLL_RIGHT));
        map.put(new Actions(Actions.UNIT_SCROLL_RIGHT));
        map.put(new Actions(Actions.UNIT_SCROLL_LEFT));
    }



    public void paint(Graphics g, JComponent c) {
        Border vpBorder = scrollpane.getViewportBorder();
        if (vpBorder != null) {
            Rectangle r = scrollpane.getViewportBorderBounds();
            vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
        }
    }


    /**
     * @return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)
     */
    public Dimension getMaximumSize(JComponent c) {
        return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
    }


    protected void installDefaults(JScrollPane scrollpane)
    {
        LookAndFeel.installBorder(scrollpane, "ScrollPane.border");
        LookAndFeel.installColorsAndFont(scrollpane,
            "ScrollPane.background",
            "ScrollPane.foreground",
            "ScrollPane.font");

        Border vpBorder = scrollpane.getViewportBorder();
        if ((vpBorder == null) ||( vpBorder instanceof UIResource)) {
            vpBorder = UIManager.getBorder("ScrollPane.viewportBorder");
            scrollpane.setViewportBorder(vpBorder);
        }
        LookAndFeel.installProperty(scrollpane, "opaque", Boolean.TRUE);
    }


    protected void installListeners(JScrollPane c)
    {
        vsbChangeListener = createVSBChangeListener();
        vsbPropertyChangeListener = createVSBPropertyChangeListener();
        hsbChangeListener = createHSBChangeListener();
        hsbPropertyChangeListener = createHSBPropertyChangeListener();
        viewportChangeListener = createViewportChangeListener();
        spPropertyChangeListener = createPropertyChangeListener();

        JViewport viewport = scrollpane.getViewport();
        JScrollBar vsb = scrollpane.getVerticalScrollBar();
        JScrollBar hsb = scrollpane.getHorizontalScrollBar();

        if (viewport != null) {
            viewport.addChangeListener(viewportChangeListener);
        }
        if (vsb != null) {
            vsb.getModel().addChangeListener(vsbChangeListener);
            vsb.addPropertyChangeListener(vsbPropertyChangeListener);
        }
        if (hsb != null) {
            hsb.getModel().addChangeListener(hsbChangeListener);
            hsb.addPropertyChangeListener(hsbPropertyChangeListener);
        }

        scrollpane.addPropertyChangeListener(spPropertyChangeListener);

    mouseScrollListener = createMouseWheelListener();
    scrollpane.addMouseWheelListener(mouseScrollListener);

    }

    protected void installKeyboardActions(JScrollPane c) {
        InputMap inputMap = getInputMap(JComponent.
                                  WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        SwingUtilities.replaceUIInputMap(c, JComponent.
                               WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);

        LazyActionMap.installLazyActionMap(c, BasicScrollPaneUI.class,
                                           "ScrollPane.actionMap");
    }

    InputMap getInputMap(int condition) {
        if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
            InputMap keyMap = (InputMap)DefaultLookup.get(scrollpane, this,
                                        "ScrollPane.ancestorInputMap");
            InputMap rtlKeyMap;

            if (scrollpane.getComponentOrientation().isLeftToRight() ||
                    ((rtlKeyMap = (InputMap)DefaultLookup.get(scrollpane, this,
                    "ScrollPane.ancestorInputMap.RightToLeft")) == null)) {
                return keyMap;
            } else {
                rtlKeyMap.setParent(keyMap);
                return rtlKeyMap;
            }
        }
        return null;
    }

    public void installUI(JComponent x) {
        scrollpane = (JScrollPane)x;
        installDefaults(scrollpane);
        installListeners(scrollpane);
        installKeyboardActions(scrollpane);
    }


    protected void uninstallDefaults(JScrollPane c) {
        LookAndFeel.uninstallBorder(scrollpane);

        if (scrollpane.getViewportBorder() instanceof UIResource) {
            scrollpane.setViewportBorder(null);
        }
    }


    protected void uninstallListeners(JComponent c) {
        JViewport viewport = scrollpane.getViewport();
        JScrollBar vsb = scrollpane.getVerticalScrollBar();
        JScrollBar hsb = scrollpane.getHorizontalScrollBar();

        if (viewport != null) {
            viewport.removeChangeListener(viewportChangeListener);
        }
        if (vsb != null) {
            vsb.getModel().removeChangeListener(vsbChangeListener);
            vsb.removePropertyChangeListener(vsbPropertyChangeListener);
        }
        if (hsb != null) {
            hsb.getModel().removeChangeListener(hsbChangeListener);
            hsb.removePropertyChangeListener(hsbPropertyChangeListener);
        }

        scrollpane.removePropertyChangeListener(spPropertyChangeListener);

    if (mouseScrollListener != null) {
        scrollpane.removeMouseWheelListener(mouseScrollListener);
    }

        vsbChangeListener = null;
        hsbChangeListener = null;
        viewportChangeListener = null;
        spPropertyChangeListener = null;
        mouseScrollListener = null;
        handler = null;
    }


    protected void uninstallKeyboardActions(JScrollPane c) {
        SwingUtilities.replaceUIActionMap(c, null);
        SwingUtilities.replaceUIInputMap(c, JComponent.
                           WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
    }


    public void uninstallUI(JComponent c) {
        uninstallDefaults(scrollpane);
        uninstallListeners(scrollpane);
        uninstallKeyboardActions(scrollpane);
        scrollpane = null;
    }

    private Handler getHandler() {
        if (handler == null) {
            handler = new Handler();
        }
        return handler;
    }

    protected void syncScrollPaneWithViewport()
    {
        JViewport viewport = scrollpane.getViewport();
        JScrollBar vsb = scrollpane.getVerticalScrollBar();
        JScrollBar hsb = scrollpane.getHorizontalScrollBar();
        JViewport rowHead = scrollpane.getRowHeader();
        JViewport colHead = scrollpane.getColumnHeader();
        boolean ltr = scrollpane.getComponentOrientation().isLeftToRight();

        if (viewport != null) {
            Dimension extentSize = viewport.getExtentSize();
            Dimension viewSize = viewport.getViewSize();
            Point viewPosition = viewport.getViewPosition();

            if (vsb != null) {
                int extent = extentSize.height;
                int max = viewSize.height;
                int value = Math.max(0, Math.min(viewPosition.y, max - extent));
                vsb.setValues(value, extent, 0, max);
            }

            if (hsb != null) {
                int extent = extentSize.width;
                int max = viewSize.width;
                int value;

                if (ltr) {
                    value = Math.max(0, Math.min(viewPosition.x, max - extent));
                } else {
                    int currentValue = hsb.getValue();

                    /* Use a particular formula to calculate "value"
                     * until effective x coordinate is calculated.
                     */
                    if (setValueCalled && ((max - currentValue) == viewPosition.x)) {
                        value = Math.max(0, Math.min(max - extent, currentValue));
                        /* After "extent" is set, turn setValueCalled flag off.
                         */
                        if (extent != 0) {
                            setValueCalled = false;
                        }
                    } else {
                        if (extent > max) {
                            viewPosition.x = max - extent;
                            viewport.setViewPosition(viewPosition);
                            value = 0;
                        } else {
                           /* The following line can't handle a small value of
                            * viewPosition.x like Integer.MIN_VALUE correctly
                            * because (max - extent - viewPositoiin.x) causes
                            * an overflow. As a result, value becomes zero.
                            * (e.g. setViewPosition(Integer.MAX_VALUE, ...)
                            *       in a user program causes a overflow.
                            *       Its expected value is (max - extent).)
                            * However, this seems a trivial bug and adding a
                            * fix makes this often-called method slow, so I'll
                            * leave it until someone claims.
                            */
                            value = Math.max(0, Math.min(max - extent, max - extent - viewPosition.x));
                        }
                    }
                }
                hsb.setValues(value, extent, 0, max);
            }

            if (rowHead != null) {
                Point p = rowHead.getViewPosition();
                p.y = viewport.getViewPosition().y;
                p.x = 0;
                rowHead.setViewPosition(p);
            }

            if (colHead != null) {
                Point p = colHead.getViewPosition();
                if (ltr) {
                    p.x = viewport.getViewPosition().x;
                } else {
                    p.x = Math.max(0, viewport.getViewPosition().x);
                }
                p.y = 0;
                colHead.setViewPosition(p);
            }
        }
    }

    /**
     * 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) {
        JViewport viewport = scrollpane.getViewport();
        Insets spInsets = scrollpane.getInsets();
        int y = spInsets.top;
        height = height - spInsets.top - spInsets.bottom;
        width = width - spInsets.left - spInsets.right;
        JViewport columnHeader = scrollpane.getColumnHeader();
        if (columnHeader != null && columnHeader.isVisible()) {
            Component header = columnHeader.getView();
            if (header != null && header.isVisible()) {
                // Header is always given it's preferred size.
                Dimension headerPref = header.getPreferredSize();
                int baseline = header.getBaseline(headerPref.width,
                                                  headerPref.height);
                if (baseline >= 0) {
                    return y + baseline;
                }
            }
            Dimension columnPref = columnHeader.getPreferredSize();
            height -= columnPref.height;
            y += columnPref.height;
        }
        Component view = (viewport == null) ? null : viewport.getView();
        if (view != null && view.isVisible() &&
                view.getBaselineResizeBehavior() ==
                Component.BaselineResizeBehavior.CONSTANT_ASCENT) {
            Border viewportBorder = scrollpane.getViewportBorder();
            if (viewportBorder != null) {
                Insets vpbInsets = viewportBorder.getBorderInsets(scrollpane);
                y += vpbInsets.top;
                height = height - vpbInsets.top - vpbInsets.bottom;
                width = width - vpbInsets.left - vpbInsets.right;
            }
            if (view.getWidth() > 0 && view.getHeight() > 0) {
                Dimension min = view.getMinimumSize();
                width = Math.max(min.width, view.getWidth());
                height = Math.max(min.height, view.getHeight());
            }
            if (width > 0 && height > 0) {
                int baseline = view.getBaseline(width, height);
                if (baseline > 0) {
                    return y + baseline;
                }
            }
        }
        return -1;
    }

    /**
     * Returns an enum indicating how the baseline of the component
     * changes as the size changes.
     *
     * @throws NullPointerException {@inheritDoc}
     * @see javax.swing.JComponent#getBaseline(int, int)
     * @since 1.6
     */
    public Component.BaselineResizeBehavior getBaselineResizeBehavior(
            JComponent c) {
        super.getBaselineResizeBehavior(c);
        // Baseline is either from the header, in which case it's always
        // the same size and therefor can be created as CONSTANT_ASCENT.
        // If the header doesn't have a baseline than the baseline will only
        // be valid if it's BaselineResizeBehavior is
        // CONSTANT_ASCENT, so, return CONSTANT_ASCENT.
        return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
    }


    /**
     * Listener for viewport events.
     */
    public class ViewportChangeHandler implements ChangeListener
    {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        public void stateChanged(ChangeEvent e) {
            getHandler().stateChanged(e);
        }
    }

    protected ChangeListener createViewportChangeListener() {
        return getHandler();
    }


    /**
     * Horizontal scrollbar listener.
     */
    public class HSBChangeListener implements ChangeListener
    {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        public void stateChanged(ChangeEvent e)
        {
            getHandler().stateChanged(e);
        }
    }

    /**
     * Returns a <code>PropertyChangeListener</code> that will be installed
     * on the horizontal <code>JScrollBar</code>.
     */
    private PropertyChangeListener createHSBPropertyChangeListener() {
        return getHandler();
    }

    protected ChangeListener createHSBChangeListener() {
        return getHandler();
    }


    /**
     * Vertical scrollbar listener.
     */
    public class VSBChangeListener implements ChangeListener
    {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        public void stateChanged(ChangeEvent e)
        {
            getHandler().stateChanged(e);
        }
    }


    /**
     * Returns a <code>PropertyChangeListener</code> that will be installed
     * on the vertical <code>JScrollBar</code>.
     */
    private PropertyChangeListener createVSBPropertyChangeListener() {
        return getHandler();
    }

    protected ChangeListener createVSBChangeListener() {
        return getHandler();
    }

    /**
     * MouseWheelHandler is an inner class which implements the
     * MouseWheelListener interface.  MouseWheelHandler responds to
     * MouseWheelEvents by scrolling the JScrollPane appropriately.
     * If the scroll pane's
     * <code>isWheelScrollingEnabled</code>
     * method returns false, no scrolling occurs.
     *
     * @see javax.swing.JScrollPane#isWheelScrollingEnabled
     * @see #createMouseWheelListener
     * @see java.awt.event.MouseWheelListener
     * @see java.awt.event.MouseWheelEvent
     * @since 1.4
     */
    protected class MouseWheelHandler implements MouseWheelListener {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        /**
         * Called when the mouse wheel is rotated while over a
         * JScrollPane.
         *
         * @param e     MouseWheelEvent to be handled
         * @since 1.4
         */
        public void mouseWheelMoved(MouseWheelEvent e) {
            getHandler().mouseWheelMoved(e);
        }
    }

    /**
     * Creates an instance of MouseWheelListener, which is added to the
     * JScrollPane by installUI().  The returned MouseWheelListener is used
     * to handle mouse wheel-driven scrolling.
     *
     * @return      MouseWheelListener which implements wheel-driven scrolling
     * @see #installUI
     * @see MouseWheelHandler
     * @since 1.4
     */
    protected MouseWheelListener createMouseWheelListener() {
        return getHandler();
    }

    protected void updateScrollBarDisplayPolicy(PropertyChangeEvent e) {
        scrollpane.revalidate();
        scrollpane.repaint();
    }


    protected void updateViewport(PropertyChangeEvent e)
    {
        JViewport oldViewport = (JViewport)(e.getOldValue());
        JViewport newViewport = (JViewport)(e.getNewValue());

        if (oldViewport != null) {
            oldViewport.removeChangeListener(viewportChangeListener);
        }

        if (newViewport != null) {
            Point p = newViewport.getViewPosition();
            if (scrollpane.getComponentOrientation().isLeftToRight()) {
                p.x = Math.max(p.x, 0);
            } else {
                int max = newViewport.getViewSize().width;
                int extent = newViewport.getExtentSize().width;
                if (extent > max) {
                    p.x = max - extent;
                } else {
                    p.x = Math.max(0, Math.min(max - extent, p.x));
                }
            }
            p.y = Math.max(p.y, 0);
            newViewport.setViewPosition(p);
            newViewport.addChangeListener(viewportChangeListener);
        }
    }


    protected void updateRowHeader(PropertyChangeEvent e)
    {
        JViewport newRowHead = (JViewport)(e.getNewValue());
        if (newRowHead != null) {
            JViewport viewport = scrollpane.getViewport();
            Point p = newRowHead.getViewPosition();
            p.y = (viewport != null) ? viewport.getViewPosition().y : 0;
            newRowHead.setViewPosition(p);
        }
    }


    protected void updateColumnHeader(PropertyChangeEvent e)
    {
        JViewport newColHead = (JViewport)(e.getNewValue());
        if (newColHead != null) {
            JViewport viewport = scrollpane.getViewport();
            Point p = newColHead.getViewPosition();
            if (viewport == null) {
                p.x = 0;
            } else {
                if (scrollpane.getComponentOrientation().isLeftToRight()) {
                    p.x = viewport.getViewPosition().x;
                } else {
                    p.x = Math.max(0, viewport.getViewPosition().x);
                }
            }
            newColHead.setViewPosition(p);
            scrollpane.add(newColHead, COLUMN_HEADER);
        }
    }

    private void updateHorizontalScrollBar(PropertyChangeEvent pce) {
        updateScrollBar(pce, hsbChangeListener, hsbPropertyChangeListener);
    }

    private void updateVerticalScrollBar(PropertyChangeEvent pce) {
        updateScrollBar(pce, vsbChangeListener, vsbPropertyChangeListener);
    }

    private void updateScrollBar(PropertyChangeEvent pce, ChangeListener cl,
                                 PropertyChangeListener pcl) {
        JScrollBar sb = (JScrollBar)pce.getOldValue();
        if (sb != null) {
            if (cl != null) {
                sb.getModel().removeChangeListener(cl);
            }
            if (pcl != null) {
                sb.removePropertyChangeListener(pcl);
            }
        }
        sb = (JScrollBar)pce.getNewValue();
        if (sb != null) {
            if (cl != null) {
                sb.getModel().addChangeListener(cl);
            }
            if (pcl != null) {
                sb.addPropertyChangeListener(pcl);
            }
        }
    }

    public class PropertyChangeHandler implements PropertyChangeListener
    {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        public void propertyChange(PropertyChangeEvent e)
        {
            getHandler().propertyChange(e);
        }
    }



    /**
     * Creates an instance of PropertyChangeListener that's added to
     * the JScrollPane by installUI().  Subclasses can override this method
     * to return a custom PropertyChangeListener, e.g.
     * <pre>
     * class MyScrollPaneUI extends BasicScrollPaneUI {
     *    protected PropertyChangeListener <b>createPropertyChangeListener</b>() {
     *        return new MyPropertyChangeListener();
     *    }
     *    public class MyPropertyChangeListener extends PropertyChangeListener {
     *        public void propertyChange(PropertyChangeEvent e) {
     *            if (e.getPropertyName().equals("viewport")) {
     *                // do some extra work when the viewport changes
     *            }
     *            super.propertyChange(e);
     *        }
     *    }
     * }
     * </pre>
     *
     * @see java.beans.PropertyChangeListener
     * @see #installUI
     */
    protected PropertyChangeListener createPropertyChangeListener() {
        return getHandler();
    }


    private static class Actions extends UIAction {
        private static final String SCROLL_UP = "scrollUp";
        private static final String SCROLL_DOWN = "scrollDown";
        private static final String SCROLL_HOME = "scrollHome";
        private static final String SCROLL_END = "scrollEnd";
        private static final String UNIT_SCROLL_UP = "unitScrollUp";
        private static final String UNIT_SCROLL_DOWN = "unitScrollDown";
        private static final String SCROLL_LEFT = "scrollLeft";
        private static final String SCROLL_RIGHT = "scrollRight";
        private static final String UNIT_SCROLL_LEFT = "unitScrollLeft";
        private static final String UNIT_SCROLL_RIGHT = "unitScrollRight";


        Actions(String key) {
            super(key);
        }

        public void actionPerformed(ActionEvent e) {
            JScrollPane scrollPane = (JScrollPane)e.getSource();
            boolean ltr = scrollPane.getComponentOrientation().isLeftToRight();
            String key = getName();

            if (key == SCROLL_UP) {
                scroll(scrollPane, SwingConstants.VERTICAL, -1, true);
            }
            else if (key == SCROLL_DOWN) {
                scroll(scrollPane, SwingConstants.VERTICAL, 1, true);
            }
            else if (key == SCROLL_HOME) {
                scrollHome(scrollPane);
            }
            else if (key == SCROLL_END) {
                scrollEnd(scrollPane);
            }
            else if (key == UNIT_SCROLL_UP) {
                scroll(scrollPane, SwingConstants.VERTICAL, -1, false);
            }
            else if (key == UNIT_SCROLL_DOWN) {
                scroll(scrollPane, SwingConstants.VERTICAL, 1, false);
            }
            else if (key == SCROLL_LEFT) {
                scroll(scrollPane, SwingConstants.HORIZONTAL, ltr ? -1 : 1,
                       true);
            }
            else if (key == SCROLL_RIGHT) {
                scroll(scrollPane, SwingConstants.HORIZONTAL, ltr ? 1 : -1,
                       true);
            }
            else if (key == UNIT_SCROLL_LEFT) {
                scroll(scrollPane, SwingConstants.HORIZONTAL, ltr ? -1 : 1,
                       false);
            }
            else if (key == UNIT_SCROLL_RIGHT) {
                scroll(scrollPane, SwingConstants.HORIZONTAL, ltr ? 1 : -1,
                       false);
            }
        }

        private void scrollEnd(JScrollPane scrollpane) {
            JViewport vp = scrollpane.getViewport();
            Component view;
            if (vp != null && (view = vp.getView()) != null) {
                Rectangle visRect = vp.getViewRect();
                Rectangle bounds = view.getBounds();
                if (scrollpane.getComponentOrientation().isLeftToRight()) {
                    vp.setViewPosition(new Point(bounds.width - visRect.width,
                                             bounds.height - visRect.height));
                } else {
                    vp.setViewPosition(new Point(0,
                                             bounds.height - visRect.height));
                }
            }
        }

        private void scrollHome(JScrollPane scrollpane) {
            JViewport vp = scrollpane.getViewport();
            Component view;
            if (vp != null && (view = vp.getView()) != null) {
                if (scrollpane.getComponentOrientation().isLeftToRight()) {
                    vp.setViewPosition(new Point(0, 0));
                } else {
                    Rectangle visRect = vp.getViewRect();
                    Rectangle bounds = view.getBounds();
                    vp.setViewPosition(new Point(bounds.width - visRect.width, 0));
                }
            }
        }

        private void scroll(JScrollPane scrollpane, int orientation,
                            int direction, boolean block) {
            JViewport vp = scrollpane.getViewport();
            Component view;
            if (vp != null && (view = vp.getView()) != null) {
                Rectangle visRect = vp.getViewRect();
                Dimension vSize = view.getSize();
                int amount;

                if (view instanceof Scrollable) {
                    if (block) {
                        amount = ((Scrollable)view).getScrollableBlockIncrement
                                 (visRect, orientation, direction);
                    }
                    else {
                        amount = ((Scrollable)view).getScrollableUnitIncrement
                                 (visRect, orientation, direction);
                    }
                }
                else {
                    if (block) {
                        if (orientation == SwingConstants.VERTICAL) {
                            amount = visRect.height;
                        }
                        else {
                            amount = visRect.width;
                        }
                    }
                    else {
                        amount = 10;
                    }
                }
                if (orientation == SwingConstants.VERTICAL) {
                    visRect.y += (amount * direction);
                    if ((visRect.y + visRect.height) > vSize.height) {
                        visRect.y = Math.max(0, vSize.height - visRect.height);
                    }
                    else if (visRect.y < 0) {
                        visRect.y = 0;
                    }
                }
                else {
                    if (scrollpane.getComponentOrientation().isLeftToRight()) {
                        visRect.x += (amount * direction);
                        if ((visRect.x + visRect.width) > vSize.width) {
                            visRect.x = Math.max(0, vSize.width - visRect.width);
                        } else if (visRect.x < 0) {
                            visRect.x = 0;
                        }
                    } else {
                        visRect.x -= (amount * direction);
                        if (visRect.width > vSize.width) {
                            visRect.x = vSize.width - visRect.width;
                        } else {
                            visRect.x = Math.max(0, Math.min(vSize.width - visRect.width, visRect.x));
                        }
                    }
                }
                vp.setViewPosition(visRect.getLocation());
            }
        }
    }


    class Handler implements ChangeListener, PropertyChangeListener, MouseWheelListener {
        //
        // MouseWheelListener
        //
        public void mouseWheelMoved(MouseWheelEvent e) {
            if (scrollpane.isWheelScrollingEnabled() &&
                e.getWheelRotation() != 0) {
                JScrollBar toScroll = scrollpane.getVerticalScrollBar();
                int direction = e.getWheelRotation() < 0 ? -1 : 1;
                int orientation = SwingConstants.VERTICAL;

                // find which scrollbar to scroll, or return if none
                if (toScroll == null || !toScroll.isVisible()) {
                    toScroll = scrollpane.getHorizontalScrollBar();
                    if (toScroll == null || !toScroll.isVisible()) {
                        return;
                    }
                    orientation = SwingConstants.HORIZONTAL;
                }

                if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
                    JViewport vp = scrollpane.getViewport();
                    if (vp == null) { return; }
                    Component comp = vp.getView();
                    int units = Math.abs(e.getUnitsToScroll());

                    // When the scrolling speed is set to maximum, it's possible
                    // for a single wheel click to scroll by more units than
                    // will fit in the visible area.  This makes it
                    // hard/impossible to get to certain parts of the scrolling
                    // Component with the wheel.  To make for more accurate
                    // low-speed scrolling, we limit scrolling to the block
                    // increment if the wheel was only rotated one click.
                    boolean limitScroll = Math.abs(e.getWheelRotation()) == 1;

                    // Check if we should use the visibleRect trick
                    Object fastWheelScroll = toScroll.getClientProperty(
                                               "JScrollBar.fastWheelScrolling");
                    if (Boolean.TRUE == fastWheelScroll &&
                        comp instanceof Scrollable) {
                        // 5078454: Under maximum acceleration, we may scroll
                        // by many 100s of units in ~1 second.
                        //
                        // BasicScrollBarUI.scrollByUnits() can bog down the EDT
                        // with repaints in this situation.  However, the
                        // Scrollable interface allows us to pass in an
                        // arbitrary visibleRect.  This allows us to accurately
                        // calculate the total scroll amount, and then update
                        // the GUI once.  This technique provides much faster
                        // accelerated wheel scrolling.
                        Scrollable scrollComp = (Scrollable) comp;
                        Rectangle viewRect = vp.getViewRect();
                        int startingX = viewRect.x;
                        boolean leftToRight =
                                 comp.getComponentOrientation().isLeftToRight();
                        int scrollMin = toScroll.getMinimum();
                        int scrollMax = toScroll.getMaximum() -
                                        toScroll.getModel().getExtent();

                        if (limitScroll) {
                            int blockIncr =
                                scrollComp.getScrollableBlockIncrement(viewRect,
                                                                    orientation,
                                                                    direction);
                            if (direction < 0) {
                                scrollMin = Math.max(scrollMin,
                                               toScroll.getValue() - blockIncr);
                            }
                            else {
                                scrollMax = Math.min(scrollMax,
                                               toScroll.getValue() + blockIncr);
                            }
                        }

                        for (int i = 0; i < units; i++) {
                            int unitIncr =
                                scrollComp.getScrollableUnitIncrement(viewRect,
                                                        orientation, direction);
                            // Modify the visible rect for the next unit, and
                            // check to see if we're at the end already.
                            if (orientation == SwingConstants.VERTICAL) {
                                if (direction < 0) {
                                    viewRect.y -= unitIncr;
                                    if (viewRect.y <= scrollMin) {
                                        viewRect.y = scrollMin;
                                        break;
                                    }
                                }
                                else { // (direction > 0
                                    viewRect.y += unitIncr;
                                    if (viewRect.y >= scrollMax) {
                                        viewRect.y = scrollMax;
                                        break;
                                    }
                                }
                            }
                            else {
                                // Scroll left
                                if ((leftToRight && direction < 0) ||
                                    (!leftToRight && direction > 0)) {
                                    viewRect.x -= unitIncr;
                                    if (leftToRight) {
                                        if (viewRect.x < scrollMin) {
                                            viewRect.x = scrollMin;
                                            break;
                                        }
                                    }
                                }
                                // Scroll right
                                else if ((leftToRight && direction > 0) ||
                                    (!leftToRight && direction < 0)) {
                                    viewRect.x += unitIncr;
                                    if (leftToRight) {
                                        if (viewRect.x > scrollMax) {
                                            viewRect.x = scrollMax;
                                            break;
                                        }
                                    }
                                }
                                else {
                                    assert false : "Non-sensical ComponentOrientation / scroll direction";
                                }
                            }
                        }
                        // Set the final view position on the ScrollBar
                        if (orientation == SwingConstants.VERTICAL) {
                            toScroll.setValue(viewRect.y);
                        }
                        else {
                            if (leftToRight) {
                                toScroll.setValue(viewRect.x);
                            }
                            else {
                                // rightToLeft scrollbars are oriented with
                                // minValue on the right and maxValue on the
                                // left.
                                int newPos = toScroll.getValue() -
                                                       (viewRect.x - startingX);
                                if (newPos < scrollMin) {
                                    newPos = scrollMin;
                                }
                                else if (newPos > scrollMax) {
                                    newPos = scrollMax;
                                }
                                toScroll.setValue(newPos);
                            }
                        }
                    }
                    else {
                        // Viewport's view is not a Scrollable, or fast wheel
                        // scrolling is not enabled.
                        BasicScrollBarUI.scrollByUnits(toScroll, direction,
                                                       units, limitScroll);
                    }
                }
                else if (e.getScrollType() ==
                         MouseWheelEvent.WHEEL_BLOCK_SCROLL) {
                    BasicScrollBarUI.scrollByBlock(toScroll, direction);
                }
            }
        }

        //
        // ChangeListener: This is added to the vieport, and hsb/vsb models.
        //
        public void stateChanged(ChangeEvent e) {
            JViewport viewport = scrollpane.getViewport();

            if (viewport != null) {
                if (e.getSource() == viewport) {
                    viewportStateChanged(e);
                }
                else {
                    JScrollBar hsb = scrollpane.getHorizontalScrollBar();
                    if (hsb != null && e.getSource() == hsb.getModel()) {
                        hsbStateChanged(viewport, e);
                    }
                    else {
                        JScrollBar vsb = scrollpane.getVerticalScrollBar();
                        if (vsb != null && e.getSource() == vsb.getModel()) {
                            vsbStateChanged(viewport, e);
                        }
                    }
                }
            }
        }

        private void vsbStateChanged(JViewport viewport, ChangeEvent e) {
            BoundedRangeModel model = (BoundedRangeModel)(e.getSource());
            Point p = viewport.getViewPosition();
            p.y = model.getValue();
            viewport.setViewPosition(p);
        }

        private void hsbStateChanged(JViewport viewport, ChangeEvent e) {
            BoundedRangeModel model = (BoundedRangeModel)(e.getSource());
            Point p = viewport.getViewPosition();
            int value = model.getValue();
            if (scrollpane.getComponentOrientation().isLeftToRight()) {
                p.x = value;
            } else {
                int max = viewport.getViewSize().width;
                int extent = viewport.getExtentSize().width;
                int oldX = p.x;

                /* Set new X coordinate based on "value".
                 */
                p.x = max - extent - value;

                /* If setValue() was called before "extent" was fixed,
                 * turn setValueCalled flag on.
                 */
                if ((extent == 0) && (value != 0) && (oldX == max)) {
                    setValueCalled = true;
                } else {
                    /* When a pane without a horizontal scroll bar was
                     * reduced and the bar appeared, the viewport should
                     * show the right side of the view.
                     */
                    if ((extent != 0) && (oldX < 0) && (p.x == 0)) {
                        p.x += value;
                    }
                }
            }
            viewport.setViewPosition(p);
        }

        private void viewportStateChanged(ChangeEvent e) {
            syncScrollPaneWithViewport();
        }


        //
        // PropertyChangeListener: This is installed on both the JScrollPane
        // and the horizontal/vertical scrollbars.
        //

        // Listens for changes in the model property and reinstalls the
        // horizontal/vertical PropertyChangeListeners.
        public void propertyChange(PropertyChangeEvent e) {
            if (e.getSource() == scrollpane) {
                scrollPanePropertyChange(e);
            }
            else {
                sbPropertyChange(e);
            }
        }

        private void scrollPanePropertyChange(PropertyChangeEvent e) {
            String propertyName = e.getPropertyName();

            if (propertyName == "verticalScrollBarDisplayPolicy") {
                updateScrollBarDisplayPolicy(e);
            }
            else if (propertyName == "horizontalScrollBarDisplayPolicy") {
                updateScrollBarDisplayPolicy(e);
            }
            else if (propertyName == "viewport") {
                updateViewport(e);
            }
            else if (propertyName == "rowHeader") {
                updateRowHeader(e);
            }
            else if (propertyName == "columnHeader") {
                updateColumnHeader(e);
            }
            else if (propertyName == "verticalScrollBar") {
                updateVerticalScrollBar(e);
            }
            else if (propertyName == "horizontalScrollBar") {
                updateHorizontalScrollBar(e);
            }
            else if (propertyName == "componentOrientation") {
                scrollpane.revalidate();
                scrollpane.repaint();
            }
        }

        // PropertyChangeListener for the horizontal and vertical scrollbars.
        private void sbPropertyChange(PropertyChangeEvent e) {
            String propertyName = e.getPropertyName();
            Object source = e.getSource();

            if ("model" == propertyName) {
                JScrollBar sb = scrollpane.getVerticalScrollBar();
                BoundedRangeModel oldModel = (BoundedRangeModel)e.
                                     getOldValue();
                ChangeListener cl = null;

                if (source == sb) {
                    cl = vsbChangeListener;
                }
                else if (source == scrollpane.getHorizontalScrollBar()) {
                    sb = scrollpane.getHorizontalScrollBar();
                    cl = hsbChangeListener;
                }
                if (cl != null) {
                    if (oldModel != null) {
                        oldModel.removeChangeListener(cl);
                    }
                    if (sb.getModel() != null) {
                        sb.getModel().addChangeListener(cl);
                    }
                }
            }
            else if ("componentOrientation" == propertyName) {
                if (source == scrollpane.getHorizontalScrollBar()) {
                    JScrollBar hsb = scrollpane.getHorizontalScrollBar();
                    JViewport viewport = scrollpane.getViewport();
                    Point p = viewport.getViewPosition();
                    if (scrollpane.getComponentOrientation().isLeftToRight()) {
                        p.x = hsb.getValue();
                    } else {
                        p.x = viewport.getViewSize().width - viewport.getExtentSize().width - hsb.getValue();
                    }
                    viewport.setViewPosition(p);
                }
            }
        }
    }
}
