/* BasicProgressBarUI.java --
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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, or (at your option)
any later version.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.plaf.basic;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JComponent;
import javax.swing.JProgressBar;
import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ProgressBarUI;

/**
 * The Basic Look and Feel UI delegate for the 
 * JProgressBar.
 */
public class BasicProgressBarUI extends ProgressBarUI
{
  /**
   * A helper class that listens for ChangeEvents 
   * from the progressBar's model.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class ChangeHandler implements ChangeListener
  {
    /**
     * Called every time the state of the model changes.
     *
     * @param e The ChangeEvent given by the model.
     */
    public void stateChanged(ChangeEvent e)
    {
      // Nothing to do but repaint.
      progressBar.repaint();
    }
  }

  /**
   * This helper class is used to listen for 
   * PropertyChangeEvents from the progressBar.
   */
  private class PropertyChangeHandler implements PropertyChangeListener
  {
    /**
     * Called every time the properties of the 
     * progressBar change.
     *
     * @param e The PropertyChangeEvent given by the progressBar.
     */
    public void propertyChange(PropertyChangeEvent e)
    {
      // Only need to listen for indeterminate changes.
      // All other things are done on a repaint.
      if (e.getPropertyName().equals("indeterminate"))
        if (((Boolean) e.getNewValue()).booleanValue()
            && progressBar.isShowing())
          startAnimationTimer();
        else
          stopAnimationTimer();
    }
  }

  /**
   * Receives notification when the progressbar is becoming visible or
   * invisible and starts/stops the animation timer accordingly.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  private class AncestorHandler implements AncestorListener
  {

    /**
     * Receives notification when the progressbar is becoming visible. This
     * starts the animation timer if the progressbar is indeterminate.
     *
     * @param event the ancestor event
     */
    public void ancestorAdded(AncestorEvent event)
    {
      if (progressBar.isIndeterminate())
        startAnimationTimer();
    }

    /**
     * Receives notification when the progressbar is becoming invisible. This
     * stops the animation timer if the progressbar is indeterminate.
     *
     * @param event the ancestor event
     */
    public void ancestorRemoved(AncestorEvent event)
    {
      stopAnimationTimer();
    }

    /**
     * Receives notification when an ancestor has been moved. We don't need to
     * do anything here.
     */
    public void ancestorMoved(AncestorEvent event)
    {
      // Nothing to do here.
    }
    
  }

  /**
   * This helper class is used to listen for 
   * the animationTimer's intervals. On every interval,
   * the bouncing box should move.
   */
  private class Animator implements ActionListener
  {
    /**
     * Called every time the animationTimer reaches
     * its interval.
     *
     * @param e The ActionEvent given by the timer.
     */
    public void actionPerformed(ActionEvent e)
    {
      // Incrementing the animation index will cause
      // a repaint.
      incrementAnimationIndex();
    }
  }

  /**
   * Receives notification when the size of the progress bar changes and
   * invalidates the layout information for the box calculation in
   * {@link BasicProgressBarUI#getBox(Rectangle)}.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  private class ComponentHandler extends ComponentAdapter
  {
    /**
     * Receives notification when the size of the progress bar changes and
     * invalidates the layout information for the box calculation in
     * {@link BasicProgressBarUI#getBox}.
     *
     * @param e the component event
     */
    public void componentResized(ComponentEvent e)
    {
      boxDependent = -1;
      boxIndependent = -1;
      incr = -1;
    }
  }

  /**
   * Holds the value of the bouncing box that is returned by {@link #getBox}.
   *
   * @since 1.5
   */ 
  protected Rectangle boxRect;

  /** The timer used to move the bouncing box. */
  private transient Timer animationTimer;

  // The total number of frames must be an even number.
  // The total number of frames is calculated from
  // the cycleTime and repaintInterval given by
  // the basic Look and Feel defaults.
  //
  // +-----------------------------------------------+
  // | frame0 | frame1 | frame2 | frame 3 | frame 4  |
  // |        | frame7 | frame6 | frame 5 |          |
  // +-----------------------------------------------+
  
  /** The current animation index. */
  private transient int animationIndex;

  /** The total number of frames.*/
  private transient int numFrames;

  /** The helper that moves the bouncing box. */
  private transient Animator animation;

  /** The helper that listens for property change events. */
  private transient PropertyChangeHandler propertyListener;

  /** The Listener for the model. */
  protected ChangeListener changeListener;

  /** The progressBar for this UI. */
  protected JProgressBar progressBar;


  /**
   * The size of the box returned by {@link #getBox} in the orientation
   * direction of the progress bar. This is package private to avoid accessor
   * method.
   */
  transient double boxDependent = - 1;

  /**
   * The size of the box returned by {@link #getBox} against the orientation
   * direction of the progress bar. This is package private to avoid accessor
   * method. 
   */
  transient int boxIndependent = - 1;

  /**
   * The increment for box animation. This is package private to avoid accessor
   * method.
   */
  transient double incr = -1;

  /** The length of the cell. The cell is the painted part. */
  private transient int cellLength;

  /** The gap between cells. */
  private transient int cellSpacing;

  /** The color of the text when the bar is not over it.*/
  private transient Color selectionBackground;

  /** The color of the text when the bar is over it. */
  private transient Color selectionForeground;

  /**
   * Listens for notification when the component becomes showing and
   * starts/stops the animation timer.
   */
  private AncestorListener ancestorListener;

  /**
   * Listens for resize events on the progress bar and invalidates some
   * layout info.
   */
  private ComponentListener componentListener;

  /**
   * Creates a new BasicProgressBarUI object.
   */
  public BasicProgressBarUI()
  {
    super();
  }

  /**
   * Creates a new BasicProgressBarUI for the component.
   *
   * @param x The JComponent to create the UI for.
   *
   * @return A new BasicProgressBarUI.
   */
  public static ComponentUI createUI(JComponent x)
  {
    return new BasicProgressBarUI();
  }

  /**
   * This method returns the length of the bar (from the minimum)
   * in pixels (or units that the Graphics object draws in) based
   * on the progressBar's getPercentComplete() value.
   *
   * @param b The insets of the progressBar.
   * @param width The width of the progressBar.
   * @param height The height of the progressBar.
   *
   * @return The length of the bar that should be painted in pixels.
   */
  protected int getAmountFull(Insets b, int width, int height)
  {
    double percentDone = progressBar.getPercentComplete();
    if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
      return (int) (percentDone * (width - b.left - b.right));
    else
      return (int) (percentDone * (height - b.top - b.bottom));
  }

  /**
   * The current animation index.
   *
   * @return The current animation index.
   */
  protected int getAnimationIndex()
  {
    return animationIndex;
  }

  /**
   * This method returns the size and position of the bouncing box
   * for the current animation index. It stores the values in the 
   * given rectangle and returns it. It returns null if no box should
   * be drawn.
   *
   * @param r The bouncing box rectangle.
   *
   * @return The bouncing box rectangle.
   */
  protected Rectangle getBox(Rectangle r)
  {
    if (!progressBar.isIndeterminate())
      return null;
    if (r == null)
      r = new Rectangle();

    Rectangle vr = new Rectangle();
    SwingUtilities.calculateInnerArea(progressBar, vr);

    // Recalculate the metrics only when size of the progressbar has changed.
    if (incr == -1 || boxDependent == -1 || boxIndependent == -1)
      {
        //numFrames has to be an even number as defined by spec.
        int iterations = numFrames / 2;
        if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
          {
            boxDependent = vr.width / 6.;
            incr = ((double) (vr.width - boxDependent)) / (double) iterations;
            boxIndependent = vr.height;
          }
        else
          {
            boxDependent = vr.height / 6.;
            incr = ((double) (vr.height - boxDependent)) / (double) iterations;
            boxIndependent = vr.width;
          }
      }

    int index = getAnimationIndex();
    if (animationIndex > numFrames / 2)
      index = numFrames - getAnimationIndex();

    if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
      {
        r.x = vr.x + (int) (incr * index);
        r.y = vr.y;
        r.width = (int) boxDependent;
        r.height = (int) boxIndependent;
      }
    else
      {
        r.x = vr.x;
        r.y = vr.height - (int) (incr * index) + vr.y - (int) boxDependent;
        r.width = (int) boxIndependent;
        r.height = (int) boxDependent;
      }
    return r;
  }

  /**
   * This method returns the length of the cells.
   *
   * @return The cell length.
   */
  protected int getCellLength()
  {
    return cellLength;
  }

  /**
   * This method returns the spacing between cells.
   *
   * @return The cell gap.
   */
  protected int getCellSpacing()
  {
    return cellSpacing;
  }

  /**
   * This method returns the maximum size of the JComponent.
   * If it returns null, it is up to the LayoutManager
   * to give it a size.
   *
   * @param c The component to find a maximum size for.
   *
   * @return The maximum size.
   */
  public Dimension getMaximumSize(JComponent c)
  {
    Insets insets = c.getInsets();
    Dimension ret;
    int orientation = progressBar.getOrientation();
    if (orientation == JProgressBar.VERTICAL)
      {
        ret = getPreferredInnerVertical();
        ret.height = Short.MAX_VALUE;
        ret.width += insets.left + insets.right;
      }
    else
      {
        ret = getPreferredInnerHorizontal();
        ret.width = Short.MAX_VALUE;
        ret.height += insets.top + insets.bottom;
      }
    return ret;
  }

  /**
   * This method returns the minimum size of the JComponent.
   * If it returns null, it is up to the LayoutManager to
   * give it a size.
   *
   * @param c The component to find a minimum size for.
   *
   * @return The minimum size.
   */
  public Dimension getMinimumSize(JComponent c)
  {
    Insets insets = c.getInsets();
    Dimension ret;
    int orientation = progressBar.getOrientation();
    if (orientation == JProgressBar.VERTICAL)
      {
        ret = getPreferredInnerVertical();
        ret.height = 10;
        ret.width += insets.left + insets.right;
      }
    else
      {
        ret = getPreferredInnerHorizontal();
        ret.width = 10;
        ret.height += insets.top + insets.bottom;
      }
    return ret;
  }

  /**
   * This method returns the preferred size of the inner
   * rectangle (the bounds without the insets) if the
   * progressBar is horizontal.
   *
   * @return The preferred size of the progressBar minus 
   *         insets if it's horizontal.
   */
  protected Dimension getPreferredInnerHorizontal()
  {
    Font font = progressBar.getFont();
    FontMetrics fm = progressBar.getFontMetrics(font);

    int stringWidth = 0;
    String str = progressBar.getString();
    if (str != null)
      stringWidth = fm.stringWidth(progressBar.getString());
    Insets i = progressBar.getInsets();
    int prefWidth = Math.max(200 - i.left - i.right, stringWidth);

    int stringHeight = 0;
    if (str != null)
      stringHeight = fm.getHeight();
    int prefHeight = Math.max(16 - i.top - i.bottom, stringHeight);

    return new Dimension(prefWidth, prefHeight);
  }

  /**
   * This method returns the preferred size of the inner
   * rectangle (the bounds without insets) if the 
   * progressBar is vertical.
   *
   * @return The preferred size of the progressBar minus
   *         insets if it's vertical.
   */
  protected Dimension getPreferredInnerVertical()
  {
    Font font = progressBar.getFont();
    FontMetrics fm = progressBar.getFontMetrics(font);

    int stringWidth = 0;
    String str = progressBar.getString();
    if (str != null)
      stringWidth = fm.stringWidth(progressBar.getString());
    Insets i = progressBar.getInsets();
    int prefHeight = Math.max(200 - i.left - i.right, stringWidth);

    int stringHeight = 0;
    if (str != null)
      stringHeight = fm.getHeight();
    int prefWidth = Math.max(16 - i.top - i.bottom, stringHeight);

    return new Dimension(prefWidth, prefHeight);
  }

  /**
   * This method returns the preferred size of the 
   * given JComponent. If it returns null, then it
   * is up to the LayoutManager to give it a size.
   *
   * @param c The component to find the preferred size for.
   *
   * @return The preferred size of the component.
   */
  public Dimension getPreferredSize(JComponent c)
  {
    Insets insets = c.getInsets();
    Dimension ret;
    int orientation = progressBar.getOrientation();
    if (orientation == JProgressBar.VERTICAL)
      ret = getPreferredInnerVertical();
    else
      ret = getPreferredInnerHorizontal();
    ret.width += insets.left + insets.right;
    ret.height += insets.top + insets.bottom;
    return ret;
  }

  /**
   * This method returns the Color that the text is shown in when the bar is
   * not over the text.
   *
   * @return The color of the text when the bar is not over it.
   */
  protected Color getSelectionBackground()
  {
    return selectionBackground;
  }

  /**
   * This method returns the Color that the text is shown in  when the bar is
   * over the text.
   *
   * @return The color of the text when the bar is over it.
   */
  protected Color getSelectionForeground()
  {
    return selectionForeground;
  }

  /**
   * This method returns the point (the top left of the bounding box)
   * where the text should be painted. 
   *
   * @param g The Graphics object to measure FontMetrics with.
   * @param progressString The string to paint.
   * @param x The x coordinate of the overall bounds box.
   * @param y The y coordinate of the overall bounds box.
   * @param width The width of the overall bounds box.
   * @param height The height of the overall bounds box.
   *
   * @return The top left of the bounding box where text should be painted.
   */
  protected Point getStringPlacement(Graphics g, String progressString, int x,
                                     int y, int width, int height)
  {
    Rectangle tr = new Rectangle();
    Rectangle vr = new Rectangle(x, y, width, height);
    Rectangle ir = new Rectangle();

    Font f = g.getFont();
    FontMetrics fm = g.getFontMetrics(f);

    SwingUtilities.layoutCompoundLabel(progressBar, fm, progressString, null,
                                       SwingConstants.CENTER,
                                       SwingConstants.CENTER,
                                       SwingConstants.CENTER,
                                       SwingConstants.CENTER, vr, ir, tr, 0);
    return new Point(tr.x, tr.y);
  }

  /**
   * This method increments the animation index.
   */
  protected void incrementAnimationIndex()
  {
    animationIndex++;
    //numFrames is like string length, it should be named numFrames or something
    if (animationIndex >= numFrames)
      animationIndex = 0;
    progressBar.repaint();
  }

  /**
   * This method paints the progressBar. It delegates its responsibilities
   * to paintDeterminate and paintIndeterminate.
   *
   * @param g The Graphics object to paint with.
   * @param c The JComponent to paint.
   */
  public void paint(Graphics g, JComponent c)
  {
    if (! progressBar.isIndeterminate())
      paintDeterminate(g, c);
    else
      paintIndeterminate(g, c);
  }

  /**
   * This method is called if the painting to be done is 
   * for a determinate progressBar.
   *
   * @param g The Graphics object to paint with.
   * @param c The JComponent to paint.
   */
  protected void paintDeterminate(Graphics g, JComponent c)
  {
    Color saved = g.getColor();
    int space = getCellSpacing();
    int len = getCellLength();
    int max = progressBar.getMaximum();
    int min = progressBar.getMinimum();
    int value = progressBar.getValue();

    Rectangle vr = SwingUtilities.calculateInnerArea(c, new Rectangle());
    Rectangle or = progressBar.getBounds();
    Insets insets = c.getInsets();

    int amountFull = getAmountFull(insets, or.width, or.height);

	if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
	  {
	    g.setColor(c.getForeground());
	    g.fillRect(vr.x, vr.y, amountFull, vr.height);
	  }
	else
	  {
	    g.setColor(c.getForeground());
	    g.fillRect(vr.x, vr.y + vr.height - amountFull, vr.width, 
                       amountFull);
	  }

    if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
      paintString(g, 0, 0, or.width, or.height, amountFull, insets);
    g.setColor(saved);
  }

  /**
   * This method is called if the painting to be done is for
   * an indeterminate progressBar.
   *
   * @param g The Graphics object to paint with.
   * @param c The JComponent to paint.
   */
  protected void paintIndeterminate(Graphics g, JComponent c)
  {
    //need to paint the box at it's current position. no text is painted since
    //all we're doing is bouncing back and forth
    Color saved = g.getColor();
    Insets insets = c.getInsets();

    Rectangle or = c.getBounds();
    Rectangle vr = new Rectangle();
    SwingUtilities.calculateInnerArea(c, vr);

    g.setColor(c.getBackground());
    g.fillRect(vr.x, vr.y, vr.width, vr.height);

    boxRect = getBox(boxRect);

    g.setColor(c.getForeground());
    g.fillRect(boxRect.x, boxRect.y, boxRect.width, boxRect.height);

    if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
      paintString(g, 0, 0, or.width, or.height,
                  getAmountFull(insets, or.width, or.height), insets);

    g.setColor(saved);
  }

  /**
   * This method paints the string for the progressBar.
   *
   * @param g The Graphics object to paint with.
   * @param x The x coordinate of the progressBar.
   * @param y The y coordinate of the progressBar.
   * @param width The width of the progressBar.
   * @param height The height of the progressBar.
   * @param amountFull The amount of the progressBar that has its bar filled.
   * @param b The insets of the progressBar.
   */
  protected void paintString(Graphics g, int x, int y, int width, int height,
                             int amountFull, Insets b)
  {
    String str = progressBar.getString();
    int full = getAmountFull(b, width, height);
    Point placement = getStringPlacement(g, progressBar.getString(),
                                         x + b.left, y + b.top, 
                                         width - b.left - b.right,
                                         height - b.top - b.bottom);
    Color savedColor = g.getColor();
    Shape savedClip = g.getClip();
    FontMetrics fm = g.getFontMetrics(progressBar.getFont());
    
    if (progressBar.getOrientation() == JProgressBar.VERTICAL)
      {
        AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2);
        g.setFont(progressBar.getFont().deriveFont(rotate));
      }
    
    g.setColor(getSelectionForeground());
    g.setClip(0, 0, full + b.left, height);
    g.drawString(str, placement.x, placement.y + fm.getAscent());
    g.setColor(getSelectionBackground());
    g.setClip(full + b.left, 0, width - full, height);
    g.drawString(str, placement.x, placement.y + fm.getAscent());
    g.setClip(savedClip);
    g.setColor(savedColor);
  }

  /**
   * This method sets the current animation index. If the index is greater than
   * the number of frames, it resets to 0.
   * 
   * @param newValue The new animation index.
   */
  protected void setAnimationIndex(int newValue)
  {
    animationIndex = (newValue <= numFrames) ? newValue : 0;
    progressBar.repaint();
  }

  /**
   * This method sets the cell length.
   *
   * @param cellLen The cell length.
   */
  protected void setCellLength(int cellLen)
  {
    cellLength = cellLen;
  }

  /**
   * This method sets the cell spacing.
   *
   * @param cellSpace The cell spacing.
   */
  protected void setCellSpacing(int cellSpace)
  {
    cellSpacing = cellSpace;
  }

  /**
   * This method starts the animation timer. It is called
   * when the propertyChangeListener detects that the progressBar
   * has changed to indeterminate mode.
   *
   * @since 1.4
   */
  protected void startAnimationTimer()
  {
    if (animationTimer != null)
      animationTimer.start();
  }

  /**
   * This method stops the animation timer. It is called when
   * the propertyChangeListener detects that the progressBar
   * has changed to determinate mode.
   *
   * @since 1.4
   */
  protected void stopAnimationTimer()
  {
    if (animationTimer != null)
      animationTimer.stop();
    setAnimationIndex(0);
  }

  /**
   * This method changes the settings for the progressBar to
   * the defaults provided by the current Look and Feel.
   */
  protected void installDefaults()
  {
    LookAndFeel.installColorsAndFont(progressBar, "ProgressBar.background",
                                     "ProgressBar.foreground",
                                     "ProgressBar.font");
    LookAndFeel.installBorder(progressBar, "ProgressBar.border");
    progressBar.setOpaque(true);

    selectionForeground = UIManager.getColor("ProgressBar.selectionForeground");
    selectionBackground = UIManager.getColor("ProgressBar.selectionBackground");
    cellLength = UIManager.getInt("ProgressBar.cellLength");
    cellSpacing = UIManager.getInt("ProgressBar.cellSpacing");

    int repaintInterval = UIManager.getInt("ProgressBar.repaintInterval");
    int cycleTime = UIManager.getInt("ProgressBar.cycleTime");

    if (cycleTime % repaintInterval != 0
        && (cycleTime / repaintInterval) % 2 != 0)
      {
	int div = (cycleTime / repaintInterval) + 2;
	div /= 2;
	div *= 2;
	cycleTime = div * repaintInterval;
      }
    setAnimationIndex(0);
    numFrames = cycleTime / repaintInterval;
    animationTimer.setDelay(repaintInterval);
  }

  /**
   * The method uninstalls any defaults that were
   * set by the current Look and Feel.
   */
  protected void uninstallDefaults()
  {
    progressBar.setFont(null);
    progressBar.setForeground(null);
    progressBar.setBackground(null);

    selectionForeground = null;
    selectionBackground = null;
  }

  /**
   * This method registers listeners to all the 
   * components that this UI delegate needs to listen to.
   */
  protected void installListeners()
  {
    changeListener = new ChangeHandler();
    propertyListener = new PropertyChangeHandler();
    animation = new Animator();

    progressBar.addChangeListener(changeListener);
    progressBar.addPropertyChangeListener(propertyListener);
    animationTimer.addActionListener(animation);

    ancestorListener = new AncestorHandler();
    progressBar.addAncestorListener(ancestorListener);

    componentListener = new ComponentHandler();
    progressBar.addComponentListener(componentListener);
  }

  /**
   * This method unregisters listeners to all the 
   * components that were listened to.
   */
  protected void uninstallListeners()
  {
    progressBar.removeChangeListener(changeListener);
    progressBar.removePropertyChangeListener(propertyListener);
    animationTimer.removeActionListener(animation);

    changeListener = null;
    propertyListener = null;
    animation = null;

    if (ancestorListener != null)
      progressBar.removeAncestorListener(ancestorListener);
    ancestorListener = null;

    if (componentListener != null)
      progressBar.removeComponentListener(componentListener);
    componentListener = null;
  }

  /**
   * This method installs the UI for the given JComponent.
   * This includes setting up defaults and listeners as
   * well as initializing any values or objects that
   * the UI may need.
   *
   * @param c The JComponent that is having this UI installed.
   */
  public void installUI(JComponent c)
  {
    super.installUI(c);
    if (c instanceof JProgressBar)
      {
	progressBar = (JProgressBar) c;

	animationTimer = new Timer(200, null);
	animationTimer.setRepeats(true);

	installDefaults();
	installListeners();
      }
    if (progressBar.isIndeterminate())
      startAnimationTimer();
  }

  /**
   * This method removes the UI for the given JComponent.
   * This includes removing any listeners or defaults
   * that the installUI may have set up.
   *
   * @param c The JComponent that is having this UI uninstalled.
   */
  public void uninstallUI(JComponent c)
  {
    super.uninstallUI(c);
    uninstallListeners();
    uninstallDefaults();

    animationTimer = null;
    progressBar = null;
  }

}
