/**
   * Updates the scroll bar's value.
   *
   * @param component The scroll bar.
   * @param scrollType Unit or block scrolling.
   * @param scrollAmount The amount of scrolling.
   * @param wheelRotation <tt>-1</tt> or <tt>1</tt> for backward or forward scrolling, respectively.
   * @param x The x-coordinate of the event in the scroll bar's coordinate space.
   * @param y The y-coordinate of the event in the scroll bar's coordinate space.
   */
  @Override
  public boolean mouseWheel(
      Component component,
      Mouse.ScrollType scrollType,
      int scrollAmount,
      int wheelRotation,
      int x,
      int y) {
    boolean consumed = false;

    ScrollBar scrollBar = (ScrollBar) getComponent();

    int previousValue = scrollBar.getValue();
    int newValue = previousValue + (scrollAmount * wheelRotation * scrollBar.getUnitIncrement());

    if (wheelRotation > 0) {
      int maxValue = scrollBar.getEnd() - scrollBar.getExtent();
      newValue = Math.min(newValue, maxValue);

      if (previousValue < maxValue) {
        consumed = true;
      }
    } else {
      newValue = Math.max(newValue, 0);

      if (previousValue > 0) {
        consumed = true;
      }
    }

    scrollBar.setValue(newValue);

    return consumed;
  }
    private void scroll() {
      ScrollBar scrollBar = (ScrollBar) TerraScrollBarSkin.this.getComponent();

      int start = scrollBar.getStart();
      int end = scrollBar.getEnd();
      int extent = scrollBar.getExtent();
      int value = scrollBar.getValue();

      int adjustment;

      if (incrementType == Mouse.ScrollType.UNIT) {
        adjustment = direction * scrollBar.getUnitIncrement();
      } else {
        adjustment = direction * scrollBar.getBlockIncrement();
      }

      if (adjustment < 0) {
        int newValue = Math.max(value + adjustment, start);
        scrollBar.setValue(newValue);

        if (stopValue != -1 && newValue < stopValue) {
          // We've reached the explicit stop value
          stop();
        }

        if (newValue == start) {
          // We implicit stop at the minimum scroll bar value
          stop();
        }
      } else {
        int newValue = Math.min(value + adjustment, end - extent);
        scrollBar.setValue(newValue);

        if (stopValue != -1 && newValue > stopValue) {
          // We've reached the explicit stop value
          stop();
        }

        if (newValue == end - extent) {
          // We implicitly stop at the maximum scroll bar value
          stop();
        }
      }
    }
  @Override
  public void valueChanged(ScrollBar scrollBar, int previousValue) {
    // Invalidating the component would yield the correct behavior but
    // would be overkill. If all that has changed is the value, we can just
    // update the handle's location and save the work of full invalidation.
    if (handle.isVisible()) {
      int value = scrollBar.getValue();

      if (scrollBar.getOrientation() == Orientation.HORIZONTAL) {
        int handleX = (int) (value * getValueScale()) + scrollUpButton.getWidth() - 1;

        handle.setLocation(handleX, 0);
      } else {
        int handleY = (int) (value * getValueScale()) + scrollUpButton.getHeight() - 1;

        handle.setLocation(0, handleY);
      }
    }
  }
  @Override
  public void layout() {
    ScrollBar scrollBar = (ScrollBar) getComponent();

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

    int start = scrollBar.getStart();
    int end = scrollBar.getEnd();
    int extent = scrollBar.getExtent();
    int value = scrollBar.getValue();

    int maxLegalRealValue = end - extent;
    int numLegalRealValues = maxLegalRealValue - start + 1;
    float extentPercentage = (float) extent / (float) (end - start);

    if (scrollBar.getOrientation() == Orientation.HORIZONTAL) {
      scrollUpButton.setSize(scrollUpButton.getPreferredWidth(-1), height);
      scrollUpButton.setLocation(0, 0);

      scrollDownButton.setSize(scrollDownButton.getPreferredWidth(-1), height);
      scrollDownButton.setLocation(width - scrollDownButton.getWidth(), 0);

      if (scrollBar.isEnabled()) {
        // Calculate the handle width first, as it dictates how much
        // room is left to represent the range of legal values. Note
        // that the handle may overlap each scroll button by 1px so
        // that its borders merge into the borders of the scroll buttons
        int availableWidth = width - scrollUpButton.getWidth() - scrollDownButton.getWidth() + 2;
        int handleWidth =
            Math.max(minimumHandleLength, Math.round(extentPercentage * availableWidth));

        // Calculate the position of the handle by calculating the
        // scale that maps logical value to pixel value
        int numLegalPixelValues = availableWidth - handleWidth + 1;
        float valueScale = (float) numLegalPixelValues / (float) numLegalRealValues;
        int handleX = (int) (value * valueScale) + scrollUpButton.getWidth() - 1;

        if (handleWidth > availableWidth) {
          // If we can't fit the handle, we hide it
          handle.setVisible(false);
        } else {
          handle.setVisible(true);

          handle.setSize(handleWidth, height);
          handle.setLocation(handleX, 0);
        }
      } else {
        handle.setVisible(false);
      }
    } else {
      scrollUpButton.setSize(width, scrollUpButton.getPreferredHeight(-1));
      scrollUpButton.setLocation(0, 0);

      scrollDownButton.setSize(width, scrollDownButton.getPreferredHeight(-1));
      scrollDownButton.setLocation(0, height - scrollDownButton.getHeight());

      if (scrollBar.isEnabled()) {
        // Calculate the handle height first, as it dictates how much
        // room is left to represent the range of legal values. Note
        // that the handle may overlap each scroll button by 1px so
        // that its borders merge into the borders of the scroll buttons
        int availableHeight =
            height - scrollUpButton.getHeight() - scrollDownButton.getHeight() + 2;
        int handleHeight =
            Math.max(minimumHandleLength, Math.round(extentPercentage * availableHeight));

        // Calculate the position of the handle by calculating the
        // scale maps logical value to pixel value
        int numLegalPixelValues = availableHeight - handleHeight + 1;
        float valueScale = (float) numLegalPixelValues / (float) numLegalRealValues;
        int handleY = (int) (value * valueScale) + scrollUpButton.getHeight() - 1;

        if (handleHeight > availableHeight) {
          // If we can't fit the handle, we hide it
          handle.setVisible(false);
        } else {
          handle.setVisible(true);

          handle.setSize(width, handleHeight);
          handle.setLocation(0, handleY);
        }
      } else {
        handle.setVisible(false);
      }
    }
  }