/*
 * @(#)PDFLabelUI.java  1.6  2007-11-18
 *
 * Copyright (c) 2005-2007 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */
package ch.randelshofer.pdf.plaf;

import ch.randelshofer.pdf.plaf.util.*;
import ch.randelshofer.gui.border.BackgroundBorder;
import ch.randelshofer.pdf.plaf.color.PaintableColor;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import javax.swing.text.*;

/**
 * PDFLabelUI.
 *
 * @author  Werner Randelshofer
 * @version 1.6 2007-11-18 Added support for property "Quaqua.Label.style"=
 * "emboss" and "shadow".
 * <br>1.5.1 2007-01-15 Perceiced bounds.height must reflect font size
 * even if the label is empty.
 * <br>1.5 2006-02-18 Tweaked perceived text bounds. Draw disabled label
 * with disabled text color. Draw background again if we are opaque.
 * <br>1.4 2005-12-08 Support for background border added.
 * <br>1.3 2005-07-17 Adapted to changes in interface VisuallyLayoutable.
 * <br>1.2 2006-06-20 Paint text antialiased.
 * <br>1.0  02 April 2005  Created.
 */
public class PDFLabelUI extends BasicLabelUI {

    protected static PDFLabelUI labelUI = new PDFLabelUI();
    /* These rectangles/insets are allocated once for this shared LabelUI
     * implementation.  Re-using rectangles rather than allocating
     * them in each getPreferredSize call sped up the method substantially.
     */
    private static Rectangle iconR = new Rectangle();
    private static Rectangle textR = new Rectangle();
    private static Rectangle viewR = new Rectangle();
    private static Insets viewInsets = new Insets(0, 0, 0, 0);

    /**
     * Preferred spacing between labels and other components.
     * Pixels from colon and associated controls (RadioButton,
     * CheckBox)
     * /
     * private final static Insets associatedRegularSpacing = new Insets(8,8,8,8);
     * private final static Insets associatedSmallSpacing = new Insets(6,6,6,6);
     * private final static Insets associatedMiniSpacing = new Insets(5,5,5,5);
     */
    public static ComponentUI createUI(JComponent c) {
        return labelUI;
    }

    @Override
    protected void installDefaults(JLabel b) {
        super.installDefaults(b);

        // load shared instance defaults
         PDFLookAndFeel.installColorsAndFont(b, "Label.background", "Label.foreground", "Label.font");
        PDFLookAndFeel.installBorder(b, "Label.border");

        // FIXME - Very, very dirty trick to achieve small labels on sliders
        //         This hack should be removed, when we implement a SliderUI
        //         on our own.
        if (b.getClass().getName().endsWith("LabelUIResource")) {
            b.setFont(UIManager.getFont("Slider.labelFont"));
        }
    }

    public void paint(Graphics gr, JComponent c) {
        Graphics2D g = (Graphics2D) gr;
        Object oldHints = PDFUtilities.beginGraphics(g);

        // Paint background again so that the texture paint is drawn
        if (c.isOpaque()) {
            g.setPaint(PaintableColor.getPaint(c.getBackground(), c));
            g.fillRect(0, 0, c.getWidth(), c.getHeight());
        }

        // Paint background border
        Border b = c.getBorder();
        if (b != null && b instanceof BackgroundBorder) {
            ((BackgroundBorder) b).getBackgroundBorder().paintBorder(c, g, 0, 0, c.getWidth(), c.getHeight());
        }

        super.paint(g, c);
        PDFUtilities.endGraphics(g, oldHints);
    }

    /**
     * Paint label with disabled text color.
     *
     * @see #paint
     * @see #paintEnabledText
     */
    protected void paintDisabledText(JLabel l, Graphics g, String s, int textX, int textY) {
        Color c = UIManager.getColor("Label.disabledForeground");
        g.setColor((c != null) ? c : l.getForeground());
        // Make sure we render with the font of the JLabel
        g.setFont(l.getFont());

        int accChar = -1; //l.getDisplayedMnemonicIndex();

        PDFUtilities.drawString(g, s, accChar,
                textX, textY);
    }

    protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) {
        int mnemIndex = l.getDisplayedMnemonicIndex();

        // Make sure we render with the font of the JLabel
        g.setFont(l.getFont());
        
        String style = (String) l.getClientProperty("Quaqua.Label.style");
        if (style != null) {
            if (style.equals("emboss") &&
                    UIManager.getColor("Label.embossForeground") != null) {
                g.setColor(UIManager.getColor("Label.embossForeground"));
                PDFUtilities.drawString(g, s, mnemIndex, textX, textY + 1);

            } else if (style.equals("shadow") &&
                    UIManager.getColor("Label.shadowForeground") != null) {
                g.setColor(UIManager.getColor("Label.shadowForeground"));
                PDFUtilities.drawString(g, s, mnemIndex, textX, textY + 1);
            }
        }
        g.setColor(l.getForeground());
        PDFUtilities.drawString(g, s, mnemIndex, textX, textY);
    //SwingUtilities2.drawStringUnderlineCharAt(l, g, s, mnemIndex,
    //                                             textX, textY);
    }

    /**
     * Forwards the call to SwingUtilities.layoutCompoundLabel().
     * This method is here so that a subclass could do Label specific
     * layout and to shorten the method name a little.
     *
     * @see SwingUtilities#layoutCompoundLabel
     */
    protected String layoutCL(
            JLabel label,
            FontMetrics fontMetrics,
            String text,
            Icon icon,
            Rectangle viewR,
            Rectangle iconR,
            Rectangle textR) {
        return SwingUtilities.layoutCompoundLabel(
                (JComponent) label,
                fontMetrics,
                text,
                icon,
                label.getVerticalAlignment(),
                label.getHorizontalAlignment(),
                label.getVerticalTextPosition(),
                label.getHorizontalTextPosition(),
                viewR,
                iconR,
                textR,
                label.getIconTextGap());
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        String name = evt.getPropertyName();

        if (name.equals("JComponent.sizeVariant")) {
//            PDFUtilities.applySizeVariant((JLabel) evt.getSource());
        } else {
            super.propertyChange(evt);
        }
    }
}
