/*
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.apple.laf;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.beans.*;

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

import sun.swing.SwingUtilities2;

import apple.laf.JRSUIStateFactory;
import apple.laf.JRSUIConstants.*;
import apple.laf.JRSUIState.ValueState;

import com.apple.laf.AquaUtilControlSize.*;
import com.apple.laf.AquaUtils.RecyclableSingleton;

public class AquaProgressBarUI extends ProgressBarUI implements ChangeListener, PropertyChangeListener, AncestorListener, Sizeable {
    private static final boolean ADJUSTTIMER = true;

    protected static final RecyclableSingleton<SizeDescriptor> sizeDescriptor = new RecyclableSingleton<SizeDescriptor>() {
        @Override
        protected SizeDescriptor getInstance() {
            return new SizeDescriptor(new SizeVariant(146, 20)) {
                public SizeVariant deriveSmall(final SizeVariant v) { v.alterMinSize(0, -6); return super.deriveSmall(v); }
            };
        }
    };
    static SizeDescriptor getSizeDescriptor() {
        return sizeDescriptor.get();
    }

    protected Size sizeVariant = Size.REGULAR;

    protected Color selectionForeground;

    private Animator animator;
    protected boolean isAnimating;
    protected boolean isCircular;

    protected final AquaPainter<ValueState> painter = AquaPainter.create(JRSUIStateFactory.getProgressBar());

    protected JProgressBar progressBar;

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

    protected AquaProgressBarUI() { }

    public void installUI(final JComponent c) {
        progressBar = (JProgressBar)c;
        installDefaults();
        installListeners();
    }

    public void uninstallUI(final JComponent c) {
        uninstallDefaults();
        uninstallListeners();
        stopAnimationTimer();
        progressBar = null;
    }

    protected void installDefaults() {
        progressBar.setOpaque(false);
        LookAndFeel.installBorder(progressBar, "ProgressBar.border");
        LookAndFeel.installColorsAndFont(progressBar, "ProgressBar.background", "ProgressBar.foreground", "ProgressBar.font");
        selectionForeground = UIManager.getColor("ProgressBar.selectionForeground");
    }

    protected void uninstallDefaults() {
        LookAndFeel.uninstallBorder(progressBar);
    }

    protected void installListeners() {
        progressBar.addChangeListener(this); // Listen for changes in the progress bar's data
        progressBar.addPropertyChangeListener(this); // Listen for changes between determinate and indeterminate state
        progressBar.addAncestorListener(this);
        AquaUtilControlSize.addSizePropertyListener(progressBar);
    }

    protected void uninstallListeners() {
        AquaUtilControlSize.removeSizePropertyListener(progressBar);
        progressBar.removeAncestorListener(this);
        progressBar.removePropertyChangeListener(this);
        progressBar.removeChangeListener(this);
    }

    public void stateChanged(final ChangeEvent e) {
        progressBar.repaint();
    }

    public void propertyChange(final PropertyChangeEvent e) {
        final String prop = e.getPropertyName();
        if ("indeterminate".equals(prop)) {
            if (!progressBar.isIndeterminate()) return;
            stopAnimationTimer();
            // start the animation thread
            if (progressBar.isDisplayable()) {
              startAnimationTimer();
            }
        }

        if ("JProgressBar.style".equals(prop)) {
            isCircular = "circular".equalsIgnoreCase(e.getNewValue() + "");
            progressBar.repaint();
        }
    }

    // listen for Ancestor events to stop our timer when we are no longer visible
    // <rdar://problem/5405035> JProgressBar: UI in Aqua look and feel causes memory leaks
    public void ancestorRemoved(final AncestorEvent e) {
        stopAnimationTimer();
    }

    public void ancestorAdded(final AncestorEvent e) {
        if (!progressBar.isIndeterminate()) return;
        if (progressBar.isDisplayable()) {
          startAnimationTimer();
        }
    }

    public void ancestorMoved(final AncestorEvent e) { }

    public void paint(final Graphics g, final JComponent c) {
        revalidateAnimationTimers(); // revalidate to turn on/off timers when values change

        painter.state.set(getState(c));
        painter.state.set(isHorizontal() ? Orientation.HORIZONTAL : Orientation.VERTICAL);
        painter.state.set(isAnimating ? Animating.YES : Animating.NO);

        if (progressBar.isIndeterminate()) {
            if (isCircular) {
                painter.state.set(Widget.PROGRESS_SPINNER);
                painter.paint(g, c, 2, 2, 16, 16);
                return;
            }

            painter.state.set(Widget.PROGRESS_INDETERMINATE_BAR);
            paint(g);
            return;
        }

        painter.state.set(Widget.PROGRESS_BAR);
        painter.state.setValue(checkValue(progressBar.getPercentComplete()));
        paint(g);
    }

    static double checkValue(final double value) {
        return Double.isNaN(value) ? 0 : value;
    }

    protected void paint(final Graphics g) {
        // this is questionable. We may want the insets to mean something different.
        final Insets i = progressBar.getInsets();
        final int width = progressBar.getWidth() - (i.right + i.left);
        final int height = progressBar.getHeight() - (i.bottom + i.top);

        painter.paint(g, progressBar, i.left, i.top, width, height);

        if (progressBar.isStringPainted() && !progressBar.isIndeterminate()) {
            paintString(g, i.left, i.top, width, height);
        }
    }

    protected State getState(final JComponent c) {
        if (!c.isEnabled()) return State.INACTIVE;
        if (!AquaFocusHandler.isActive(c)) return State.INACTIVE;
        return State.ACTIVE;
    }

    protected void paintString(final Graphics g, final int x, final int y, final int width, final int height) {
        if (!(g instanceof Graphics2D)) return;

        final Graphics2D g2 = (Graphics2D)g;
        final String progressString = progressBar.getString();
        g2.setFont(progressBar.getFont());
        final Point renderLocation = getStringPlacement(g2, progressString, x, y, width, height);
        final Rectangle oldClip = g2.getClipBounds();

        if (isHorizontal()) {
            g2.setColor(selectionForeground);
            SwingUtilities2.drawString(progressBar, g2, progressString, renderLocation.x, renderLocation.y);
        } else { // VERTICAL
            // We rotate it -90 degrees, then translate it down since we are going to be bottom up.
            final AffineTransform savedAT = g2.getTransform();
            g2.transform(AffineTransform.getRotateInstance(0.0f - (Math.PI / 2.0f), 0, 0));
            g2.translate(-progressBar.getHeight(), 0);

            // 0,0 is now the bottom left of the viewable area, so we just draw our image at
            // the render location since that calculation knows about rotation.
            g2.setColor(selectionForeground);
            SwingUtilities2.drawString(progressBar, g2, progressString, renderLocation.x, renderLocation.y);

            g2.setTransform(savedAT);
        }

        g2.setClip(oldClip);
    }

    /**
     * Designate the place where the progress string will be painted. This implementation places it at the center of the
     * progress bar (in both x and y). Override this if you want to right, left, top, or bottom align the progress
     * string or if you need to nudge it around for any reason.
     */
    protected Point getStringPlacement(final Graphics g, final String progressString, int x, int y, int width, int height) {
        final FontMetrics fontSizer = progressBar.getFontMetrics(progressBar.getFont());
        final int stringWidth = fontSizer.stringWidth(progressString);

        if (!isHorizontal()) {
            // Calculate the location for the rotated text in real component coordinates.
            // swapping x & y and width & height
            final int oldH = height;
            height = width;
            width = oldH;

            final int oldX = x;
            x = y;
            y = oldX;
        }

        return new Point(x + Math.round(width / 2 - stringWidth / 2), y + ((height + fontSizer.getAscent() - fontSizer.getLeading() - fontSizer.getDescent()) / 2) - 1);
    }

    static Dimension getCircularPreferredSize() {
        return new Dimension(20, 20);
    }

    public Dimension getPreferredSize(final JComponent c) {
        if (isCircular) {
            return getCircularPreferredSize();
        }

        final FontMetrics metrics = progressBar.getFontMetrics(progressBar.getFont());

        final Dimension size = isHorizontal() ? getPreferredHorizontalSize(metrics) : getPreferredVerticalSize(metrics);
        final Insets insets = progressBar.getInsets();

        size.width += insets.left + insets.right;
        size.height += insets.top + insets.bottom;
        return size;
    }

    protected Dimension getPreferredHorizontalSize(final FontMetrics metrics) {
        final SizeVariant variant = getSizeDescriptor().get(sizeVariant);
        final Dimension size = new Dimension(variant.w, variant.h);
        if (!progressBar.isStringPainted()) return size;

        // Ensure that the progress string will fit
        final String progString = progressBar.getString();
        final int stringWidth = metrics.stringWidth(progString);
        if (stringWidth > size.width) {
            size.width = stringWidth;
        }

        // This uses both Height and Descent to be sure that
        // there is more than enough room in the progress bar
        // for everything.
        // This does have a strange dependency on
        // getStringPlacememnt() in a funny way.
        final int stringHeight = metrics.getHeight() + metrics.getDescent();
        if (stringHeight > size.height) {
            size.height = stringHeight;
        }
        return size;
    }

    protected Dimension getPreferredVerticalSize(final FontMetrics metrics) {
        final SizeVariant variant = getSizeDescriptor().get(sizeVariant);
        final Dimension size = new Dimension(variant.h, variant.w);
        if (!progressBar.isStringPainted()) return size;

        // Ensure that the progress string will fit.
        final String progString = progressBar.getString();
        final int stringHeight = metrics.getHeight() + metrics.getDescent();
        if (stringHeight > size.width) {
            size.width = stringHeight;
        }

        // This is also for completeness.
        final int stringWidth = metrics.stringWidth(progString);
        if (stringWidth > size.height) {
            size.height = stringWidth;
        }
        return size;
    }

    public Dimension getMinimumSize(final JComponent c) {
        if (isCircular) {
            return getCircularPreferredSize();
        }

        final Dimension pref = getPreferredSize(progressBar);

        // The Minimum size for this component is 10.
        // The rationale here is that there should be at least one pixel per 10 percent.
        if (isHorizontal()) {
            pref.width = 10;
        } else {
            pref.height = 10;
        }

        return pref;
    }

    public Dimension getMaximumSize(final JComponent c) {
        if (isCircular) {
            return getCircularPreferredSize();
        }

        final Dimension pref = getPreferredSize(progressBar);

        if (isHorizontal()) {
            pref.width = Short.MAX_VALUE;
        } else {
            pref.height = Short.MAX_VALUE;
        }

        return pref;
    }

    public void applySizeFor(final JComponent c, final Size size) {
        painter.state.set(sizeVariant = size == Size.MINI ? Size.SMALL : sizeVariant); // CUI doesn't support mini progress bars right now
    }

    protected void startAnimationTimer() {
        if (animator == null) animator = new Animator();
        animator.start();
        isAnimating = true;
    }

    protected void stopAnimationTimer() {
        if (animator != null) animator.stop();
        isAnimating = false;
    }

    private final Rectangle fUpdateArea = new Rectangle(0, 0, 0, 0);
    private final Dimension fLastSize = new Dimension(0, 0);
    protected Rectangle getRepaintRect() {
        int height = progressBar.getHeight();
        int width = progressBar.getWidth();

        if (isCircular) {
            return new Rectangle(20, 20);
        }

        if (fLastSize.height == height && fLastSize.width == width) {
            return fUpdateArea;
        }

        int x = 0;
        int y = 0;
        fLastSize.height = height;
        fLastSize.width = width;

        final int maxHeight = getMaxProgressBarHeight();

        if (isHorizontal()) {
            final int excessHeight = height - maxHeight;
            y += excessHeight / 2;
            height = maxHeight;
        } else {
            final int excessHeight = width - maxHeight;
            x += excessHeight / 2;
            width = maxHeight;
        }

        fUpdateArea.setBounds(x, y, width, height);

        return fUpdateArea;
    }

    protected int getMaxProgressBarHeight() {
        return getSizeDescriptor().get(sizeVariant).h;
    }

    protected boolean isHorizontal() {
        return progressBar.getOrientation() == SwingConstants.HORIZONTAL;
    }

    protected void revalidateAnimationTimers() {
        if (progressBar.isIndeterminate()) return;

        if (!isAnimating) {
            startAnimationTimer(); // only starts if supposed to!
            return;
        }

        final BoundedRangeModel model = progressBar.getModel();
        final double currentValue = model.getValue();
        if ((currentValue == model.getMaximum()) || (currentValue == model.getMinimum())) {
            stopAnimationTimer();
        }
    }

    protected void repaint() {
        final Rectangle repaintRect = getRepaintRect();
        if (repaintRect == null) {
            progressBar.repaint();
            return;
        }

        progressBar.repaint(repaintRect);
    }

    protected class Animator implements ActionListener {
        private static final int MINIMUM_DELAY = 5;
        private Timer timer;
        private long previousDelay; // used to tune the repaint interval
        private long lastCall; // the last time actionPerformed was called
        private int repaintInterval;

        public Animator() {
            repaintInterval = UIManager.getInt("ProgressBar.repaintInterval");

            // Make sure repaintInterval is reasonable.
            if (repaintInterval <= 0) repaintInterval = 100;
        }

        protected void start() {
            previousDelay = repaintInterval;
            lastCall = 0;

            if (timer == null) {
                timer = new Timer(repaintInterval, this);
            } else {
                timer.setDelay(repaintInterval);
            }

            if (ADJUSTTIMER) {
                timer.setRepeats(false);
                timer.setCoalesce(false);
            }

            timer.start();
        }

        protected void stop() {
            timer.stop();
        }

        public void actionPerformed(final ActionEvent e) {
            if (!ADJUSTTIMER) {
                repaint();
                return;
            }

            final long time = System.currentTimeMillis();

            if (lastCall > 0) {
                // adjust nextDelay
                int nextDelay = (int)(previousDelay - time + lastCall + repaintInterval);
                if (nextDelay < MINIMUM_DELAY) {
                    nextDelay = MINIMUM_DELAY;
                }

                timer.setInitialDelay(nextDelay);
                previousDelay = nextDelay;
            }

            timer.start();
            lastCall = time;

            repaint();
        }
    }
}
