/*
 * Copyright (c) 2008, 2011, Oracle  and/or its affiliates. All rights reserved.
 *
 * Use is subject to license terms.
 */

package com.sun.javafx.tk.quantum;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

import com.sun.glass.ui.Application;
import com.sun.glass.ui.Pixels;
import com.sun.javafx.iio.ImageFormatDescription;
import com.sun.javafx.iio.ImageStorage;
import com.sun.prism.Image;
import com.sun.prism.ImageFormatTool;
import com.sun.prism.PixelFormat;


public class PixelUtils {

    private PixelUtils() {
    }
    
    private static ImageFormatDescription[] supportedFormats =
                                ImageStorage.getSupportedDescriptions();

    protected static boolean supportedFormatType(String type) {
        for (ImageFormatDescription ifd: supportedFormats) {
            for (String ext: ifd.getExtensions()) {
                if (type.endsWith(ext)) {
                    return true;
                }
            }
        }
        return false;
    }

    public static Pixels imageToPixels(Image image) {
        PixelFormat.DataType pixelType = image.getDataType();
        Application app = Application.GetApplication();
        int nativeFormat = Pixels.getNativeFormat();
        Pixels pixels = null;
        
        if (pixelType == PixelFormat.DataType.BYTE) {
            ByteBuffer bytes = (ByteBuffer)image.getPixelBuffer();

            if (image.getBytesPerPixelUnit() == 3) {
                switch (nativeFormat) {
                    case Pixels.Format.BYTE_ARGB:
                        bytes = ImageFormatTool.RGBtoARGB(bytes);
                        break;
                    case Pixels.Format.BYTE_BGRA_PRE:
                        ByteBuffer bgra = ImageFormatTool.RGBtoBGRA(bytes);
                        bytes = ImageFormatTool.BGRAtoBGRA_PRE(bgra);
                        break;
                    default:
                        throw new IllegalArgumentException("unhandled native format: " + nativeFormat);
                }
            } else if (image.getPixelFormat() != PixelFormat.BYTE_BGRA_PRE) {
                throw new IllegalArgumentException("non-RGB image format");
            }
            pixels = app.createPixels((int)image.getWidth(),
                                      (int)image.getHeight(), bytes);
            return pixels;
        } else if (pixelType == PixelFormat.DataType.INT) {
            if (ByteOrder.nativeOrder() != ByteOrder.LITTLE_ENDIAN) {
                final String MSG = "INT_ARGB_PRE only supported for LITTLE_ENDIAN machines";
                throw new UnsupportedOperationException(MSG);
            }
            /*
             * Glass only returns BYTE_BGRA_PRE and our only INT PixelFormat
             * is INT_ARGB_PRE == BYTE_BGRA_PRE.  No conversion necessary.
             */
            IntBuffer ints = (IntBuffer)image.getPixelBuffer();
            pixels = app.createPixels((int)image.getWidth(),
                                      (int)image.getHeight(), ints);
            return pixels;
        } else {
            throw new IllegalArgumentException("unhandled image type: " + pixelType);
        }
    }
    
    public static Image pixelsToImage(Pixels pix) {
        Buffer pixbuf = pix.getPixels();
        if (pix.getBytesPerComponent() == 1) {
            ByteBuffer buf = ByteBuffer.allocateDirect(pixbuf.capacity());
            buf.put((ByteBuffer)pixbuf);
            buf.rewind();
            return (Image.fromByteBgraPreData(buf, pix.getWidth(), pix.getHeight()));
        } else if (pix.getBytesPerComponent() == 4) {
            IntBuffer buf = IntBuffer.allocate(pixbuf.capacity());
            buf.put((IntBuffer)pixbuf);
            buf.rewind();
            return (Image.fromIntArgbPreData((IntBuffer)pixbuf, 
                                             pix.getWidth(), pix.getHeight()));
        } else {
            throw new IllegalArgumentException("unhandled pixel buffer: " + 
                                               pixbuf.getClass().getName());
        }
    }
}
