/*
 * Copyright (c) 2008, 2009, 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.sun.awt;

import java.awt.*;

import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;

/**
 * A collection of utility methods for AWT.
 *
 * The functionality provided by the static methods of the class includes:
 * <ul>
 * <li>Setting shapes on top-level windows
 * <li>Setting a constant alpha value for each pixel of a top-level window
 * <li>Making a window non-opaque, after that it paints only explicitly
 * painted pixels on the screen, with arbitrary alpha values for every pixel.
 * <li>Setting a 'mixing-cutout' shape for a component.
 * </ul>
 * <p>
 * A "top-level window" is an instance of the {@code Window} class (or its
 * descendant, such as {@code JFrame}).
 * <p>
 * Some of the mentioned features may not be supported by the native platform.
 * To determine whether a particular feature is supported, the user must use
 * the {@code isTranslucencySupported()} method of the class passing a desired
 * translucency kind (a member of the {@code Translucency} enum) as an
 * argument.
 * <p>
 * The per-pixel alpha feature also requires the user to create her/his
 * windows using a translucency-capable graphics configuration.
 * The {@code isTranslucencyCapable()} method must
 * be used to verify whether any given GraphicsConfiguration supports
 * the trasnlcency effects.
 * <p>
 * <b>WARNING</b>: This class is an implementation detail and only meant
 * for limited use outside of the core platform. This API may change
 * drastically between update release, and it may even be
 * removed or be moved in some other package(s)/class(es).
 */
public final class AWTUtilities {

    /**
     * The AWTUtilities class should not be instantiated
     */
    private AWTUtilities() {
    }

    /** Kinds of translucency supported by the underlying system.
     *  @see #isTranslucencySupported
     */
    public static enum Translucency {
        /**
         * Represents support in the underlying system for windows each pixel
         * of which is guaranteed to be either completely opaque, with
         * an alpha value of 1.0, or completely transparent, with an alpha
         * value of 0.0.
         */
        PERPIXEL_TRANSPARENT,

        /**
         * Represents support in the underlying system for windows all of
         * the pixels of which have the same alpha value between or including
         * 0.0 and 1.0.
         */
        TRANSLUCENT,

        /**
         * Represents support in the underlying system for windows that
         * contain or might contain pixels with arbitrary alpha values
         * between and including 0.0 and 1.0.
         */
        PERPIXEL_TRANSLUCENT;
    }


    /**
     * Returns whether the given level of translucency is supported by
     * the underlying system.
     *
     * Note that this method may sometimes return the value
     * indicating that the particular level is supported, but
     * the native windowing system may still not support the
     * given level of translucency (due to the bugs in
     * the windowing system).
     *
     * @param translucencyKind a kind of translucency support
     *                         (either PERPIXEL_TRANSPARENT,
     *                         TRANSLUCENT, or PERPIXEL_TRANSLUCENT)
     * @return whether the given translucency kind is supported
     */
    public static boolean isTranslucencySupported(Translucency translucencyKind) {
        switch (translucencyKind) {
            case PERPIXEL_TRANSPARENT:
                return isWindowShapingSupported();
            case TRANSLUCENT:
                return isWindowOpacitySupported();
            case PERPIXEL_TRANSLUCENT:
                return isWindowTranslucencySupported();
        }
        return false;
    }


    /**
     * Returns whether the windowing system supports changing the opacity
     * value of top-level windows.
     * Note that this method may sometimes return true, but the native
     * windowing system may still not support the concept of
     * translucency (due to the bugs in the windowing system).
     */
    private static boolean isWindowOpacitySupported() {
        Toolkit curToolkit = Toolkit.getDefaultToolkit();
        if (!(curToolkit instanceof SunToolkit)) {
            return false;
        }
        return ((SunToolkit)curToolkit).isWindowOpacitySupported();
    }

    /**
     * Set the opacity of the window. The opacity is at the range [0..1].
     * Note that setting the opacity level of 0 may or may not disable
     * the mouse event handling on this window. This is
     * a platform-dependent behavior.
     *
     * In order for this method to enable the translucency effect,
     * the isTranslucencySupported() method should indicate that the
     * TRANSLUCENT level of translucency is supported.
     *
     * <p>Also note that the window must not be in the full-screen mode
     * when setting the opacity value &lt; 1.0f. Otherwise
     * the IllegalArgumentException is thrown.
     *
     * @param window the window to set the opacity level to
     * @param opacity the opacity level to set to the window
     * @throws NullPointerException if the window argument is null
     * @throws IllegalArgumentException if the opacity is out of
     *                                  the range [0..1]
     * @throws IllegalArgumentException if the window is in full screen mode,
     *                                  and the opacity is less than 1.0f
     * @throws UnsupportedOperationException if the TRANSLUCENT translucency
     *                                       kind is not supported
     */
    public static void setWindowOpacity(Window window, float opacity) {
        if (window == null) {
            throw new NullPointerException(
                    "The window argument should not be null.");
        }

        AWTAccessor.getWindowAccessor().setOpacity(window, opacity);
    }

    /**
     * Get the opacity of the window. If the opacity has not
     * yet being set, this method returns 1.0.
     *
     * @param window the window to get the opacity level from
     * @throws NullPointerException if the window argument is null
     */
    public static float getWindowOpacity(Window window) {
        if (window == null) {
            throw new NullPointerException(
                    "The window argument should not be null.");
        }

        return AWTAccessor.getWindowAccessor().getOpacity(window);
    }

    /**
     * Returns whether the windowing system supports changing the shape
     * of top-level windows.
     * Note that this method may sometimes return true, but the native
     * windowing system may still not support the concept of
     * shaping (due to the bugs in the windowing system).
     */
    public static boolean isWindowShapingSupported() {
        Toolkit curToolkit = Toolkit.getDefaultToolkit();
        if (!(curToolkit instanceof SunToolkit)) {
            return false;
        }
        return ((SunToolkit)curToolkit).isWindowShapingSupported();
    }

    /**
     * Returns an object that implements the Shape interface and represents
     * the shape previously set with the call to the setWindowShape() method.
     * If no shape has been set yet, or the shape has been reset to null,
     * this method returns null.
     *
     * @param window the window to get the shape from
     * @return the current shape of the window
     * @throws NullPointerException if the window argument is null
     */
    public static Shape getWindowShape(Window window) {
        if (window == null) {
            throw new NullPointerException(
                    "The window argument should not be null.");
        }
        return AWTAccessor.getWindowAccessor().getShape(window);
    }

    /**
     * Sets a shape for the given window.
     * If the shape argument is null, this methods restores
     * the default shape making the window rectangular.
     * <p>Note that in order to set a shape, the window must be undecorated.
     * If the window is decorated, this method ignores the {@code shape}
     * argument and resets the shape to null.
     * <p>Also note that the window must not be in the full-screen mode
     * when setting a non-null shape. Otherwise the IllegalArgumentException
     * is thrown.
     * <p>Depending on the platform, the method may return without
     * effecting the shape of the window if the window has a non-null warning
     * string ({@link Window#getWarningString()}). In this case the passed
     * shape object is ignored.
     *
     * @param window the window to set the shape to
     * @param shape the shape to set to the window
     * @throws NullPointerException if the window argument is null
     * @throws IllegalArgumentException if the window is in full screen mode,
     *                                  and the shape is not null
     * @throws UnsupportedOperationException if the PERPIXEL_TRANSPARENT
     *                                       translucency kind is not supported
     */
    public static void setWindowShape(Window window, Shape shape) {
        if (window == null) {
            throw new NullPointerException(
                    "The window argument should not be null.");
        }
        AWTAccessor.getWindowAccessor().setShape(window, shape);
    }

    private static boolean isWindowTranslucencySupported() {
        /*
         * Per-pixel alpha is supported if all the conditions are TRUE:
         *    1. The toolkit is a sort of SunToolkit
         *    2. The toolkit supports translucency in general
         *        (isWindowTranslucencySupported())
         *    3. There's at least one translucency-capable
         *        GraphicsConfiguration
         */

        Toolkit curToolkit = Toolkit.getDefaultToolkit();
        if (!(curToolkit instanceof SunToolkit)) {
            return false;
        }

        if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) {
            return false;
        }

        GraphicsEnvironment env =
            GraphicsEnvironment.getLocalGraphicsEnvironment();

        // If the default GC supports translucency return true.
        // It is important to optimize the verification this way,
        // see CR 6661196 for more details.
        if (isTranslucencyCapable(env.getDefaultScreenDevice()
                    .getDefaultConfiguration()))
        {
            return true;
        }

        // ... otherwise iterate through all the GCs.
        GraphicsDevice[] devices = env.getScreenDevices();

        for (int i = 0; i < devices.length; i++) {
            GraphicsConfiguration[] configs = devices[i].getConfigurations();
            for (int j = 0; j < configs.length; j++) {
                if (isTranslucencyCapable(configs[j])) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Enables the per-pixel alpha support for the given window.
     * Once the window becomes non-opaque (the isOpaque is set to false),
     * the drawing sub-system is starting to respect the alpha value of each
     * separate pixel. If a pixel gets painted with alpha color component
     * equal to zero, it becomes visually transparent, if the alpha of the
     * pixel is equal to 255, the pixel is fully opaque. Interim values
     * of the alpha color component make the pixel semi-transparent (i.e.
     * translucent).
     * <p>Note that in order for the window to support the per-pixel alpha
     * mode, the window must be created using the GraphicsConfiguration
     * for which the {@link #isTranslucencyCapable}
     * method returns true.
     * <p>Also note that some native systems enable the per-pixel translucency
     * mode for any window created using the translucency-compatible
     * graphics configuration. However, it is highly recommended to always
     * invoke the setWindowOpaque() method for these windows, at least for
     * the sake of cross-platform compatibility reasons.
     * <p>Also note that the window must not be in the full-screen mode
     * when making it non-opaque. Otherwise the IllegalArgumentException
     * is thrown.
     * <p>If the window is a {@code Frame} or a {@code Dialog}, the window must
     * be undecorated prior to enabling the per-pixel translucency effect (see
     * {@link Frame#setUndecorated()} and/or {@link Dialog#setUndecorated()}).
     * If the window becomes decorated through a subsequent call to the
     * corresponding {@code setUndecorated()} method, the per-pixel
     * translucency effect will be disabled and the opaque property reset to
     * {@code true}.
     * <p>Depending on the platform, the method may return without
     * effecting the opaque property of the window if the window has a non-null
     * warning string ({@link Window#getWarningString()}). In this case
     * the passed 'isOpaque' value is ignored.
     *
     * @param window the window to set the shape to
     * @param isOpaque whether the window must be opaque (true),
     *                 or translucent (false)
     * @throws NullPointerException if the window argument is null
     * @throws IllegalArgumentException if the window uses
     *                                  a GraphicsConfiguration for which the
     *                                  {@code isTranslucencyCapable()}
     *                                  method returns false
     * @throws IllegalArgumentException if the window is in full screen mode,
     *                                  and the isOpaque is false
     * @throws IllegalArgumentException if the window is decorated and the
     * isOpaque argument is {@code false}.
     * @throws UnsupportedOperationException if the PERPIXEL_TRANSLUCENT
     *                                       translucency kind is not supported
     */
    public static void setWindowOpaque(Window window, boolean isOpaque) {
        if (window == null) {
            throw new NullPointerException(
                    "The window argument should not be null.");
        }
        if (!isOpaque && !isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) {
            throw new UnsupportedOperationException(
                    "The PERPIXEL_TRANSLUCENT translucency kind is not supported");
        }
        AWTAccessor.getWindowAccessor().setOpaque(window, isOpaque);
    }

    /**
     * Returns whether the window is opaque or translucent.
     *
     * @param window the window to set the shape to
     * @return whether the window is currently opaque (true)
     *         or translucent (false)
     * @throws NullPointerException if the window argument is null
     */
    public static boolean isWindowOpaque(Window window) {
        if (window == null) {
            throw new NullPointerException(
                    "The window argument should not be null.");
        }

        return window.isOpaque();
    }

    /**
     * Verifies whether a given GraphicsConfiguration supports
     * the PERPIXEL_TRANSLUCENT kind of translucency.
     * All windows that are intended to be used with the {@link #setWindowOpaque}
     * method must be created using a GraphicsConfiguration for which this method
     * returns true.
     * <p>Note that some native systems enable the per-pixel translucency
     * mode for any window created using a translucency-capable
     * graphics configuration. However, it is highly recommended to always
     * invoke the setWindowOpaque() method for these windows, at least
     * for the sake of cross-platform compatibility reasons.
     *
     * @param gc GraphicsConfiguration
     * @throws NullPointerException if the gc argument is null
     * @return whether the given GraphicsConfiguration supports
     *         the translucency effects.
     */
    public static boolean isTranslucencyCapable(GraphicsConfiguration gc) {
        if (gc == null) {
            throw new NullPointerException("The gc argument should not be null");
        }
        /*
        return gc.isTranslucencyCapable();
        */
        Toolkit curToolkit = Toolkit.getDefaultToolkit();
        if (!(curToolkit instanceof SunToolkit)) {
            return false;
        }
        return ((SunToolkit)curToolkit).isTranslucencyCapable(gc);
    }

    /**
     * Sets a 'mixing-cutout' shape for the given component.
     *
     * By default a lightweight component is treated as an opaque rectangle for
     * the purposes of the Heavyweight/Lightweight Components Mixing feature.
     * This method enables developers to set an arbitrary shape to be cut out
     * from heavyweight components positioned underneath the lightweight
     * component in the z-order.
     * <p>
     * The {@code shape} argument may have the following values:
     * <ul>
     * <li>{@code null} - reverts the default cutout shape (the rectangle equal
     * to the component's {@code getBounds()})
     * <li><i>empty-shape</i> - does not cut out anything from heavyweight
     * components. This makes the given lightweight component effectively
     * transparent. Note that descendants of the lightweight component still
     * affect the shapes of heavyweight components.  An example of an
     * <i>empty-shape</i> is {@code new Rectangle()}.
     * <li><i>non-empty-shape</i> - the given shape will be cut out from
     * heavyweight components.
     * </ul>
     * <p>
     * The most common example when the 'mixing-cutout' shape is needed is a
     * glass pane component. The {@link JRootPane#setGlassPane()} method
     * automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape
     * for the given glass pane component.  If a developer needs some other
     * 'mixing-cutout' shape for the glass pane (which is rare), this must be
     * changed manually after installing the glass pane to the root pane.
     * <p>
     * Note that the 'mixing-cutout' shape neither affects painting, nor the
     * mouse events handling for the given component. It is used exclusively
     * for the purposes of the Heavyweight/Lightweight Components Mixing
     * feature.
     *
     * @param component the component that needs non-default
     * 'mixing-cutout' shape
     * @param shape the new 'mixing-cutout' shape
     * @throws NullPointerException if the component argument is {@code null}
     */
    public static void setComponentMixingCutoutShape(Component component,
            Shape shape)
    {
        if (component == null) {
            throw new NullPointerException(
                    "The component argument should not be null.");
        }

        AWTAccessor.getComponentAccessor().setMixingCutoutShape(component,
                shape);
    }
}

