/*
 * Copyright (c) 2003, 2007, 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 sun.awt.image;

import java.awt.Color;
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.ImageCapabilities;
import java.awt.image.BufferedImage;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;
import sun.java2d.SurfaceData;
import sun.java2d.SurfaceDataProxy;
import sun.java2d.loops.CompositeType;

/**
 * The abstract base class that manages the various SurfaceData objects that
 * represent an Image's contents.  Subclasses can customize how the surfaces
 * are organized, whether to cache the original contents in an accelerated
 * surface, and so on.
 * <p>
 * The SurfaceManager also maintains an arbitrary "cache" mechanism which
 * allows other agents to store data in it specific to their use of this
 * image.  The most common use of the caching mechanism is for destination
 * SurfaceData objects to store cached copies of the source image.
 */
public abstract class SurfaceManager {

    public static abstract class ImageAccessor {
        public abstract SurfaceManager getSurfaceManager(Image img);
        public abstract void setSurfaceManager(Image img, SurfaceManager mgr);
    }

    private static ImageAccessor imgaccessor;

    public static void setImageAccessor(ImageAccessor ia) {
        if (imgaccessor != null) {
            throw new InternalError("Attempt to set ImageAccessor twice");
        }
        imgaccessor = ia;
    }

    /**
     * Returns the SurfaceManager object contained within the given Image.
     */
    public static SurfaceManager getManager(Image img) {
        SurfaceManager sMgr = imgaccessor.getSurfaceManager(img);
        if (sMgr == null) {
            /*
             * In practice only a BufferedImage will get here.
             */
            try {
                BufferedImage bi = (BufferedImage) img;
                sMgr = new BufImgSurfaceManager(bi);
                setManager(bi, sMgr);
            } catch (ClassCastException e) {
                throw new IllegalArgumentException("Invalid Image variant");
            }
        }
        return sMgr;
    }

    public static void setManager(Image img, SurfaceManager mgr) {
        imgaccessor.setSurfaceManager(img, mgr);
    }

    private ConcurrentHashMap cacheMap;

    /**
     * Return an arbitrary cached object for an arbitrary cache key.
     * Other objects can use this mechanism to store cached data about
     * the source image that will let them save time when using or
     * manipulating the image in the future.
     * <p>
     * Note that the cache is maintained as a simple Map with no
     * attempts to keep it up to date or invalidate it so any data
     * stored here must either not be dependent on the state of the
     * image or it must be individually tracked to see if it is
     * outdated or obsolete.
     * <p>
     * The SurfaceData object of the primary (destination) surface
     * has a StateTracker mechanism which can help track the validity
     * and "currentness" of any data stored here.
     * For convenience and expediency an object stored as cached
     * data may implement the FlushableCacheData interface specified
     * below so that it may be notified immediately if the flush()
     * method is ever called.
     */
    public Object getCacheData(Object key) {
        return (cacheMap == null) ? null : cacheMap.get(key);
    }

    /**
     * Store an arbitrary cached object for an arbitrary cache key.
     * See the getCacheData() method for notes on tracking the
     * validity of data stored using this mechanism.
     */
    public void setCacheData(Object key, Object value) {
        if (cacheMap == null) {
            synchronized (this) {
                if (cacheMap == null) {
                    cacheMap = new ConcurrentHashMap(2);
                }
            }
        }
        cacheMap.put(key, value);
    }

    /**
     * Returns the main SurfaceData object that "owns" the pixels for
     * this SurfaceManager.  This SurfaceData is used as the destination
     * surface in a rendering operation and is the most authoritative
     * storage for the current state of the pixels, though other
     * versions might be cached in other locations for efficiency.
     */
    public abstract SurfaceData getPrimarySurfaceData();

    /**
     * Restores the primary surface being managed, and then returns the
     * replacement surface.  This is called when an accelerated surface has
     * been "lost", in an attempt to auto-restore its contents.
     */
    public abstract SurfaceData restoreContents();

    /**
     * Notification that any accelerated surfaces associated with this manager
     * have been "lost", which might mean that they need to be manually
     * restored or recreated.
     *
     * The default implementation does nothing, but platform-specific
     * variants which have accelerated surfaces should perform any necessary
     * actions.
     */
    public void acceleratedSurfaceLost() {}

    /**
     * Returns an ImageCapabilities object which can be
     * inquired as to the specific capabilities of this
     * Image.  The capabilities object will return true for
     * isAccelerated() if the image has a current and valid
     * SurfaceDataProxy object cached for the specified
     * GraphicsConfiguration parameter.
     * <p>
     * This class provides a default implementation of the
     * ImageCapabilities that will try to determine if there
     * is an associated SurfaceDataProxy object and if it is
     * up to date, but only works for GraphicsConfiguration
     * objects which implement the ProxiedGraphicsConfig
     * interface defined below.  In practice, all configs
     * which can be accelerated are currently implementing
     * that interface.
     * <p>
     * A null GraphicsConfiguration returns a value based on whether the
     * image is currently accelerated on its default GraphicsConfiguration.
     *
     * @see java.awt.Image#getCapabilities
     * @since 1.5
     */
    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
        return new ImageCapabilitiesGc(gc);
    }

    class ImageCapabilitiesGc extends ImageCapabilities {
        GraphicsConfiguration gc;

        public ImageCapabilitiesGc(GraphicsConfiguration gc) {
            super(false);
            this.gc = gc;
        }

        public boolean isAccelerated() {
            // Note that when img.getAccelerationPriority() gets set to 0
            // we remove SurfaceDataProxy objects from the cache and the
            // answer will be false.
            GraphicsConfiguration tmpGc = gc;
            if (tmpGc == null) {
                tmpGc = GraphicsEnvironment.getLocalGraphicsEnvironment().
                    getDefaultScreenDevice().getDefaultConfiguration();
            }
            if (tmpGc instanceof ProxiedGraphicsConfig) {
                Object proxyKey =
                    ((ProxiedGraphicsConfig) tmpGc).getProxyKey();
                if (proxyKey != null) {
                    SurfaceDataProxy sdp =
                        (SurfaceDataProxy) getCacheData(proxyKey);
                    return (sdp != null && sdp.isAccelerated());
                }
            }
            return false;
        }
    }

    /**
     * An interface for GraphicsConfiguration objects to implement if
     * their surfaces accelerate images using SurfaceDataProxy objects.
     *
     * Implementing this interface facilitates the default
     * implementation of getImageCapabilities() above.
     */
    public static interface ProxiedGraphicsConfig {
        /**
         * Return the key that destination surfaces created on the
         * given GraphicsConfiguration use to store SurfaceDataProxy
         * objects for their cached copies.
         */
        public Object getProxyKey();
    }

    /**
     * Releases system resources in use by ancillary SurfaceData objects,
     * such as surfaces cached in accelerated memory.  Subclasses should
     * override to release any of their flushable data.
     * <p>
     * The default implementation will visit all of the value objects
     * in the cacheMap and flush them if they implement the
     * FlushableCacheData interface.
     */
    public synchronized void flush() {
        flush(false);
    }

    synchronized void flush(boolean deaccelerate) {
        if (cacheMap != null) {
            Iterator i = cacheMap.values().iterator();
            while (i.hasNext()) {
                Object o = i.next();
                if (o instanceof FlushableCacheData) {
                    if (((FlushableCacheData) o).flush(deaccelerate)) {
                        i.remove();
                    }
                }
            }
        }
    }

    /**
     * An interface for Objects used in the SurfaceManager cache
     * to implement if they have data that should be flushed when
     * the Image is flushed.
     */
    public static interface FlushableCacheData {
        /**
         * Flush all cached resources.
         * The deaccelerated parameter indicates if the flush is
         * happening because the associated surface is no longer
         * being accelerated (for instance the acceleration priority
         * is set below the threshold needed for acceleration).
         * Returns a boolean that indicates if the cached object is
         * no longer needed and should be removed from the cache.
         */
        public boolean flush(boolean deaccelerated);
    }

    /**
     * Called when image's acceleration priority is changed.
     * <p>
     * The default implementation will visit all of the value objects
     * in the cacheMap when the priority gets set to 0.0 and flush them
     * if they implement the FlushableCacheData interface.
     */
    public void setAccelerationPriority(float priority) {
        if (priority == 0.0f) {
            flush(true);
        }
    }
}
