/*
 * Copyright 2007 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.
 *
 * 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.
 */

import java.awt.Color;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class ImageFactory {
    public static int WIDTH = 256;
    public static int HEIGHT = 256;


    final static int aMask = 0xFF000000;
    final static int rMask = 0x00FF0000;
    final static int gMask = 0x0000FF00;
    final static int bMask = 0x000000FF;

    final static int r555Mask = 0x7c00;
    final static int g555Mask = 0x3e0;
    final static int b555Mask = 0x1f;

    final static int r565Mask = 0xf800;
    final static int g565Mask = 0x7e0;
    final static int b565Mask = 0x1f;

    final static int rShift = 16;
    final static int gShift = 8;
    final static int bShift = 0;

    public static BufferedImage createCCMImage(int cs, int dataType)
    {

        ColorSpace cSpace = ColorSpace.getInstance(cs);
        ComponentColorModel ccm = null;
        if (dataType == DataBuffer.TYPE_INT)
        {
            ccm = new ComponentColorModel(cSpace,
                    ((cs == ColorSpace.CS_GRAY)?
                        new int[] {8}: new int[] {8,8,8}),
                    false, false, Transparency.OPAQUE, dataType);
        } else {
            ccm = new ComponentColorModel(
                cSpace, false, false, Transparency.OPAQUE, dataType);
        }
        SampleModel sm = ccm.createCompatibleSampleModel(WIDTH, HEIGHT);
        WritableRaster raster = ccm.createCompatibleWritableRaster(WIDTH,
                                                                   HEIGHT);
        DataBuffer data = raster.getDataBuffer();
        fillCCM(data, sm, cSpace);
        return new BufferedImage(ccm, raster, false, null);
    }

    public static BufferedImage createDCMImage(int type, int cs) {
        if (type == BufferedImage.TYPE_INT_RGB && cs == ColorSpace.CS_sRGB) {
            BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
                                                    BufferedImage.TYPE_INT_RGB);
            DataBuffer data = image.getData().getDataBuffer();
            fill(image);
            return image;
        }

        ColorSpace cSpace = ColorSpace.getInstance(cs);
        DirectColorModel dcm = null;
        switch(type) {
            case BufferedImage.TYPE_INT_ARGB:
                dcm = new DirectColorModel(cSpace, 32, rMask, gMask,
                                           bMask, aMask, false,
                                           DataBuffer.TYPE_INT);
                break;
            case BufferedImage.TYPE_INT_RGB:
                dcm = new DirectColorModel(cSpace, 24, rMask, gMask,
                                           bMask, 0, false,
                                           DataBuffer.TYPE_INT);
                break;
            case BufferedImage.TYPE_INT_BGR:
                dcm = new DirectColorModel(cSpace, 24, rMask, gMask,
                                           bMask, 0, false,
                                           DataBuffer.TYPE_INT);
                break;
            case BufferedImage.TYPE_USHORT_555_RGB:
                dcm = new DirectColorModel(cSpace, 15, r555Mask, g555Mask,
                                           b555Mask, 0, false,
                                           DataBuffer.TYPE_USHORT);
                break;
            case BufferedImage.TYPE_USHORT_565_RGB:
                dcm = new DirectColorModel(cSpace, 16, r565Mask, g565Mask,
                                           b565Mask, 0, false,
                                           DataBuffer.TYPE_USHORT);
                break;
        }
        SampleModel sm = dcm.createCompatibleSampleModel(WIDTH, HEIGHT);
        WritableRaster raster = dcm.createCompatibleWritableRaster(WIDTH,
                                                                   HEIGHT);
        switch(type) {
            case BufferedImage.TYPE_INT_ARGB:
                fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
                break;
            case BufferedImage.TYPE_INT_RGB:
                fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
                break;
            case BufferedImage.TYPE_INT_BGR:
                fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
                break;
            case BufferedImage.TYPE_USHORT_555_RGB:
                fillDCM(raster.getDataBuffer(), sm, cSpace.getType(), 5, 5, 5);
                break;
            case BufferedImage.TYPE_USHORT_565_RGB:
                fillDCM(raster.getDataBuffer(), sm, cSpace.getType(), 5, 6, 5);
                break;
        }
        return new BufferedImage(dcm, raster, false, null);
    }

    public static void fill(BufferedImage image) {
        for (int i = 0; i < WIDTH; i++) {
            for (int j = 0; j < HEIGHT; j++) {
                image.setRGB(i,j,0xFF000000 | (i << 16) | (j << 8) |
                        ((i + j)>>1));
            }
        }
    }

    public static void fillCCM(DataBuffer data, SampleModel sm, ColorSpace cs) {
        switch (cs.getType()) {
            case ColorSpace.TYPE_RGB:
            case ColorSpace.TYPE_XYZ:
            case ColorSpace.TYPE_3CLR:
                if (data.getDataType() == DataBuffer.TYPE_BYTE ||
                    data.getDataType() == DataBuffer.TYPE_INT)
                {
                    int [] pixel = new int[3];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = i;
                            pixel[1] = j;
                            pixel[2] = ((i + j)>>1);
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                } else if (data.getDataType() == DataBuffer.TYPE_SHORT) {
                    int [] pixel = new int[3];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = (i<<7);
                            pixel[1] = (j<<7);
                            pixel[2] = ((i + j)<<6);
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                } else if (data.getDataType() == DataBuffer.TYPE_USHORT) {
                    int [] pixel = new int[3];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = (i<<8);
                            pixel[1] = (j<<8);
                            pixel[2] = ((i + j)<<7);
                            sm.setPixel(i, j, pixel, data);
                        }
                    }

                } else if (data.getDataType() == DataBuffer.TYPE_DOUBLE) {
                    double [] pixel = new double [3];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = (i/255.0)*(cs.getMaxValue(0) -
                                                  cs.getMinValue(0)) +
                                       cs.getMinValue(0);
                            pixel[1] = (j/255.0)*(cs.getMaxValue(1) -
                                                  cs.getMinValue(1)) +
                                       cs.getMinValue(1);
                            pixel[2] = (((i + j)>>1)/255.0)*(cs.getMaxValue(2) -
                                                             cs.getMinValue(2))+
                                       cs.getMinValue(2);
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                } else if (data.getDataType() == DataBuffer.TYPE_FLOAT) {
                    float [] pixel = new float [3];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = (i/255.0f)*(cs.getMaxValue(0) -
                                                  cs.getMinValue(0)) +
                                       cs.getMinValue(0);
                            pixel[1] = (j/255.0f)*(cs.getMaxValue(1) -
                                                  cs.getMinValue(1)) +
                                       cs.getMinValue(1);
                            pixel[2] = (((i + j)>>1)/255.0f)*(cs.getMaxValue(2)-
                                                              cs.getMinValue(2))
                                       + cs.getMinValue(2);
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                } else {
                    throw new RuntimeException("Unsupported DataBuffer type");
                }
                break;
            case ColorSpace.TYPE_GRAY:
                if (data.getDataType() == DataBuffer.TYPE_BYTE ||
                    data.getDataType() == DataBuffer.TYPE_INT) {
                    int [] pixel = new int[1];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = i;
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                } else if (data.getDataType() == DataBuffer.TYPE_SHORT) {
                    int [] pixel = new int[1];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = i << 7;
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                } else if (data.getDataType() == DataBuffer.TYPE_USHORT) {
                    int [] pixel = new int[1];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = i << 8;
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                } else if (data.getDataType() == DataBuffer.TYPE_DOUBLE) {
                    double [] pixel = new double[1];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = (i/255.0)*(cs.getMaxValue(0) -
                                                  cs.getMinValue(0)) +
                                       cs.getMinValue(0);;
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                 } else if (data.getDataType() == DataBuffer.TYPE_FLOAT) {
                    float [] pixel = new float[1];
                    for (int i = 0; i < WIDTH; i++) {
                        for (int j = 0; j < HEIGHT; j++) {
                            pixel[0] = (i/255.0f)*(cs.getMaxValue(0) -
                                                  cs.getMinValue(0)) +
                                       cs.getMinValue(0);;
                            sm.setPixel(i, j, pixel, data);
                        }
                    }
                } else {
                    throw new RuntimeException("Unsupported DataBuffer type");
                }
                break;
        }
    }

    public static void fillDCM(DataBuffer data, SampleModel sm, int csType,
                               int c1Bits, int c2Bits, int c3Bits)
    {
        int [] pixel;
        pixel = new int[4];
        for (int i = 0; i < WIDTH; i++) {
            for (int j = 0; j < HEIGHT; j++) {
                pixel[0] = i >> (8 - c1Bits);
                pixel[1] = j >> (8 - c2Bits);
                pixel[2] = ((i + j)>>1) >> (8 - c3Bits);
                pixel[3] = 0xFF;
                sm.setPixel(i, j, pixel, data);
            }
        }
    }

    public static void fillDCM(DataBuffer data, SampleModel sm, int csType) {
        fillDCM(data, sm, csType, 8, 8, 8);
    }

    public static BufferedImage createDstImage(int type) {
        return new BufferedImage(WIDTH, HEIGHT, type);
    }
}
