/*
 * Copyright 2002-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package com.sun.java.swing.plaf.gtk;

import javax.swing.*;
import javax.swing.plaf.synth.*;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

/**
 * @author Joshua Outwater
 */
class GTKGraphicsUtils extends SynthGraphicsUtils {
    public void paintText(SynthContext context, Graphics g, String text,
                          int x, int y, int mnemonicIndex) {
        if (text == null || text.length() <= 0) {
            // We don't need to paint empty strings
            return;
        }

        if (context.getRegion() == Region.INTERNAL_FRAME_TITLE_PANE) {
            // Metacity handles painting of text on internal frame title,
            // ignore this.
            return;
        }
        int componentState = context.getComponentState();
        if ((componentState & SynthConstants.DISABLED) ==
                              SynthConstants.DISABLED){
            Color orgColor = g.getColor();
            g.setColor(context.getStyle().getColor(context,
                                                   GTKColorType.WHITE));
            x += 1;
            y += 1;
            super.paintText(context, g, text, x, y, mnemonicIndex);

            g.setColor(orgColor);
            x -= 1;
            y -= 1;
            super.paintText(context, g, text, x, y, mnemonicIndex);
        }
        else {
            String themeName = GTKLookAndFeel.getGtkThemeName();
            if (themeName != null && themeName.startsWith("blueprint") &&
                shouldShadowText(context.getRegion(), componentState)) {

                g.setColor(Color.BLACK);
                super.paintText(context, g, text, x+1, y+1, mnemonicIndex);
                g.setColor(Color.WHITE);
            }

            super.paintText(context, g, text, x, y, mnemonicIndex);
        }
    }

    /**
     * Paints text at the specified location. This will not attempt to
     * render the text as html nor will it offset by the insets of the
     * component.
     *
     * @param ss SynthContext
     * @param g Graphics used to render string in.
     * @param text Text to render
     * @param bounds Bounds of the text to be drawn.
     * @param mnemonicIndex Index to draw string at.
     */
    public void paintText(SynthContext context, Graphics g, String text,
                          Rectangle bounds, int mnemonicIndex) {
        if (text == null || text.length() <= 0) {
            // We don't need to paint empty strings
            return;
        }

        Region id = context.getRegion();
        if ((id == Region.RADIO_BUTTON ||
             id == Region.CHECK_BOX ||
             id == Region.TABBED_PANE_TAB) &&
            (context.getComponentState() & SynthConstants.FOCUSED) != 0)
        {
            JComponent source = context.getComponent();
            if (!(source instanceof AbstractButton) ||
                ((AbstractButton)source).isFocusPainted()) {

                // The "bounds" parameter encompasses only the actual text;
                // when drawing the focus, we need to expand that bounding
                // box by "focus-line-width" plus "focus-padding".  Note that
                // the layout process for these components will have already
                // taken these values into account, so there should always
                // be enough space allocated for drawing the focus indicator.
                int synthState = context.getComponentState();
                GTKStyle style = (GTKStyle)context.getStyle();
                int focusSize =
                    style.getClassSpecificIntValue(context,
                                                   "focus-line-width", 1);
                int focusPad =
                    style.getClassSpecificIntValue(context,
                                                   "focus-padding", 1);
                int totalFocus = focusSize + focusPad;
                int x = bounds.x - totalFocus;
                int y = bounds.y - totalFocus;
                int w = bounds.width  + (2 * totalFocus);
                int h = bounds.height + (2 * totalFocus);

                Color color = g.getColor();
                GTKPainter.INSTANCE.paintFocus(context, g, id,
                                               synthState, "checkbutton",
                                               x, y, w, h);
                g.setColor(color);
            }
        }
        super.paintText(context, g, text, bounds, mnemonicIndex);
    }

    private static boolean shouldShadowText(Region id, int state) {
        int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
        return((gtkState == SynthConstants.MOUSE_OVER) &&
               (id == Region.MENU ||
                id == Region.MENU_ITEM ||
                id == Region.CHECK_BOX_MENU_ITEM ||
                id == Region.RADIO_BUTTON_MENU_ITEM));
    }
}
