/*
 * Copyright (c) 2007, 2008, 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.java2d.d3d;

import java.awt.AWTException;
import java.awt.BufferCapabilities;
import java.awt.BufferCapabilities.FlipContents;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.ImageCapabilities;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.VolatileImage;
import sun.awt.Win32GraphicsConfig;
import sun.awt.image.SunVolatileImage;
import sun.awt.image.SurfaceManager;
import sun.awt.windows.WComponentPeer;
import sun.java2d.Surface;
import sun.java2d.SurfaceData;
import sun.java2d.pipe.hw.AccelDeviceEventNotifier;
import sun.java2d.pipe.hw.AccelTypedVolatileImage;
import sun.java2d.pipe.hw.AccelGraphicsConfig;
import sun.java2d.pipe.hw.AccelSurface;
import sun.java2d.pipe.hw.ContextCapabilities;
import static sun.java2d.pipe.hw.AccelSurface.*;
import static sun.java2d.d3d.D3DContext.D3DContextCaps.*;
import sun.java2d.pipe.hw.AccelDeviceEventListener;

public class D3DGraphicsConfig
    extends Win32GraphicsConfig
    implements AccelGraphicsConfig
{
    private static ImageCapabilities imageCaps = new D3DImageCaps();

    private BufferCapabilities bufferCaps;
    private D3DGraphicsDevice device;

    protected D3DGraphicsConfig(D3DGraphicsDevice device) {
        super(device, 0);
        this.device = device;
    }

    public SurfaceData createManagedSurface(int w, int h, int transparency) {
        return D3DSurfaceData.createData(this, w, h,
                                         getColorModel(transparency),
                                         null,
                                         D3DSurfaceData.TEXTURE);
    }

    @Override
    public synchronized void displayChanged() {
        super.displayChanged();
        // the context could hold a reference to a D3DSurfaceData, which in
        // turn has a reference back to this D3DGraphicsConfig, so in order
        // for this instance to be disposed we need to break the connection
        D3DRenderQueue rq = D3DRenderQueue.getInstance();
        rq.lock();
        try {
            D3DContext.invalidateCurrentContext();
        } finally {
            rq.unlock();
        }
    }

    @Override
    public ColorModel getColorModel(int transparency) {
        switch (transparency) {
        case Transparency.OPAQUE:
            // REMIND: once the ColorModel spec is changed, this should be
            //         an opaque premultiplied DCM...
            return new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
        case Transparency.BITMASK:
            return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
        case Transparency.TRANSLUCENT:
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
            return new DirectColorModel(cs, 32,
                                        0xff0000, 0xff00, 0xff, 0xff000000,
                                        true, DataBuffer.TYPE_INT);
        default:
            return null;
        }
    }

    @Override
    public String toString() {
        return ("D3DGraphicsConfig[dev="+screen+",pixfmt="+visual+"]");
    }

    /**
     * The following methods are invoked from WComponentPeer.java rather
     * than having the Win32-dependent implementations hardcoded in that
     * class.  This way the appropriate actions are taken based on the peer's
     * GraphicsConfig, whether it is a Win32GraphicsConfig or a
     * D3DGraphicsConfig.
     */

    /**
     * Creates a new SurfaceData that will be associated with the given
     * WComponentPeer. D3D9 doesn't allow rendering to the screen,
     * so a GDI surface will be returned.
     */
    @Override
    public SurfaceData createSurfaceData(WComponentPeer peer,
                                         int numBackBuffers)
    {
        return super.createSurfaceData(peer, numBackBuffers);
    }

    /**
     * The following methods correspond to the multibuffering methods in
     * WComponentPeer.java...
     */

    /**
     * Checks that the requested configuration is natively supported; if not,
     * an AWTException is thrown.
     */
    @Override
    public void assertOperationSupported(Component target,
                                         int numBuffers,
                                         BufferCapabilities caps)
        throws AWTException
    {
        if (numBuffers < 2 || numBuffers > 4) {
            throw new AWTException("Only 2-4 buffers supported");
        }
        if (caps.getFlipContents() == BufferCapabilities.FlipContents.COPIED &&
            numBuffers != 2)
        {
            throw new AWTException("FlipContents.COPIED is only" +
                                   "supported for 2 buffers");
        }
    }

    /**
     * Creates a D3D-based backbuffer for the given peer and returns the
     * image wrapper.
     */
    @Override
    public VolatileImage createBackBuffer(WComponentPeer peer) {
        Component target = (Component)peer.getTarget();
        // it is possible for the component to have size 0x0, adjust it to
        // be at least 1x1 to avoid IAE
        int w = Math.max(1, target.getWidth());
        int h = Math.max(1, target.getHeight());
        return new SunVolatileImage(target, w, h, Boolean.TRUE);
    }

    /**
     * Performs the native D3D flip operation for the given target Component.
     */
    @Override
    public void flip(WComponentPeer peer,
                     Component target, VolatileImage backBuffer,
                     int x1, int y1, int x2, int y2,
                     BufferCapabilities.FlipContents flipAction)
    {
        // REMIND: we should actually get a surface data for the
        // backBuffer's VI
        SurfaceManager d3dvsm =
            SurfaceManager.getManager(backBuffer);
        SurfaceData sd = d3dvsm.getPrimarySurfaceData();
        if (sd instanceof D3DSurfaceData) {
            D3DSurfaceData d3dsd = (D3DSurfaceData)sd;
            D3DSurfaceData.swapBuffers(d3dsd, x1, y1, x2, y2);
        } else {
            // the surface was likely lost could not have been restored
            Graphics g = peer.getGraphics();
            try {
                g.drawImage(backBuffer,
                            x1, y1, x2, y2,
                            x1, y1, x2, y2,
                            null);
            } finally {
                g.dispose();
            }
        }

        if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {
            Graphics g = backBuffer.getGraphics();
            try {
                g.setColor(target.getBackground());
                g.fillRect(0, 0,
                           backBuffer.getWidth(),
                           backBuffer.getHeight());
            } finally {
                g.dispose();
            }
        }
    }

    private static class D3DBufferCaps extends BufferCapabilities {
        public D3DBufferCaps() {
            // REMIND: should we indicate that the front-buffer
            // (the on-screen rendering) is not accelerated?
            super(imageCaps, imageCaps, FlipContents.UNDEFINED);
        }
        @Override
        public boolean isMultiBufferAvailable() {
            return true;
        }

    }

    @Override
    public BufferCapabilities getBufferCapabilities() {
        if (bufferCaps == null) {
            bufferCaps = new D3DBufferCaps();
        }
        return bufferCaps;
    }

    private static class D3DImageCaps extends ImageCapabilities {
        private D3DImageCaps() {
            super(true);
        }
        @Override
        public boolean isTrueVolatile() {
            return true;
        }
    }

    @Override
    public ImageCapabilities getImageCapabilities() {
        return imageCaps;
    }

    D3DGraphicsDevice getD3DDevice() {
        return device;
    }

    /**
     * {@inheritDoc}
     *
     * @see sun.java2d.pipe.hw.BufferedContextProvider#getContext
     */
    @Override
    public D3DContext getContext() {
        return device.getContext();
    }

    /**
     * {@inheritDoc}
     *
     * @see sun.java2d.pipe.hw.AccelGraphicsConfig#createCompatibleVolatileImage
     */
    @Override
    public VolatileImage
        createCompatibleVolatileImage(int width, int height,
                                      int transparency, int type)
    {
        if (type == FLIP_BACKBUFFER || type == WINDOW || type == UNDEFINED ||
            transparency == Transparency.BITMASK)
        {
            return null;
        }
        boolean isOpaque = transparency == Transparency.OPAQUE;
        if (type == RT_TEXTURE) {
            int cap = isOpaque ? CAPS_RT_TEXTURE_OPAQUE : CAPS_RT_TEXTURE_ALPHA;
            if (!device.isCapPresent(cap)) {
                return null;
            }
        } else if (type == RT_PLAIN) {
            if (!isOpaque && !device.isCapPresent(CAPS_RT_PLAIN_ALPHA)) {
                return null;
            }
        }

        SunVolatileImage vi = new AccelTypedVolatileImage(this, width, height,
                                                          transparency, type);
        Surface sd = vi.getDestSurface();
        if (!(sd instanceof AccelSurface) ||
            ((AccelSurface)sd).getType() != type)
        {
            vi.flush();
            vi = null;
        }

        return vi;
    }

    /**
     * {@inheritDoc}
     *
     * @see sun.java2d.pipe.hw.AccelGraphicsConfig#getContextCapabilities
     */
    @Override
    public ContextCapabilities getContextCapabilities() {
        return device.getContextCapabilities();
    }

    @Override
    public void addDeviceEventListener(AccelDeviceEventListener l) {
        AccelDeviceEventNotifier.addListener(l, device.getScreen());
    }

    @Override
    public void removeDeviceEventListener(AccelDeviceEventListener l) {
        AccelDeviceEventNotifier.removeListener(l);
    }
}
