/*
 * jNPad v0.3 - jNPad's an Simple Text Editor written in Java
 *
 * Copyright (C) 2014-2017  rgs
 *
 * Require JDK 1.6 (or later)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program 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 for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 *
 * Info, Questions, Suggestions & Bugs Report to rgsevero@gmail.com
 */

package jnpad.ui.plaf;

import java.awt.Adjustable;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.metal.MetalScrollBarUI;

import jnpad.ui.ColorUtilities;

/**
 * The Class JNPadScrollBarUI.
 *
 * @version 0.3
 * @since   jNPad v0.1
 */
public final class JNPadScrollBarUI extends MetalScrollBarUI {
  private static Color thumbColor;
  private static Color thumbShadow;
  private static Color thumbHighlightColor;

  private Color        highlight;
  private Color        shadow;

  private Color        a, b, c, d;
  private boolean      clicked;

  /**
   *
   * @param c JComponent
   * @return ComponentUI
   */
  public static ComponentUI createUI(JComponent c) {
    return new JNPadScrollBarUI();
  }

  /**
   *
   * @return TrackListener
   */
  @Override
  protected TrackListener createTrackListener(){
    return new JNPadTrackListener();
  }

  /**
   *
   * @param orientation int
   * @return JButton
   */
  @Override
  protected JButton createDecreaseButton(int orientation) {
    decreaseButton = new JNPadScrollButton(orientation, scrollBarWidth, isFreeStanding);
    return decreaseButton;
  }

  /**
   *
   * @param orientation int
   * @return JButton
   */
  @Override
  protected JButton createIncreaseButton(int orientation) {
    increaseButton = new JNPadScrollButton(orientation, scrollBarWidth, isFreeStanding);
    return increaseButton;
  }

  /**
   *
   */
  @Override
  protected void configureScrollBarColors() {
    super.configureScrollBarColors();
	thumbColor          = UIManager.getColor("ScrollBar.thumb");         //$NON-NLS-1$
	thumbShadow         = UIManager.getColor("ScrollBar.thumbShadow");   //$NON-NLS-1$
	thumbHighlightColor = UIManager.getColor("ScrollBar.thumbHighlight");//$NON-NLS-1$
  }

  /**
   *
   * @param g Graphics
   * @param c JComponent
   * @param thumbBounds Rectangle
   */
  @Override
  protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
    if (!c.isEnabled()) {
      return;
    }

    g.translate(thumbBounds.x, thumbBounds.y);

    Graphics2D g2D = (Graphics2D) g;

    Color c1, c2;
    if (clicked) {
      c1 = thumbColor;
      c2 = thumbHighlightColor;
    }
    else {
      c1 = thumbHighlightColor;
      c2 = thumbColor;
    }

    boolean leftToRight = c.getComponentOrientation().isLeftToRight();

    if ( ( (JScrollBar) c).getOrientation() == Adjustable.VERTICAL) {

      if (!isFreeStanding) {
        if (!leftToRight) {
          thumbBounds.width += 1;
          g.translate( -1, 0);
        }
        else {
          thumbBounds.width += 2;
        }
      }

      g2D.setPaint(new GradientPaint(0, 0, c1, thumbBounds.width / 2 + 1, 0, c2, true));
      g2D.fillRect(0, 0, thumbBounds.width - 2, thumbBounds.height - 1);

      g.setColor(thumbShadow);
      g.drawRect(0, 0, thumbBounds.width - 2, thumbBounds.height - 1);

      g.setColor(thumbHighlightColor);
      g.drawLine(1, 1, thumbBounds.width - 3, 1);
      g.drawLine(1, 1, 1, thumbBounds.height - 2);

      int i = (int) thumbBounds.getWidth() / 2;
      int k = (int) thumbBounds.getHeight() / 2;

      boolean small = thumbBounds.getHeight() <= 20D;

      g.setColor(a());
      if (!small) {
        g.drawLine(i - 3, k - 8, i + 3, k - 8);
      }
      g.drawLine(i - 3, k - 4, i + 3, k - 4);
      g.drawLine(i - 3, k, i + 3, k);
      g.drawLine(i - 3, k + 4, i + 3, k + 4);
      if (!small) {
        g.drawLine(i - 3, k + 8, i + 3, k + 8);
      }

      g.setColor(b());
      if (!small) {
        g.drawLine(i - 2, k - 7, i + 4, k - 7);
      }
      g.drawLine(i - 2, k - 3, i + 4, k - 3);
      g.drawLine(i - 2, k + 1, i + 4, k + 1);
      g.drawLine(i - 2, k + 5, i + 4, k + 5);
      if (!small) {
        g.drawLine(i - 2, k + 9, i + 4, k + 9);
      }

      if (!isFreeStanding) {
        if (!leftToRight) {
          thumbBounds.width -= 1;
          g.translate(1, 0);
        }
        else {
          thumbBounds.width -= 2;
        }
      }
    }
    else { // HORIZONTAL
      if (!isFreeStanding) {
        thumbBounds.height += 2;
      }

      g2D.setPaint(new GradientPaint(0, 0, c1, 0, thumbBounds.height / 2 + 1, c2, true));
      g2D.fillRect(0, 0, thumbBounds.width - 1, thumbBounds.height - 2);

      g.setColor(thumbShadow);
      g.drawRect(0, 0, thumbBounds.width - 1, thumbBounds.height - 2);

      g.setColor(thumbHighlightColor);
      g.drawLine(1, 1, thumbBounds.width - 3, 1);
      g.drawLine(1, 1, 1, thumbBounds.height - 3);

      int j = (int) thumbBounds.getWidth() / 2;
      int l = (int) thumbBounds.getHeight() / 2;

      boolean small = thumbBounds.getWidth() <= 20D;

      g.setColor(c());
      if (!small) {
        g.drawLine(j - 8, l - 3, j - 8, l + 3);
      }
      g.drawLine(j - 4, l - 3, j - 4, l + 3);
      g.drawLine(j, l - 3, j, l + 3);
      g.drawLine(j + 4, l - 3, j + 4, l + 3);
      if (!small) {
        g.drawLine(j + 8, l - 3, j + 8, l + 3);
      }

      g.setColor(d());
      if (!small) {
        g.drawLine(j - 7, l - 2, j - 7, l + 4);
      }
      g.drawLine(j - 3, l - 2, j - 3, l + 4);
      g.drawLine(j + 1, l - 2, j + 1, l + 4);
      g.drawLine(j + 5, l - 2, j + 5, l + 4);
      if (!small) {
        g.drawLine(j + 9, l - 2, j + 9, l + 4);
      }

      if (!isFreeStanding) {
        thumbBounds.height -= 2;
      }
    }

    g.translate( -thumbBounds.x, -thumbBounds.y);
  }

  /**
   *
   * @param g Graphics
   * @param c JComponent
   * @param trackBounds Rectangle
   */
  @Override
  protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) {
    super.paintTrack(g, c, trackBounds);

    Graphics2D g2D = (Graphics2D) g;
    GradientPaint grad;

    if (scrollbar.getOrientation() == Adjustable.HORIZONTAL) {
      grad = new GradientPaint(trackBounds.x, trackBounds.y, shadow(),
                               trackBounds.x, trackBounds.y + trackBounds.height, highlight());
    }
    else {
      grad = new GradientPaint(trackBounds.x, trackBounds.y, shadow(),
                               trackBounds.x + trackBounds.width, trackBounds.y, highlight());
    }

    g2D.setPaint(grad);
    g2D.fill(trackBounds);
  }

  /**
   *
   * @return Color
   */
  private Color highlight() {
    if (highlight == null)
      highlight = ColorUtilities.withAlpha(trackHighlightColor, 64);
    return highlight;
  }

  /**
   *
   * @return Color
   */
  private Color shadow() {
    if (shadow == null)
      shadow = ColorUtilities.withAlpha(trackColor, 64);
    return shadow;
  }

  /**
   *
   * @return Color
   */
  private Color a() {
    if (a == null)
      a = ColorUtilities.withAlpha(thumbShadow, 150);
    return a;
  }

  /**
   *
   * @return Color
   */
  private Color b() {
    if (b == null)
      b = ColorUtilities.withAlpha(thumbHighlightColor, 150);
    return b;
  }

  /**
   *
   * @return Color
   */
  private Color c() {
    if (c == null)
      c = ColorUtilities.withAlpha(thumbShadow, 200);
    return c;
  }

  /**
   *
   * @return Color
   */
  private Color d() {
    if (d == null)
      d = ColorUtilities.withAlpha(thumbHighlightColor, 200);
    return d;
  }

  //////////////////////////////////////////////////////////////////////////////
  /**
   * The Class JNPadTrackListener.
   */
  protected class JNPadTrackListener extends MetalScrollBarUI.TrackListener {
    /**
     * Mouse pressed.
     *
     * @param e the MouseEvent
     * @see javax.swing.plaf.basic.BasicScrollBarUI.TrackListener#mousePressed(java.awt.event.MouseEvent)
     */
    @Override
    public void mousePressed(MouseEvent e) {
      super.mousePressed(e);
      clicked = true;
      scrollbar.repaint();
    }

    /**
     * Mouse released.
     *
     * @param e the MouseEvent
     * @see javax.swing.plaf.basic.BasicScrollBarUI.TrackListener#mouseReleased(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseReleased(MouseEvent e) {
      super.mouseReleased(e);
      clicked = false;
      scrollbar.repaint();
    }
  }
  //////////////////////////////////////////////////////////////////////////////

}
