/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.pivot.wtk.skin.terra;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.geom.GeneralPath;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.apache.pivot.collections.ArrayList;
import org.apache.pivot.collections.Dictionary;
import org.apache.pivot.collections.List;
import org.apache.pivot.collections.Sequence;
import org.apache.pivot.collections.Sequence.Tree.Path;
import org.apache.pivot.util.ClassUtils;
import org.apache.pivot.util.Filter;
import org.apache.pivot.util.Utils;
import org.apache.pivot.util.Vote;
import org.apache.pivot.wtk.Bounds;
import org.apache.pivot.wtk.Button;
import org.apache.pivot.wtk.Checkbox;
import org.apache.pivot.wtk.Component;
import org.apache.pivot.wtk.GraphicsUtilities;
import org.apache.pivot.wtk.Keyboard;
import org.apache.pivot.wtk.Keyboard.KeyCode;
import org.apache.pivot.wtk.Keyboard.KeyLocation;
import org.apache.pivot.wtk.Keyboard.Modifier;
import org.apache.pivot.wtk.Mouse;
import org.apache.pivot.wtk.Orientation;
import org.apache.pivot.wtk.Platform;
import org.apache.pivot.wtk.Theme;
import org.apache.pivot.wtk.TreeView;
import org.apache.pivot.wtk.TreeView.SelectMode;
import org.apache.pivot.wtk.TreeViewBranchListener;
import org.apache.pivot.wtk.TreeViewListener;
import org.apache.pivot.wtk.TreeViewNodeListener;
import org.apache.pivot.wtk.TreeViewNodeStateListener;
import org.apache.pivot.wtk.TreeViewSelectionListener;
import org.apache.pivot.wtk.skin.ComponentSkin;

/**
 * Tree view skin.
 */
public class TerraTreeViewSkin extends ComponentSkin implements TreeView.Skin, TreeViewListener,
    TreeViewBranchListener, TreeViewNodeListener, TreeViewNodeStateListener,
    TreeViewSelectionListener {

    /**
     * Node info visitor interface.
     */
    protected interface NodeInfoVisitor {
        /**
         * Visits the specified node info.
         *
         * @param nodeInfo The object to visit
         */
        public void visit(NodeInfo nodeInfo);
    }

    /**
     * Iterates through the visible nodes. For callers who wish to know the path
     * of each visible node, using this iterator will be much more efficient
     * than manually iterating over the visible nodes and calling
     * <tt>getPath()</tt> on each node.
     */
    protected final class VisibleNodeIterator implements Iterator<NodeInfo> {
        private int index;
        private int end;

        private Path path = null;
        private NodeInfo previous = null;

        public VisibleNodeIterator() {
            this(0, visibleNodes.getLength() - 1);
        }

        /**
         * Creates a new visible node iterator that will iterate over a portion
         * of the visible nodes list (useful during painting).
         *
         * @param start The start index, inclusive
         * @param end The end index, inclusive
         */
        public VisibleNodeIterator(int start, int end) {
            if (start < 0 || end >= visibleNodes.getLength()) {
                throw new IndexOutOfBoundsException();
            }

            this.index = start;
            this.end = end;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean hasNext() {
            return (index <= end);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public NodeInfo next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }

            NodeInfo next = visibleNodes.get(index++);

            if (path == null) {
                // First iteration
                path = next.getPath();
            } else if (next.parent == previous) {
                // Child of previous visible node
                path.add(0);
            } else {
                int n = path.getLength();
                while (next.parent != previous.parent) {
                    path.remove(--n, 1);
                    previous = previous.parent;
                }

                int tail = path.get(n - 1);
                path.update(n - 1, tail + 1);
            }

            previous = next;

            return next;
        }

        /**
         * This operation is not supported by this iterator.
         *
         * @throws UnsupportedOperationException always since this is unsupported.
         */
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

        /**
         * Gets the index of the node last returned by a call to {@link #next()}
         * , as seen in the current visible nodes list. Note that as branches
         * are expanded and collapsed, the row index of any given node in the
         * tree will change.
         *
         * @return The row index of the current node, or <tt>-1</tt> if
         * <tt>next()</tt> has not yet been called.
         */
        public int getRowIndex() {
            return (path == null ? -1 : index - 1);
        }

        /**
         * Gets the path of the node last returned by a call to {@link #next()}.
         *
         * @return The path to the node, or <tt>null</tt> if <tt>next()</tt> has
         * not yet been called.
         */
        public Path getPath() {
            return path;
        }
    }

    /**
     * An internal data structure that keeps track of skin-related metadata for
     * a tree node. The justification for the existence of this class lies in
     * the <tt>visibleNodes</tt> data structure, which is a flat list of nodes
     * that are visible at any given time. In this context, visible means that
     * their parent hierarchy is expanded, <b>not</b> that they are being
     * painted. This list, combined with <tt>getNodeHeight()</tt>, enables us to
     * quickly determine which nodes to paint given a graphics clip rect. It
     * also enables us to quickly traverse the tree view when handling key
     * events. <p> NOTE: some of this data is managed by <tt>TreeView</tt> and
     * cached here to provide further optimizations during painting and user
     * input.
     */
    protected static class NodeInfo {
        // Core metadata
        final TreeView treeView;
        final BranchInfo parent;
        final Object data;
        final int depth;

        // Cached fields. Note that this is maintained as a bitmask in favor of
        // separate properties because it allows us to easily clear any cached
        // field for all nodes in one common method. See #clearField(byte)
        byte fields = 0;

        public static final byte HIGHLIGHTED_MASK = 1 << 0;
        public static final byte SELECTED_MASK = 1 << 1;
        public static final byte DISABLED_MASK = 1 << 2;
        public static final byte CHECKMARK_DISABLED_MASK = 1 << 3;
        public static final byte CHECK_STATE_CHECKED_MASK = 1 << 4;
        public static final byte CHECK_STATE_MIXED_MASK = 1 << 5;

        public static final byte CHECK_STATE_MASK = CHECK_STATE_CHECKED_MASK
            | CHECK_STATE_MIXED_MASK;

        private NodeInfo(TreeView treeView, BranchInfo parent, Object data) {
            this.treeView = treeView;
            this.parent = parent;
            this.data = data;

            depth = (parent == null) ? 0 : parent.depth + 1;

            // Newly created nodes are guaranteed to not be selected or checked,
            // but they may be disabled or have their checkmarks disabled, so
            // we set those flags appropriately here.

            @SuppressWarnings("unchecked")
            Filter<Object> disabledNodeFilter = (Filter<Object>) treeView.getDisabledNodeFilter();
            if (disabledNodeFilter != null) {
                setDisabled(disabledNodeFilter.include(data));
            }

            @SuppressWarnings("unchecked")
            Filter<Object> disabledCheckmarkFilter = (Filter<Object>) treeView.getDisabledCheckmarkFilter();
            if (disabledCheckmarkFilter != null) {
                setCheckmarkDisabled(disabledCheckmarkFilter.include(data));
            }
        }

        @SuppressWarnings("unchecked")
        private static NodeInfo newInstance(TreeView treeView, BranchInfo parent, Object data) {
            NodeInfo nodeInfo = null;

            if (data instanceof List<?>) {
                nodeInfo = new BranchInfo(treeView, parent, (List<Object>) data);
            } else {
                nodeInfo = new NodeInfo(treeView, parent, data);
            }

            return nodeInfo;
        }

        @SuppressWarnings("unchecked")
        public Path getPath() {
            Path path = Path.forDepth(depth);

            NodeInfo nodeInfo = this;

            while (nodeInfo.parent != null) {
                List<Object> parentData = (List<Object>) nodeInfo.parent.data;
                int index = parentData.indexOf(nodeInfo.data);
                path.insert(index, 0);

                nodeInfo = nodeInfo.parent;
            }

            return path;
        }

        public boolean isHighlighted() {
            return ((fields & HIGHLIGHTED_MASK) != 0);
        }

        public void setHighlighted(boolean highlighted) {
            if (highlighted) {
                fields |= HIGHLIGHTED_MASK;
            } else {
                fields &= ~HIGHLIGHTED_MASK;
            }
        }

        public boolean isSelected() {
            return ((fields & SELECTED_MASK) != 0);
        }

        public void setSelected(boolean selected) {
            if (selected) {
                fields |= SELECTED_MASK;
            } else {
                fields &= ~SELECTED_MASK;
            }
        }

        public boolean isDisabled() {
            return ((fields & DISABLED_MASK) != 0);
        }

        public void setDisabled(boolean disabled) {
            if (disabled) {
                fields |= DISABLED_MASK;
            } else {
                fields &= ~DISABLED_MASK;
            }
        }

        public boolean isCheckmarkDisabled() {
            return ((fields & CHECKMARK_DISABLED_MASK) != 0);
        }

        public void setCheckmarkDisabled(boolean checkmarkDisabled) {
            if (checkmarkDisabled) {
                fields |= CHECKMARK_DISABLED_MASK;
            } else {
                fields &= ~CHECKMARK_DISABLED_MASK;
            }
        }

        public TreeView.NodeCheckState getCheckState() {
            TreeView.NodeCheckState checkState;

            switch (fields & CHECK_STATE_MASK) {
                case CHECK_STATE_CHECKED_MASK:
                    checkState = TreeView.NodeCheckState.CHECKED;
                    break;
                case CHECK_STATE_MIXED_MASK:
                    checkState = TreeView.NodeCheckState.MIXED;
                    break;
                default:
                    checkState = TreeView.NodeCheckState.UNCHECKED;
                    break;
            }

            return checkState;
        }

        public boolean isChecked() {
            return ((fields & CHECK_STATE_CHECKED_MASK) != 0);
        }

        public void setCheckState(TreeView.NodeCheckState checkState) {
            fields &= ~CHECK_STATE_MASK;

            switch (checkState) {
                case CHECKED:
                    fields |= CHECK_STATE_CHECKED_MASK;
                    break;
                case MIXED:
                    fields |= CHECK_STATE_MIXED_MASK;
                    break;
                case UNCHECKED:
                    break;
                default:
                    break;
            }
        }

        public void clearField(byte mask) {
            fields &= ~mask;
        }

        @Override
        public String toString() {
            return ClassUtils.simpleToString(this);
        }
    }

    /**
     * An internal data structure that keeps track of skin-related metadata for
     * a tree branch.
     */
    protected static final class BranchInfo extends NodeInfo {
        // Core skin metadata
        private List<NodeInfo> children = null;

        public static final byte EXPANDED_MASK = 1 << 6;

        private BranchInfo(TreeView treeView, BranchInfo parent, List<Object> data) {
            super(treeView, parent, data);
        }

        /**
         * Loads this branch info's children. The children list is initialized
         * to <tt>null</tt> and loaded lazily to allow the skin to only create
         * <tt>NodeInfo</tt> objects for the nodes that it actually needs in
         * order to paint. Thus, it is the responsibility of the skin to check
         * if <tt>children</tt> is null and call <tt>loadChildren()</tt> if
         * necessary.
         */
        @SuppressWarnings("unchecked")
        public void loadChildren() {
            if (children == null || children.isEmpty()) {
                List<Object> dataLocal = (List<Object>) this.data;
                int count = dataLocal.getLength();

                children = new ArrayList<>(count);

                for (int i = 0; i < count; i++) {
                    Object nodeData = dataLocal.get(i);
                    NodeInfo childNodeInfo = NodeInfo.newInstance(treeView, this, nodeData);
                    children.add(childNodeInfo);
                }
            }
        }

        public boolean isExpanded() {
            return ((fields & EXPANDED_MASK) != 0);
        }

        public void setExpanded(boolean expanded) {
            if (expanded) {
                fields |= EXPANDED_MASK;
            } else {
                fields &= ~EXPANDED_MASK;
            }
        }
    }

    private BranchInfo rootBranchInfo = null;
    private List<NodeInfo> visibleNodes = new ArrayList<>();

    private NodeInfo highlightedNode = null;
    private Path selectPath = null;

    // Styles
    private Font font;
    private Color color;
    private Color disabledColor;
    private Color backgroundColor;
    private Color selectionColor;
    private Color selectionBackgroundColor;
    private Color inactiveSelectionColor;
    private Color inactiveSelectionBackgroundColor;
    private Color highlightColor;
    private Color highlightBackgroundColor;
    private int spacing;
    private int indent;
    private boolean showHighlight;
    private boolean showBranchControls;
    private boolean showEmptyBranchControls;
    private Color branchControlColor;
    private Color branchControlSelectionColor;
    private Color branchControlInactiveSelectionColor;
    private Color gridColor;
    private boolean showGridLines;

    private boolean validateSelection = false;

    private static final int BRANCH_CONTROL_IMAGE_WIDTH = 8;
    private static final int BRANCH_CONTROL_IMAGE_HEIGHT = 8;
    private static final int VERTICAL_SPACING = 1;

    private static final Checkbox CHECKBOX = new Checkbox();
    private static final int CHECKBOX_VERTICAL_PADDING = 2;

    static {
        CHECKBOX.setSize(CHECKBOX.getPreferredSize());
        CHECKBOX.setTriState(true);
    }

    public TerraTreeViewSkin() {
        Theme theme = currentTheme();

        font = theme.getFont();
        color = theme.getColor(1);
        disabledColor = theme.getColor(7);
        backgroundColor = theme.getColor(4);
        selectionColor = theme.getColor(4);
        selectionBackgroundColor = theme.getColor(14);
        inactiveSelectionColor = theme.getColor(1);
        inactiveSelectionBackgroundColor = theme.getColor(10);
        highlightColor = theme.getColor(1);
        highlightBackgroundColor = theme.getColor(10);
        spacing = 6;
        indent = 16;
        showHighlight = true;
        showBranchControls = true;
        showEmptyBranchControls = true;
        branchControlColor = theme.getColor(12);
        branchControlSelectionColor = theme.getColor(4);
        branchControlInactiveSelectionColor = theme.getColor(14);
        gridColor = theme.getColor(11);
        showGridLines = false;
    }

    @Override
    public void install(Component component) {
        super.install(component);

        TreeView treeView = (TreeView) component;
        treeView.getTreeViewListeners().add(this);
        treeView.getTreeViewBranchListeners().add(this);
        treeView.getTreeViewNodeListeners().add(this);
        treeView.getTreeViewNodeStateListeners().add(this);
        treeView.getTreeViewSelectionListeners().add(this);

        treeDataChanged(treeView, null);
    }

    @Override
    public int getPreferredWidth(int height) {
        TreeView treeView = (TreeView) getComponent();
        TreeView.NodeRenderer nodeRenderer = treeView.getNodeRenderer();

        int preferredWidth = 0;

        VisibleNodeIterator visibleNodeIterator = new VisibleNodeIterator();
        while (visibleNodeIterator.hasNext()) {
            NodeInfo nodeInfo = visibleNodeIterator.next();

            int nodeWidth = (nodeInfo.depth - 1) * (indent + spacing);

            nodeRenderer.render(nodeInfo.data, visibleNodeIterator.getPath(),
                visibleNodeIterator.getRowIndex(), treeView, false, false,
                TreeView.NodeCheckState.UNCHECKED, false, false);
            nodeWidth += nodeRenderer.getPreferredWidth(-1);

            preferredWidth = Math.max(preferredWidth, nodeWidth);
        }

        if (showBranchControls) {
            preferredWidth += indent + spacing;
        }

        if (treeView.getCheckmarksEnabled()) {
            preferredWidth += Math.max(CHECKBOX.getWidth(), indent) + spacing;
        }

        return preferredWidth;
    }

    @Override
    public int getPreferredHeight(int width) {
        int nodeHeight = getNodeHeight();
        int visibleNodeCount = visibleNodes.getLength();

        int preferredHeight = nodeHeight * visibleNodeCount;

        if (visibleNodeCount > 1) {
            preferredHeight += VERTICAL_SPACING * (visibleNodeCount - 1);
        }

        return preferredHeight;
    }

    @Override
    public int getBaseline(int width, int height) {
        int baseline = -1;

        if (visibleNodes.getLength() > 0) {
            TreeView treeView = (TreeView) getComponent();
            TreeView.NodeRenderer nodeRenderer = treeView.getNodeRenderer();

            NodeInfo nodeInfo = visibleNodes.get(0);

            int nodeWidth = width - (nodeInfo.depth - 1) * (indent + spacing);
            int nodeHeight = getNodeHeight();

            boolean expanded = false;
            boolean selected = nodeInfo.isSelected();
            boolean highlighted = nodeInfo.isHighlighted();
            boolean disabled = nodeInfo.isDisabled();

            if (showBranchControls) {
                if (nodeInfo instanceof BranchInfo) {
                    BranchInfo branchInfo = (BranchInfo) nodeInfo;
                    expanded = branchInfo.isExpanded();
                }

                nodeWidth -= (indent + spacing);
            }

            TreeView.NodeCheckState checkState = TreeView.NodeCheckState.UNCHECKED;
            if (treeView.getCheckmarksEnabled()) {
                checkState = nodeInfo.getCheckState();
                nodeWidth -= (Math.max(indent, CHECKBOX.getWidth()) + spacing);
            }

            nodeRenderer.render(nodeInfo.data, nodeInfo.getPath(), 0, treeView, expanded, selected,
                checkState, highlighted, disabled);
            baseline = nodeRenderer.getBaseline(nodeWidth, nodeHeight);
        }

        return baseline;
    }

    @Override
    public void layout() {
        if (validateSelection) {
            // Ensure that the selection is visible
            scrollSelectionToVisible();
        }

        validateSelection = false;
    }

    @Override
    public void paint(Graphics2D graphics) {
        TreeView treeView = (TreeView) getComponent();
        TreeView.NodeRenderer nodeRenderer = treeView.getNodeRenderer();

        int width = getWidth();
        int height = getHeight();

        int nodeHeight = getNodeHeight();

        // Paint the background
        if (backgroundColor != null) {
            graphics.setPaint(backgroundColor);
            graphics.fillRect(0, 0, width, height);
        }

        // nodeStart and nodeEnd are both inclusive
        int nodeStart = 0;
        int nodeEnd = visibleNodes.getLength() - 1;

        // Ensure that we only paint items that are visible
        Rectangle clipBounds = graphics.getClipBounds();
        if (clipBounds != null) {
            nodeStart = Math.max(nodeStart,
                (int) (clipBounds.y / (double) (nodeHeight + VERTICAL_SPACING)));
            nodeEnd = Math.min(
                nodeEnd,
                (int) ((clipBounds.y + clipBounds.height) / (double) (nodeHeight + VERTICAL_SPACING)));
        }

        int nodeY = nodeStart * (nodeHeight + VERTICAL_SPACING);

        VisibleNodeIterator visibleNodeIterator = new VisibleNodeIterator(nodeStart, nodeEnd);
        while (visibleNodeIterator.hasNext()) {
            NodeInfo nodeInfo = visibleNodeIterator.next();

            boolean expanded = false;
            boolean highlighted = nodeInfo.isHighlighted();
            boolean selected = nodeInfo.isSelected();
            boolean disabled = nodeInfo.isDisabled();

            int nodeX = (nodeInfo.depth - 1) * (indent + spacing);

            if (treeView.isEnabled()) {
                if (selected) {
                    // Paint the selection state
                    Color selectionBackgroundColorLocal = treeView.isFocused() ? this.selectionBackgroundColor
                        : inactiveSelectionBackgroundColor;
                    graphics.setPaint(selectionBackgroundColorLocal);
                    graphics.fillRect(0, nodeY, width, nodeHeight);
                } else if (highlighted && !disabled) {
                    // Paint the highlight state
                    graphics.setPaint(highlightBackgroundColor);
                    graphics.fillRect(0, nodeY, width, nodeHeight);
                }
            }

            // Paint the expand/collapse control
            if (showBranchControls) {
                if (nodeInfo instanceof BranchInfo) {
                    BranchInfo branchInfo = (BranchInfo) nodeInfo;

                    boolean showBranchControl = true;
                    if (!showEmptyBranchControls) {
                        branchInfo.loadChildren();
                        showBranchControl = !(branchInfo.children == null || branchInfo.children.isEmpty());
                    }

                    if (showBranchControl) {
                        expanded = branchInfo.isExpanded();

                        Color branchControlColorLocal;

                        if (selected) {
                            if (treeView.isFocused()) {
                                branchControlColorLocal = branchControlSelectionColor;
                            } else {
                                branchControlColorLocal = branchControlInactiveSelectionColor;
                            }
                        } else {
                            branchControlColorLocal = this.branchControlColor;
                        }

                        GeneralPath shape = new GeneralPath();

                        int imageX = nodeX + (indent - BRANCH_CONTROL_IMAGE_WIDTH) / 2;
                        int imageY = nodeY + (nodeHeight - BRANCH_CONTROL_IMAGE_HEIGHT) / 2;

                        if (expanded) {
                            shape.moveTo(imageX, imageY + 1);
                            shape.lineTo(imageX + 8, imageY + 1);
                            shape.lineTo(imageX + 4, imageY + 7);
                        } else {
                            shape.moveTo(imageX + 1, imageY);
                            shape.lineTo(imageX + 7, imageY + 4);
                            shape.lineTo(imageX + 1, imageY + 8);
                        }

                        shape.closePath();

                        Graphics2D branchControlGraphics = (Graphics2D) graphics.create();
                        GraphicsUtilities.setAntialiasingOn(branchControlGraphics);
                        if (!treeView.isEnabled() || disabled) {
                            branchControlGraphics.setComposite(AlphaComposite.getInstance(
                                AlphaComposite.SRC_OVER, 0.5f));
                        }
                        branchControlGraphics.setPaint(branchControlColorLocal);
                        branchControlGraphics.fill(shape);
                        branchControlGraphics.dispose();
                    }
                }

                nodeX += indent + spacing;
            }

            // Paint the checkbox
            TreeView.NodeCheckState checkState = TreeView.NodeCheckState.UNCHECKED;
            if (treeView.getCheckmarksEnabled()) {
                checkState = nodeInfo.getCheckState();

                int checkboxWidth = CHECKBOX.getWidth();
                int checkboxHeight = CHECKBOX.getHeight();

                int checkboxX = Math.max(indent - checkboxWidth, 0) / 2;
                int checkboxY = (nodeHeight - checkboxHeight) / 2;
                Graphics2D checkboxGraphics = (Graphics2D) graphics.create(nodeX + checkboxX, nodeY
                    + checkboxY, checkboxWidth, checkboxHeight);

                Button.State state;
                switch (checkState) {
                    case CHECKED:
                        state = Button.State.SELECTED;
                        break;
                    case MIXED:
                        state = Button.State.MIXED;
                        break;
                    default:
                        state = Button.State.UNSELECTED;
                        break;
                }

                CHECKBOX.setState(state);
                CHECKBOX.setEnabled(treeView.isEnabled() && !disabled
                    && !nodeInfo.isCheckmarkDisabled());
                CHECKBOX.paint(checkboxGraphics);
                checkboxGraphics.dispose();

                nodeX += Math.max(indent, checkboxWidth) + spacing;
            }

            int nodeWidth = Math.max(width - nodeX, 0);

            // Paint the node data
            Graphics2D rendererGraphics = (Graphics2D) graphics.create(nodeX, nodeY, nodeWidth,
                nodeHeight);
            nodeRenderer.render(nodeInfo.data, visibleNodeIterator.getPath(),
                visibleNodeIterator.getRowIndex(), treeView, expanded, selected, checkState,
                highlighted, disabled);
            nodeRenderer.setSize(nodeWidth, nodeHeight);
            nodeRenderer.paint(rendererGraphics);
            rendererGraphics.dispose();

            // Paint the grid line
            if (showGridLines) {
                graphics.setPaint(gridColor);

                GraphicsUtilities.drawLine(graphics, 0, nodeY + nodeHeight, width,
                    Orientation.HORIZONTAL);
            }

            nodeY += nodeHeight + VERTICAL_SPACING;
        }
    }

    public Font getFont() {
        return font;
    }

    public void setFont(Font font) {
        Utils.checkNull(font, "font");

        this.font = font;
        invalidateComponent();
    }

    public final void setFont(String font) {
        setFont(decodeFont(font));
    }

    public final void setFont(Dictionary<String, ?> font) {
        setFont(Theme.deriveFont(font));
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        Utils.checkNull(color, "color");

        this.color = color;
        repaintComponent();
    }

    public void setColor(String color) {
        setColor(GraphicsUtilities.decodeColor(color, "color"));
    }

    public final void setColor(int color) {
        Theme theme = currentTheme();
        setColor(theme.getColor(color));
    }

    public Color getDisabledColor() {
        return disabledColor;
    }

    public void setDisabledColor(Color disabledColor) {
        Utils.checkNull(disabledColor, "disabledColor");

        this.disabledColor = disabledColor;
        repaintComponent();
    }

    public void setDisabledColor(String disabledColor) {
        setDisabledColor(GraphicsUtilities.decodeColor(disabledColor, "disabledColor"));
    }

    public final void setDisabledColor(int disabledColor) {
        Theme theme = currentTheme();
        setDisabledColor(theme.getColor(disabledColor));
    }

    public Color getBackgroundColor() {
        return backgroundColor;
    }

    public void setBackgroundColor(Color backgroundColor) {
        // We allow a null background color here
        this.backgroundColor = backgroundColor;
        repaintComponent();
    }

    public void setBackgroundColor(String backgroundColor) {
        setBackgroundColor(GraphicsUtilities.decodeColor(backgroundColor, "backgroundColor"));
    }

    public final void setBackgroundColor(int backgroundColor) {
        Theme theme = currentTheme();
        setBackgroundColor(theme.getColor(backgroundColor));
    }

    public Color getSelectionColor() {
        return selectionColor;
    }

    public void setSelectionColor(Color selectionColor) {
        Utils.checkNull(selectionColor, "selectionColor");

        this.selectionColor = selectionColor;
        repaintComponent();
    }

    public void setSelectionColor(String selectionColor) {
        setSelectionColor(GraphicsUtilities.decodeColor(selectionColor, "selectionColor"));
    }

    public final void setSelectionColor(int selectionColor) {
        Theme theme = currentTheme();
        setSelectionColor(theme.getColor(selectionColor));
    }

    public Color getSelectionBackgroundColor() {
        return selectionBackgroundColor;
    }

    public void setSelectionBackgroundColor(Color selectionBackgroundColor) {
        Utils.checkNull(selectionBackgroundColor, "selectionBackgroundColor");

        this.selectionBackgroundColor = selectionBackgroundColor;
        repaintComponent();
    }

    public void setSelectionBackgroundColor(String selectionBackgroundColor) {
        setSelectionBackgroundColor(
            GraphicsUtilities.decodeColor(selectionBackgroundColor, "selectionBackgroundColor"));
    }

    public final void setSelectionBackgroundColor(int selectionBackgroundColor) {
        Theme theme = currentTheme();
        setSelectionBackgroundColor(theme.getColor(selectionBackgroundColor));
    }

    public Color getInactiveSelectionColor() {
        return inactiveSelectionColor;
    }

    public void setInactiveSelectionColor(Color inactiveSelectionColor) {
        Utils.checkNull(inactiveSelectionColor, "inactiveSelectionColor");

        this.inactiveSelectionColor = inactiveSelectionColor;
        repaintComponent();
    }

    public void setInactiveSelectionColor(String inactiveSelectionColor) {
        setInactiveSelectionColor(
            GraphicsUtilities.decodeColor(inactiveSelectionColor, "inactiveSelectionColor"));
    }

    public final void setInactiveSelectionColor(int inactiveSelectionColor) {
        Theme theme = currentTheme();
        setInactiveSelectionColor(theme.getColor(inactiveSelectionColor));
    }

    public Color getInactiveSelectionBackgroundColor() {
        return inactiveSelectionBackgroundColor;
    }

    public void setInactiveSelectionBackgroundColor(Color inactiveSelectionBackgroundColor) {
        Utils.checkNull(inactiveSelectionBackgroundColor, "inactiveSelectionBackgroundColor");

        this.inactiveSelectionBackgroundColor = inactiveSelectionBackgroundColor;
        repaintComponent();
    }

    public void setInactiveSelectionBackgroundColor(String inactiveSelectionBackgroundColor) {
        setInactiveSelectionBackgroundColor(
            GraphicsUtilities.decodeColor(inactiveSelectionBackgroundColor, "inactiveSelectionBackgroundColor"));
    }

    public final void setInactiveSelectionBackgroundColor(int inactiveSelectionBackgroundColor) {
        Theme theme = currentTheme();
        setInactiveSelectionBackgroundColor(theme.getColor(inactiveSelectionBackgroundColor));
    }

    public Color getHighlightColor() {
        return highlightColor;
    }

    public void setHighlightColor(Color highlightColor) {
        Utils.checkNull(highlightColor, "highlightColor");

        this.highlightColor = highlightColor;
        repaintComponent();
    }

    public void setHighlightColor(String highlightColor) {
        setHighlightColor(GraphicsUtilities.decodeColor(highlightColor, "highlightColor"));
    }

    public final void setHighlightColor(int highlightColor) {
        Theme theme = currentTheme();
        setHighlightColor(theme.getColor(highlightColor));
    }

    public Color getHighlightBackgroundColor() {
        return highlightBackgroundColor;
    }

    public void setHighlightBackgroundColor(Color highlightBackgroundColor) {
        Utils.checkNull(highlightBackgroundColor, "highlightBackgroundColor");

        this.highlightBackgroundColor = highlightBackgroundColor;
        repaintComponent();
    }

    public void setHighlightBackgroundColor(String highlightBackgroundColor) {
        setHighlightBackgroundColor(
            GraphicsUtilities.decodeColor(highlightBackgroundColor, "highlightBackgroundColor"));
    }

    public final void setHighlightBackgroundColor(int highlightBackgroundColor) {
        Theme theme = currentTheme();
        setHighlightBackgroundColor(theme.getColor(highlightBackgroundColor));
    }

    public int getSpacing() {
        return spacing;
    }

    public void setSpacing(int spacing) {
        Utils.checkNonNegative(spacing, "spacing");

        this.spacing = spacing;
        invalidateComponent();
    }

    public void setSpacing(Number spacing) {
        Utils.checkNull(spacing, "spacing");

        setSpacing(spacing.intValue());
    }

    public int getIndent() {
        return indent;
    }

    public void setIndent(int indent) {
        Utils.checkNonNegative(indent, "indent");

        this.indent = indent;
        invalidateComponent();
    }

    public void setIndent(Number indent) {
        Utils.checkNull(indent, "indent");

        setIndent(indent.intValue());
    }

    public boolean getShowHighlight() {
        return showHighlight;
    }

    public void setShowHighlight(boolean showHighlight) {
        this.showHighlight = showHighlight;
        repaintComponent();
    }

    public boolean getShowBranchControls() {
        return showBranchControls;
    }

    public void setShowBranchControls(boolean showBranchControls) {
        this.showBranchControls = showBranchControls;
        invalidateComponent();
    }

    public boolean getShowEmptyBranchControls() {
        return showEmptyBranchControls;
    }

    public void setShowEmptyBranchControls(boolean showEmptyBranchControls) {
        this.showEmptyBranchControls = showEmptyBranchControls;
        repaintComponent();
    }

    public Color getBranchControlColor() {
        return branchControlColor;
    }

    public void setBranchControlColor(Color branchControlColor) {
        Utils.checkNull(branchControlColor, "branchControlColor");

        this.branchControlColor = branchControlColor;
        repaintComponent();
    }

    public void setBranchControlColor(String branchControlColor) {
        setBranchControlColor(GraphicsUtilities.decodeColor(branchControlColor, "branchControlColor"));
    }

    public final void setBranchControlColor(int branchControlColor) {
        Theme theme = currentTheme();
        setBranchControlColor(theme.getColor(branchControlColor));
    }

    public Color getBranchControlSelectionColor() {
        return branchControlSelectionColor;
    }

    public void setBranchControlSelectionColor(Color branchControlSelectionColor) {
        Utils.checkNull(branchControlSelectionColor, "branchControlSelectionColor");

        this.branchControlSelectionColor = branchControlSelectionColor;
        repaintComponent();
    }

    public void setBranchControlSelectionColor(String branchControlSelectionColor) {
        setBranchControlSelectionColor(
            GraphicsUtilities.decodeColor(branchControlSelectionColor, "branchControlSelectionColor"));
    }

    public final void setBranchControlSelectionColor(int branchControlSelectionColor) {
        Theme theme = currentTheme();
        setBranchControlSelectionColor(theme.getColor(branchControlSelectionColor));
    }

    public Color getBranchControlInactiveSelectionColor() {
        return branchControlInactiveSelectionColor;
    }

    public void setBranchControlInactiveSelectionColor(Color branchControlInactiveSelectionColor) {
        Utils.checkNull(branchControlInactiveSelectionColor, "branchControlInactiveSelectionColor");

        this.branchControlInactiveSelectionColor = branchControlInactiveSelectionColor;
        repaintComponent();
    }

    public void setBranchControlInactiveSelectionColor(String branchControlInactiveSelectionColor) {
        setBranchControlInactiveSelectionColor(
            GraphicsUtilities.decodeColor(branchControlInactiveSelectionColor, "branchControlInactiveSelectionColor"));
    }

    public final void setBranchControlInactiveSelectionColor(int branchControlInactiveSelectionColor) {
        Theme theme = currentTheme();
        setBranchControlInactiveSelectionColor(theme.getColor(branchControlInactiveSelectionColor));
    }

    public Color getGridColor() {
        return gridColor;
    }

    public void setGridColor(Color gridColor) {
        Utils.checkNull(gridColor, "gridColor");

        this.gridColor = gridColor;
        repaintComponent();
    }

    public void setGridColor(String gridColor) {
        setGridColor(GraphicsUtilities.decodeColor(gridColor, "gridColor"));
    }

    public final void setGridColor(int gridColor) {
        Theme theme = currentTheme();
        setGridColor(theme.getColor(gridColor));
    }

    public boolean getShowGridLines() {
        return showGridLines;
    }

    public void setShowGridLines(boolean showGridLines) {
        this.showGridLines = showGridLines;
        repaintComponent();
    }

    /**
     * @return The fixed node height of this skin.
     */
    protected int getNodeHeight() {
        TreeView treeView = (TreeView) getComponent();
        TreeView.NodeRenderer nodeRenderer = treeView.getNodeRenderer();
        nodeRenderer.render(null, null, -1, treeView, false, false,
            TreeView.NodeCheckState.UNCHECKED, false, false);

        int nodeHeight = nodeRenderer.getPreferredHeight(-1);
        if (treeView.getCheckmarksEnabled()) {
            nodeHeight = Math.max(CHECKBOX.getHeight() + (2 * CHECKBOX_VERTICAL_PADDING),
                nodeHeight);
        }

        return nodeHeight;
    }

    /**
     * @return The metadata associated with the node found at the specified
     * y-coordinate, or <tt>null</tt> if there is no node at that location.
     * @param y The current Y location.
     */
    protected final NodeInfo getNodeInfoAt(int y) {
        NodeInfo nodeInfo = null;

        int nodeHeight = getNodeHeight();
        int index = y / (nodeHeight + VERTICAL_SPACING);

        if (index >= 0 && index < visibleNodes.getLength()) {
            nodeInfo = visibleNodes.get(index);
        }

        return nodeInfo;
    }

    /**
     * @return The metadata associated with the node at the specified path. The
     * path must be valid. The empty path is supported and represents the root
     * node info.
     * @param path The path to query.
     */
    protected final NodeInfo getNodeInfoAt(Path path) {
        assert (path != null) : "Path is null";

        NodeInfo result = null;
        int n = path.getLength();

        if (n == 0) {
            result = rootBranchInfo;
        } else {
            BranchInfo branchInfo = rootBranchInfo;

            for (int i = 0; i < n - 1; i++) {
                branchInfo.loadChildren();
                NodeInfo nodeInfo = branchInfo.children.get(path.get(i));

                assert (nodeInfo instanceof BranchInfo) : "Invalid path";

                branchInfo = (BranchInfo) nodeInfo;
            }

            branchInfo.loadChildren();
            result = branchInfo.children.get(path.get(n - 1));
        }

        return result;
    }

    /**
     * @return The bounding box defined by the specified node, or <tt>null</tt> if
     * the node is not currently visible.
     * @param nodeInfo The node information to search for.
     */
    protected final Bounds getNodeBounds(NodeInfo nodeInfo) {
        Bounds bounds = null;

        int index = visibleNodes.indexOf(nodeInfo);

        if (index >= 0) {
            int nodeHeight = getNodeHeight();
            int nodeY = index * (nodeHeight + VERTICAL_SPACING);

            bounds = new Bounds(0, nodeY, getWidth(), nodeHeight);
        }

        return bounds;
    }

    /**
     * Accepts the specified visitor on all node info objects that exist in this
     * skin's node info hierarchy.
     *
     * @param visitor The callback to execute on each node info object
     */
    protected final void accept(NodeInfoVisitor visitor) {
        Sequence<NodeInfo> nodes = new ArrayList<>();
        nodes.add(rootBranchInfo);

        while (nodes.getLength() > 0) {
            NodeInfo nodeInfo = nodes.get(0);
            nodes.remove(0, 1);

            visitor.visit(nodeInfo);

            if (nodeInfo instanceof BranchInfo) {
                BranchInfo branchInfo = (BranchInfo) nodeInfo;

                if (branchInfo.children != null) {
                    for (int i = 0, n = branchInfo.children.getLength(); i < n; i++) {
                        nodes.insert(branchInfo.children.get(i), i);
                    }
                }
            }
        }
    }

    /**
     * Adds all children of the specified branch to the visible node list. Any
     * children nodes that are expanded [branches] will also have their children
     * made visible, and so on. Invalidates the component only if necessary.
     */
    private void addVisibleNodes(BranchInfo parentBranchInfo) {
        int insertIndex = -1;

        if (parentBranchInfo == rootBranchInfo) {
            // Bootstrap case since the root branch is implicitly expanded
            insertIndex = 0;
        } else {
            int branchIndex = visibleNodes.indexOf(parentBranchInfo);
            if (branchIndex >= 0) {
                insertIndex = branchIndex + 1;
            }
        }

        if (insertIndex >= 0) {
            Sequence<NodeInfo> nodes = new ArrayList<>();

            // The parent branch's children are the baseline nodes to make visible
            parentBranchInfo.loadChildren();
            for (int i = 0, n = parentBranchInfo.children.getLength(); i < n; i++) {
                nodes.add(parentBranchInfo.children.get(i));
            }

            while (nodes.getLength() > 0) {
                NodeInfo nodeInfo = nodes.get(0);
                nodes.remove(0, 1);
                visibleNodes.insert(nodeInfo, insertIndex++);

                // If we encounter an expanded branch, we add that branch's
                // children to our list of nodes that are to become visible
                if (nodeInfo instanceof BranchInfo) {
                    BranchInfo branchInfo = (BranchInfo) nodeInfo;
                    if (branchInfo.isExpanded()) {
                        branchInfo.loadChildren();
                        for (int i = 0, n = branchInfo.children.getLength(); i < n; i++) {
                            nodes.insert(branchInfo.children.get(i), i);
                        }
                    }
                }
            }

            invalidateComponent();
        }
    }

    /**
     * Adds the specified child of the specified branch to the visible node
     * list. It is assumed that the child in question is not an expanded branch.
     * Invalidates the component only if necessary.
     *
     * @param parentBranchInfo The branch info of the parent node.
     * @param index The index of the child within its parent.
     */
    private void addVisibleNode(BranchInfo parentBranchInfo, int index) {
        parentBranchInfo.loadChildren();

        assert (index >= 0) : "Index is too small";
        assert (index < parentBranchInfo.children.getLength()) : "Index is too large";

        int branchIndex = visibleNodes.indexOf(parentBranchInfo);

        if (parentBranchInfo == rootBranchInfo
            || (branchIndex >= 0 && parentBranchInfo.isExpanded())) {

            NodeInfo nodeInfo = parentBranchInfo.children.get(index);
            int insertIndex = branchIndex + index + 1;

            if (index > 0) {
                // Siblings of the node that lie before it may be expanded
                // branches, thus adding their own children to the
                // visible nodes list and pushing down our insert index
                NodeInfo youngerSibling = parentBranchInfo.children.get(index - 1);

                // Try to insert after our younger sibling
                insertIndex = visibleNodes.indexOf(youngerSibling) + 1;

                // Continue looking as long as the node at our insert index
                // has a greater depth than we do, which means that it's a
                // descendant of our younger sibling
                for (int n = visibleNodes.getLength(), nodeDepth = youngerSibling.depth; insertIndex < n
                    && visibleNodes.get(insertIndex).depth > nodeDepth; insertIndex++) {
                    continue;
                }
            }

            visibleNodes.insert(nodeInfo, insertIndex);

            invalidateComponent();
        }
    }

    /**
     * Removes the specified children of the specified branch from the visible
     * node list if necessary. If they are not already in the visible node list,
     * nothing happens. Invalidates the component only if necessary.
     *
     * @param parentBranchInfo The branch info of the parent node.
     * @param index The index of the first child node to remove from the visible
     * nodes sequence.
     * @param count The number of child nodes to remove, or <tt>-1</tt> to remove
     * all child nodes from the visible nodes sequence.
     */
    private void removeVisibleNodes(BranchInfo parentBranchInfo, int index, int count) {
        parentBranchInfo.loadChildren();
        int childrenLength = parentBranchInfo.children.getLength();

        int countUpdated = count;

        if (countUpdated == -1) {
            assert (index == 0) : "Non-zero index with 'remove all' count";
            countUpdated = childrenLength;
        }

        // If the index is greater-equal the child length, then there could
        // not possibly be any visible nodes, so just quit
        if (index >= childrenLength) {
            return;
        }
        assert (index + countUpdated <= childrenLength) : "Value too big";
        if (countUpdated > 0) {
            NodeInfo first = parentBranchInfo.children.get(index);
            NodeInfo last = parentBranchInfo.children.get(index + countUpdated - 1);

            int rangeStart = visibleNodes.indexOf(first);

            if (rangeStart >= 0) {
                int rangeEnd = visibleNodes.indexOf(last) + 1;

                assert (rangeEnd > rangeStart) : "Invalid visible node structure";

                // Continue looking as long as the node at our endpoint has a
                // greater depth than the last child node, which means that
                // it's a descendant of the last child node
                for (int n = visibleNodes.getLength(), nodeDepth = last.depth; rangeEnd < n
                    && visibleNodes.get(rangeEnd).depth > nodeDepth; rangeEnd++) {
                    continue;
                }

                visibleNodes.remove(rangeStart, rangeEnd - rangeStart);

                invalidateComponent();
            }
        }
    }

    /**
     * Repaints the region occupied by the specified node.
     *
     * @param nodeInfo The node to search for.
     */
    protected void repaintNode(NodeInfo nodeInfo) {
        Bounds bounds = getNodeBounds(nodeInfo);
        if (bounds != null) {
            repaintComponent(bounds);
        }
    }

    /**
     * Clears the highlighted node if one exists.
     */
    protected void clearHighlightedNode() {
        if (highlightedNode != null) {
            highlightedNode.setHighlighted(false);
            repaintNode(highlightedNode);

            highlightedNode = null;
        }
    }

    /**
     * Clears our <tt>NodeInfo</tt> hierarchy of the specified cached field.
     *
     * @param mask The bitmask specifying which field to clear.
     */
    private void clearFields(final byte mask) {
        accept(new NodeInfoVisitor() {
            @Override
            public void visit(NodeInfo nodeInfo) {
                nodeInfo.clearField(mask);
            }
        });
    }

    /**
     * Scrolls the last visible (expanded) selected node into viewport
     * visibility. If no such node exists, nothing happens. <p> This should only
     * be called when the tree view is valid.
     */
    private void scrollSelectionToVisible() {
        TreeView treeView = (TreeView) getComponent();

        Sequence<Path> selectedPaths = treeView.getSelectedPaths();
        int n = selectedPaths.getLength();

        if (n > 0) {
            Bounds nodeBounds = null;

            for (int i = n - 1; i >= 0 && nodeBounds == null; i--) {
                NodeInfo nodeInfo = getNodeInfoAt(selectedPaths.get(i));
                nodeBounds = getNodeBounds(nodeInfo);
            }

            if (nodeBounds != null) {
                Bounds visibleSelectionBounds = treeView.getVisibleArea(nodeBounds);
                if (visibleSelectionBounds != null
                    && visibleSelectionBounds.height < nodeBounds.height) {
                    treeView.scrollAreaToVisible(nodeBounds);
                }
            }
        }
    }

    @Override
    public boolean mouseMove(Component component, int x, int y) {
        boolean consumed = super.mouseMove(component, x, y);

        TreeView treeView = (TreeView) getComponent();

        if (showHighlight && treeView.getSelectMode() != SelectMode.NONE) {
            NodeInfo previousHighlightedNode = highlightedNode;
            highlightedNode = getNodeInfoAt(y);

            if (highlightedNode != previousHighlightedNode) {
                if (previousHighlightedNode != null) {
                    previousHighlightedNode.setHighlighted(false);
                    repaintNode(previousHighlightedNode);
                }

                if (highlightedNode != null) {
                    highlightedNode.setHighlighted(true);
                    repaintNode(highlightedNode);
                }
            }
        }

        return consumed;
    }

    @Override
    public void mouseOut(Component component) {
        super.mouseOut(component);

        clearHighlightedNode();
        selectPath = null;
    }

    @Override
    public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
        boolean consumed = super.mouseDown(component, button, x, y);

        if (!consumed) {
            TreeView treeView = (TreeView) getComponent();
            NodeInfo nodeInfo = getNodeInfoAt(y);

            if (nodeInfo != null && !nodeInfo.isDisabled()) {
                int nodeHeight = getNodeHeight();
                int baseNodeX = (nodeInfo.depth - 1) * (indent + spacing);

                int nodeX = baseNodeX + (showBranchControls ? indent + spacing : 0);
                int nodeY = (y / (nodeHeight + VERTICAL_SPACING)) * (nodeHeight + VERTICAL_SPACING);

                int checkboxWidth = CHECKBOX.getWidth();
                int checkboxHeight = CHECKBOX.getHeight();

                int checkboxX = Math.max(indent - checkboxWidth, 0) / 2;
                int checkboxY = (nodeHeight - checkboxHeight) / 2;

                // Only proceed if the user DIDN'T click on a checkbox
                if (!treeView.getCheckmarksEnabled() || nodeInfo.isCheckmarkDisabled()
                    || x < nodeX + checkboxX || x >= nodeX + checkboxX + checkboxWidth
                    || y < nodeY + checkboxY || y >= nodeY + checkboxY + checkboxHeight) {
                    Path path = nodeInfo.getPath();

                    // See if the user clicked on an expand/collapse control of
                    // a branch. If so, expand/collapse the branch
                    if (showBranchControls && nodeInfo instanceof BranchInfo && x >= baseNodeX
                        && x < baseNodeX + indent) {
                        BranchInfo branchInfo = (BranchInfo) nodeInfo;
                        treeView.setBranchExpanded(path, !branchInfo.isExpanded());
                        consumed = true;
                    }

                    // If we haven't consumed the event, then proceed to manage
                    // the selection state of the node
                    if (!consumed) {
                        SelectMode selectMode = treeView.getSelectMode();

                        if (button == Mouse.Button.LEFT) {
                            Modifier commandModifier = Platform.getCommandModifier();

                            if (Keyboard.isPressed(commandModifier)
                                && selectMode == SelectMode.MULTI) {
                                // Toggle the item's selection state
                                if (nodeInfo.isSelected()) {
                                    treeView.removeSelectedPath(path);
                                } else {
                                    treeView.addSelectedPath(path);
                                }
                            } else if (Keyboard.isPressed(commandModifier)
                                && selectMode == SelectMode.SINGLE) {
                                // Toggle the item's selection state
                                if (nodeInfo.isSelected()) {
                                    treeView.clearSelection();
                                } else {
                                    treeView.setSelectedPath(path);
                                }
                            } else {
                                if (selectMode != SelectMode.NONE) {
                                    if (nodeInfo.isSelected()) {
                                        selectPath = path;
                                    } else {
                                        treeView.setSelectedPath(path);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            treeView.requestFocus();
        }

        return consumed;
    }

    @Override
    public boolean mouseUp(Component component, Mouse.Button button, int x, int y) {
        boolean consumed = super.mouseUp(component, button, x, y);

        TreeView treeView = (TreeView) getComponent();
        if (selectPath != null
            && !treeView.getFirstSelectedPath().equals(treeView.getLastSelectedPath())) {
            treeView.setSelectedPath(selectPath);
            selectPath = null;
        }

        return consumed;
    }

    @Override
    public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
        boolean consumed = super.mouseClick(component, button, x, y, count);

        if (!consumed) {
            TreeView treeView = (TreeView) getComponent();
            NodeInfo nodeInfo = getNodeInfoAt(y);

            if (nodeInfo != null && !nodeInfo.isDisabled()) {
                int nodeHeight = getNodeHeight();
                int baseNodeX = (nodeInfo.depth - 1) * (indent + spacing);

                int nodeX = baseNodeX + (showBranchControls ? indent + spacing : 0);
                int nodeY = (y / (nodeHeight + VERTICAL_SPACING)) * (nodeHeight + VERTICAL_SPACING);

                int checkboxWidth = CHECKBOX.getWidth();
                int checkboxHeight = CHECKBOX.getHeight();

                int checkboxX = Math.max(indent - checkboxWidth, 0) / 2;
                int checkboxY = (nodeHeight - checkboxHeight) / 2;

                if (treeView.getCheckmarksEnabled() && !nodeInfo.isCheckmarkDisabled()
                    && x >= nodeX + checkboxX && x < nodeX + checkboxX + checkboxWidth
                    && y >= nodeY + checkboxY && y < nodeY + checkboxY + checkboxHeight) {
                    Path path = nodeInfo.getPath();
                    treeView.setNodeChecked(path, !nodeInfo.isChecked());
                } else {
                    if (selectPath != null && count == 1 && button == Mouse.Button.LEFT) {
                        TreeView.NodeEditor nodeEditor = treeView.getNodeEditor();
                        if (nodeEditor != null) {
                            if (nodeEditor.isEditing()) {
                                nodeEditor.endEdit(true);
                            }
                            nodeEditor.beginEdit(treeView, selectPath);
                        }
                    }
                    selectPath = null;
                }
            }
        }

        return consumed;
    }

    @Override
    public boolean mouseWheel(Component component, Mouse.ScrollType scrollType, int scrollAmount,
        int wheelRotation, int x, int y) {
        if (highlightedNode != null) {
            Bounds nodeBounds = getNodeBounds(highlightedNode);

            highlightedNode.setHighlighted(false);
            highlightedNode = null;

            if (nodeBounds != null) {
                repaintComponent(nodeBounds.x, nodeBounds.y, nodeBounds.width, nodeBounds.height,
                    true);
            }
        }

        return super.mouseWheel(component, scrollType, scrollAmount, wheelRotation, x, y);
    }

    /**
     * Keyboard handling (arrow keys with modifiers).
     * <ul>
     * <li>{@link KeyCode#UP UP} Selects the previous enabled node when select mode
     * is not {@link SelectMode#NONE}</li>
     * <li>{@link KeyCode#DOWN DOWN} Selects the next enabled node when select mode
     * is not {@link SelectMode#NONE}</li>
     * <li>{@link Modifier#SHIFT SHIFT} + {@link KeyCode#UP UP} Increases the
     * selection size by including the previous enabled node when select mode is
     * {@link SelectMode#MULTI}</li>
     * <li>{@link Modifier#SHIFT SHIFT} + {@link KeyCode#DOWN DOWN} Increases the
     * selection size by including the next enabled node when select mode is
     * {@link SelectMode#MULTI}</li>
     * </ul>
     */
    @Override
    public boolean keyPressed(Component component, int keyCode, KeyLocation keyLocation) {
        boolean consumed = false;

        TreeView treeView = (TreeView) getComponent();
        SelectMode selectMode = treeView.getSelectMode();

        switch (keyCode) {
            case KeyCode.UP:
                if (selectMode != SelectMode.NONE) {
                    Path firstSelectedPath = treeView.getFirstSelectedPath();

                    int index;
                    if (firstSelectedPath != null) {
                        NodeInfo previousSelectedNode = getNodeInfoAt(firstSelectedPath);
                        index = visibleNodes.indexOf(previousSelectedNode);
                    } else {
                        // Select the last visible node
                        index = visibleNodes.getLength();
                    }

                    NodeInfo newSelectedNode = null;
                    do {
                        newSelectedNode = (--index >= 0) ? visibleNodes.get(index) : null;
                    } while (newSelectedNode != null && newSelectedNode.isDisabled());

                    if (newSelectedNode != null) {
                        if (Keyboard.isPressed(Modifier.SHIFT)
                            && treeView.getSelectMode() == SelectMode.MULTI) {
                            treeView.addSelectedPath(newSelectedNode.getPath());
                        } else {
                            treeView.setSelectedPath(newSelectedNode.getPath());
                        }
                        treeView.scrollAreaToVisible(getNodeBounds(newSelectedNode));
                    }
                    consumed = true;
                }
                break;

            case KeyCode.DOWN:
                if (selectMode != SelectMode.NONE) {
                    Path lastSelectedPath = treeView.getLastSelectedPath();

                    int index;
                    if (lastSelectedPath != null) {
                        NodeInfo previousSelectedNode = getNodeInfoAt(lastSelectedPath);
                        index = visibleNodes.indexOf(previousSelectedNode);
                    } else {
                        // Select the first visible node
                        index = -1;
                    }

                    NodeInfo newSelectedNode = null;
                    int n = visibleNodes.getLength();
                    do {
                        newSelectedNode = (++index <= n - 1) ? visibleNodes.get(index) : null;
                    } while (newSelectedNode != null && newSelectedNode.isDisabled());

                    if (newSelectedNode != null) {
                        if (Keyboard.isPressed(Modifier.SHIFT)
                            && treeView.getSelectMode() == SelectMode.MULTI) {
                            treeView.addSelectedPath(newSelectedNode.getPath());
                        } else {
                            treeView.setSelectedPath(newSelectedNode.getPath());
                        }
                        treeView.scrollAreaToVisible(getNodeBounds(newSelectedNode));
                    }
                    consumed = true;
                }
                break;

            case KeyCode.LEFT:
                if (showBranchControls) {
                    Sequence<Path> paths = treeView.getSelectedPaths();

                    if (paths != null && paths.getLength() > 0) {
                        Path path = paths.get(paths.getLength() - 1);
                        NodeInfo nodeInfo = getNodeInfoAt(path);
                        if (nodeInfo instanceof BranchInfo) {
                            BranchInfo branchInfo = (BranchInfo) nodeInfo;
                            if (branchInfo.isExpanded()) {
                                treeView.collapseBranch(branchInfo.getPath());
                            }
                        }
                        consumed = true;
                    }
                }
                break;

            case KeyCode.RIGHT:
                if (showBranchControls) {
                    Sequence<Path> paths = treeView.getSelectedPaths();

                    if (paths != null && paths.getLength() > 0) {
                        Path path = paths.get(paths.getLength() - 1);
                        NodeInfo nodeInfo = getNodeInfoAt(path);
                        if (nodeInfo instanceof BranchInfo) {
                            BranchInfo branchInfo = (BranchInfo) nodeInfo;
                            if (!branchInfo.isExpanded()) {
                                treeView.expandBranch(branchInfo.getPath());
                            }
                        }
                        consumed = true;
                    }
                }
                break;

            default:
                consumed = super.keyPressed(component, keyCode, keyLocation);
                break;
        }

        if (consumed) {
            clearHighlightedNode();
        }

        return consumed;
    }

    /**
     * {@link KeyCode#SPACE SPACE} toggles check mark selection when select mode
     * is {@link SelectMode#SINGLE}.
     */
    @Override
    public boolean keyReleased(Component component, int keyCode, KeyLocation keyLocation) {
        boolean consumed = false;

        TreeView treeView = (TreeView) getComponent();

        if (keyCode == KeyCode.SPACE) {
            if (treeView.getCheckmarksEnabled()
                && treeView.getSelectMode() == SelectMode.SINGLE) {
                Path selectedPath = treeView.getSelectedPath();

                if (selectedPath != null) {
                    NodeInfo nodeInfo = getNodeInfoAt(selectedPath);

                    if (!nodeInfo.isCheckmarkDisabled()) {
                        treeView.setNodeChecked(selectedPath, !treeView.isNodeChecked(selectedPath));
                    }
                }
            }
        } else {
            consumed = super.keyReleased(component, keyCode, keyLocation);
        }

        return consumed;
    }

    @Override
    public boolean isFocusable() {
        TreeView treeView = (TreeView) getComponent();
        return (treeView.getSelectMode() != SelectMode.NONE);
    }

    @Override
    public boolean isOpaque() {
        return (backgroundColor != null && backgroundColor.getTransparency() == Transparency.OPAQUE);
    }

    // ComponentStateListener methods

    @Override
    public void enabledChanged(Component component) {
        super.enabledChanged(component);
        repaintComponent();
    }

    @Override
    public void focusedChanged(Component component, Component obverseComponent) {
        super.focusedChanged(component, obverseComponent);
        repaintComponent();
    }

    // TreeView.Skin methods

    @Override
    public Path getNodeAt(int y) {
        Path path = null;

        NodeInfo nodeInfo = getNodeInfoAt(y);

        if (nodeInfo != null) {
            path = nodeInfo.getPath();
        }

        return path;
    }

    @Override
    public Bounds getNodeBounds(Path path) {
        Bounds nodeBounds = null;

        NodeInfo nodeInfo = getNodeInfoAt(path);

        if (nodeInfo != null) {
            nodeBounds = getNodeBounds(nodeInfo);
        }

        return nodeBounds;
    }

    @Override
    public int getNodeIndent(int depth) {
        TreeView treeView = (TreeView) getComponent();

        int nodeIndent = (depth - 1) * (indent + spacing);

        if (showBranchControls) {
            nodeIndent += indent + spacing;
        }

        if (treeView.getCheckmarksEnabled()) {
            nodeIndent += Math.max(CHECKBOX.getWidth(), indent) + spacing;
        }

        return nodeIndent;
    }

    @Override
    public int getRowIndex(Path path) {
        int rowIndex = -1;

        NodeInfo nodeInfo = getNodeInfoAt(path);

        if (nodeInfo != null) {
            rowIndex = visibleNodes.indexOf(nodeInfo);
        }

        return rowIndex;
    }

    // TreeViewListener methods

    @Override
    public void treeDataChanged(TreeView treeView, List<?> previousTreeData) {
        @SuppressWarnings("unchecked")
        List<Object> treeData = (List<Object>) treeView.getTreeData();

        visibleNodes.clear();

        if (treeData == null) {
            rootBranchInfo = null;
        } else {
            rootBranchInfo = new BranchInfo(treeView, null, treeData);
            addVisibleNodes(rootBranchInfo);
        }

        invalidateComponent();
    }

    @Override
    public void nodeRendererChanged(TreeView treeView, TreeView.NodeRenderer previousNodeRenderer) {
        invalidateComponent();
    }

    @Override
    public void selectModeChanged(TreeView treeView, SelectMode previousSelectMode) {
        // The selection has implicitly been cleared
        clearFields(NodeInfo.SELECTED_MASK);
        repaintComponent();
    }

    @Override
    public void checkmarksEnabledChanged(TreeView treeView) {
        // The check state of all nodes has implicitly been cleared
        clearFields(NodeInfo.CHECK_STATE_MASK);
        invalidateComponent();
    }

    @Override
    public void showMixedCheckmarkStateChanged(TreeView treeView) {
        if (treeView.getCheckmarksEnabled()) {
            // The check state of all *branch* nodes may have changed, so we
            // need to update the cached check state of all BranchNode
            // instances in our hierarchy
            Sequence<NodeInfo> nodes = new ArrayList<>();
            nodes.add(rootBranchInfo);

            while (nodes.getLength() > 0) {
                NodeInfo nodeInfo = nodes.get(0);
                nodes.remove(0, 1);

                // Only branch nodes can be affected by this event
                if (nodeInfo instanceof BranchInfo) {
                    BranchInfo branchInfo = (BranchInfo) nodeInfo;

                    // Update the cached entry for this branch
                    Path path = branchInfo.getPath();
                    branchInfo.setCheckState(treeView.getNodeCheckState(path));

                    // Add the branch's children to the queue
                    if (branchInfo.children != null) {
                        for (int i = 0, n = branchInfo.children.getLength(); i < n; i++) {
                            nodes.insert(branchInfo.children.get(i), i);
                        }
                    }
                }
            }

            repaintComponent();
        }
    }

    @Override
    public void disabledNodeFilterChanged(TreeView treeView, Filter<?> previousDisabledNodeFilter) {
        @SuppressWarnings("unchecked")
        final Filter<Object> disabledNodeFilter = (Filter<Object>) treeView.getDisabledNodeFilter();

        accept(new NodeInfoVisitor() {
            @Override
            public void visit(NodeInfo nodeInfo) {
                if (nodeInfo != rootBranchInfo) {
                    nodeInfo.setDisabled(disabledNodeFilter != null
                        && disabledNodeFilter.include(nodeInfo.data));
                }
            }
        });

        repaintComponent();
    }

    @Override
    public void disabledCheckmarkFilterChanged(TreeView treeView,
        Filter<?> previousDisabledCheckmarkFilter) {
        @SuppressWarnings("unchecked")
        final Filter<Object> disabledCheckmarkFilter = (Filter<Object>) treeView.getDisabledCheckmarkFilter();

        accept(new NodeInfoVisitor() {
            @Override
            public void visit(NodeInfo nodeInfo) {
                if (nodeInfo != rootBranchInfo) {
                    nodeInfo.setCheckmarkDisabled(disabledCheckmarkFilter != null
                        && disabledCheckmarkFilter.include(nodeInfo.data));
                }
            }
        });

        repaintComponent();
    }

    // TreeViewBranchListener methods

    @Override
    public void branchExpanded(TreeView treeView, Path path) {
        BranchInfo branchInfo = (BranchInfo) getNodeInfoAt(path);

        branchInfo.setExpanded(true);
        addVisibleNodes(branchInfo);

        repaintNode(branchInfo);
    }

    @Override
    public void branchCollapsed(TreeView treeView, Path path) {
        BranchInfo branchInfo = (BranchInfo) getNodeInfoAt(path);

        branchInfo.setExpanded(false);
        removeVisibleNodes(branchInfo, 0, -1);

        repaintNode(branchInfo);
    }

    @Override
    public Vote previewBranchExpandedChange(TreeView treeView, Path path) {
        // We currently have no reason to refuse to open / close the branch
        // although other listeners might have a reason
        return Vote.APPROVE;
    }

    @Override
    public void branchExpandedChangeVetoed(TreeView treeView, Path path, Vote reason) {
        // Nothing really to do -- our visual state doesn't change until/unless the
        // expand/collapse really happens
    }

    // TreeViewNodeListener methods

    @Override
    @SuppressWarnings("unchecked")
    public void nodeInserted(TreeView treeView, Path path, int index) {
        BranchInfo branchInfo = (BranchInfo) getNodeInfoAt(path);
        List<Object> branchData = (List<Object>) branchInfo.data;

        // Update our internal branch info
        if (branchInfo.children != null) {
            NodeInfo nodeInfo = NodeInfo.newInstance(treeView, branchInfo, branchData.get(index));
            branchInfo.children.insert(nodeInfo, index);
        }

        // Add the node to the visible nodes list
        addVisibleNode(branchInfo, index);

        // If the empty branch controls are not shown, then this event might
        // need a repaint of the parent
        if (!showEmptyBranchControls) {
            repaintNode(branchInfo);
        }
    }

    @Override
    public void nodesRemoved(TreeView treeView, Path path, int index, int count) {
        BranchInfo branchInfo = (BranchInfo) getNodeInfoAt(path);

        // Remove the nodes from the visible nodes list
        removeVisibleNodes(branchInfo, index, count);

        // Update our internal branch info
        if (branchInfo.children != null) {
            // Problem: if "loadChildren" was called on this branch the first time
            // by "removeVisibleNodes" above, then the "children" will actually be
            // correct here (i.e., already removed), so this is unnecessary.
            int len = branchInfo.children.getLength();
            if (index < len && index + count <= len) {
                branchInfo.children.remove(index, count);
            }
        }

        // If the empty branch controls are not shown, then this event might
        // need a repaint of the parent
        if (!showEmptyBranchControls) {
            repaintNode(branchInfo);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public void nodeUpdated(TreeView treeView, Path path, int index) {
        BranchInfo branchInfo = (BranchInfo) getNodeInfoAt(path);
        List<Object> branchData = (List<Object>) branchInfo.data;

        branchInfo.loadChildren();
        NodeInfo nodeInfo = branchInfo.children.get(index);

        Object previousNodeData = nodeInfo.data;
        Object nodeData = branchData.get(index);

        if (previousNodeData != nodeData) {
            // Remove the old node from the visible nodes list
            removeVisibleNodes(branchInfo, index, 1);

            // Update our internal branch info
            nodeInfo = NodeInfo.newInstance(treeView, branchInfo, nodeData);
            branchInfo.children.update(index, nodeInfo);

            // Add the new node to the visible nodes list
            addVisibleNode(branchInfo, index);
        } else {
            // This update might affect the node's disabled state
            Filter<Object> disabledNodeFilter = (Filter<Object>) treeView.getDisabledNodeFilter();
            nodeInfo.setDisabled(disabledNodeFilter != null && disabledNodeFilter.include(nodeData));

            if (visibleNodes.indexOf(nodeInfo) >= 0) {
                // The updated node data might affect our preferred width
                invalidateComponent();
            }
        }
    }

    @Override
    public void nodesCleared(TreeView treeView, Path path) {
        BranchInfo branchInfo = (BranchInfo) getNodeInfoAt(path);

        // Remove the node from the visible nodes list
        removeVisibleNodes(branchInfo, 0, -1);

        // Update our internal branch info
        if (branchInfo.children != null) {
            branchInfo.children.clear();
        }
    }

    @Override
    public void nodesSorted(TreeView treeView, Path path) {
        BranchInfo branchInfo = (BranchInfo) getNodeInfoAt(path);

        // Remove the child nodes from the visible nodes list
        removeVisibleNodes(branchInfo, 0, -1);

        // Re-load the branch's children to get the correct sort order
        branchInfo.children = null;
        branchInfo.loadChildren();

        // Add the child nodes back to the visible nodes list
        addVisibleNodes(branchInfo);
    }

    // TreeViewNodeStateListener methods

    @Override
    public void nodeCheckStateChanged(TreeView treeView, Path path,
        TreeView.NodeCheckState previousCheckState) {
        NodeInfo nodeInfo = getNodeInfoAt(path);

        nodeInfo.setCheckState(treeView.getNodeCheckState(path));

        repaintNode(nodeInfo);
    }

    // TreeViewSelectionListener methods

    @Override
    public void selectedPathAdded(TreeView treeView, Path path) {
        // Update the node info
        NodeInfo nodeInfo = getNodeInfoAt(path);
        nodeInfo.setSelected(true);

        if (treeView.isValid()) {
            Bounds nodeBounds = getNodeBounds(nodeInfo);

            if (nodeBounds != null) {
                // Ensure that the selection is visible
                Bounds visibleSelectionBounds = treeView.getVisibleArea(nodeBounds);
                if (visibleSelectionBounds.height < nodeBounds.height) {
                    treeView.scrollAreaToVisible(nodeBounds);
                }
            }
        } else {
            validateSelection = true;
        }

        repaintNode(nodeInfo);
    }

    @Override
    public void selectedPathRemoved(TreeView treeView, Path path) {
        NodeInfo nodeInfo = getNodeInfoAt(path);
        nodeInfo.setSelected(false);
        repaintNode(nodeInfo);
    }

    @Override
    public void selectedPathsChanged(TreeView treeView, Sequence<Path> previousSelectedPaths) {
        if (previousSelectedPaths != null && previousSelectedPaths != treeView.getSelectedPaths()) {
            // Ensure that the selection is visible
            if (treeView.isValid()) {
                scrollSelectionToVisible();
            } else {
                validateSelection = true;
            }

            // Un-select the previous selected paths
            for (int i = 0, n = previousSelectedPaths.getLength(); i < n; i++) {
                NodeInfo previousSelectedNode = getNodeInfoAt(previousSelectedPaths.get(i));
                previousSelectedNode.setSelected(false);
                repaintNode(previousSelectedNode);
            }

            Sequence<Path> selectedPaths = treeView.getSelectedPaths();

            // Select the current selected paths
            for (int i = 0, n = selectedPaths.getLength(); i < n; i++) {
                NodeInfo selectedNode = getNodeInfoAt(selectedPaths.get(i));
                selectedNode.setSelected(true);
                repaintNode(selectedNode);
            }
        }
    }

}
