/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.gltrace.state.transforms;

import com.android.ide.eclipse.gltrace.FileUtils;
import com.android.ide.eclipse.gltrace.GLEnum;
import com.android.ide.eclipse.gltrace.state.GLStringProperty;
import com.android.ide.eclipse.gltrace.state.IGLProperty;
import com.google.common.io.Files;
import com.google.common.primitives.UnsignedBytes;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import javax.imageio.ImageIO;

/**
 * {@link TexImageTransform} transforms the state to reflect the effect of a
 * glTexImage2D or glTexSubImage2D GL call.
 */
public class TexImageTransform implements IStateTransform {
    private static final String PNG_IMAGE_FORMAT = "PNG";
    private static final String TEXTURE_FILE_PREFIX = "tex";
    private static final String TEXTURE_FILE_SUFFIX = ".png";

    private final IGLPropertyAccessor mAccessor;
    private final File mTextureDataFile;

    private final int mxOffset;
    private final int myOffset;
    private final int mWidth;
    private final int mHeight;

    private String mOldValue;
    private String mNewValue;
    private GLEnum mFormat;
    private GLEnum mType;

    /**
     * Construct a texture image transformation.
     * @param accessor accessor to obtain the GL state variable to modify
     * @param textureData texture data passed in by the call. Could be null.
     * @param format format of the source texture data
     * @param xOffset x offset for the source data (used only in glTexSubImage2D)
     * @param yOffset y offset for the source data (used only in glTexSubImage2D)
     * @param width width of the texture
     * @param height height of the texture
     */
    public TexImageTransform(IGLPropertyAccessor accessor, File textureData, GLEnum format,
            GLEnum type, int xOffset, int yOffset, int width, int height) {
        mAccessor = accessor;
        mTextureDataFile = textureData;
        mFormat = format;
        mType = type;

        mxOffset = xOffset;
        myOffset = yOffset;
        mWidth = width;
        mHeight = height;
    }

    @Override
    public void apply(IGLProperty currentState) {
        assert mOldValue == null : "Transform cannot be applied multiple times"; //$NON-NLS-1$

        IGLProperty property = mAccessor.getProperty(currentState);
        if (!(property instanceof GLStringProperty)) {
            return;
        }

        GLStringProperty prop = (GLStringProperty) property;
        mOldValue = prop.getStringValue();

        // Applying texture transformations is a heavy weight process. So we perform
        // it only once and save the result in a temporary file. The property is actually
        // the path to the file.
        if (mNewValue == null) {
            try {
                if (mOldValue == null) {
                    mNewValue = createTexture(mTextureDataFile, mWidth, mHeight);
                } else {
                    mNewValue = updateTextureData(mOldValue, mTextureDataFile, mxOffset, myOffset,
                            mWidth, mHeight);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (RuntimeException e) {
                throw e;
            }
        }

        prop.setValue(mNewValue);
    }

    @Override
    public void revert(IGLProperty state) {
        if (mOldValue != null) {
            IGLProperty property = mAccessor.getProperty(state);
            property.setValue(mOldValue);
            mOldValue = null;
        }
    }

    @Override
    public IGLProperty getChangedProperty(IGLProperty state) {
        return mAccessor.getProperty(state);
    }

    /**
     * Creates a texture of provided width and height. If the texture data file is provided,
     * then the texture is initialized with the contents of that file, otherwise an empty
     * image is created.
     * @param textureDataFile path to texture data, could be null.
     * @param width width of texture
     * @param height height of texture
     * @return path to cached texture
     */
    private String createTexture(File textureDataFile, int width, int height) throws IOException {
        File f = FileUtils.createTempFile(TEXTURE_FILE_PREFIX, TEXTURE_FILE_SUFFIX);

        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);

        if (textureDataFile != null) {
            byte[] initialData = Files.toByteArray(textureDataFile);
            img.getRaster().setDataElements(0, 0, width, height,
                    formatSourceData(initialData, width, height));
        }

        ImageIO.write(img, PNG_IMAGE_FORMAT, f);

        return f.getAbsolutePath();
    }

    /**
     * Update part of an existing texture.
     * @param currentImagePath current texture image.
     * @param textureDataFile new data to update the current texture with
     * @param xOffset x offset for the update region
     * @param yOffset y offset for the update region
     * @param width width of the update region
     * @param height height of the update region
     * @return path to the updated texture
     */
    private String updateTextureData(String currentImagePath, File textureDataFile,
            int xOffset, int yOffset, int width, int height) throws IOException {
        assert currentImagePath != null : "Attempt to update a null texture";

        if (textureDataFile == null) {
            // Do not perform any updates if we don't have the actual data.
            return currentImagePath;
        }

        File f = FileUtils.createTempFile(TEXTURE_FILE_PREFIX, TEXTURE_FILE_SUFFIX);
        BufferedImage image = null;
        image = ImageIO.read(new File(currentImagePath));

        byte[] subImageData = Files.toByteArray(textureDataFile);
        image.getRaster().setDataElements(xOffset, yOffset, width, height,
                formatSourceData(subImageData, width, height));
        ImageIO.write(image, PNG_IMAGE_FORMAT, f);

        return f.getAbsolutePath();
    }

    private byte[] formatSourceData(byte[] subImageData, int width, int height) {
        if (mType != GLEnum.GL_UNSIGNED_BYTE) {
            subImageData = unpackData(subImageData, mType);
        }

        switch (mFormat) {
            case GL_RGBA:
                // no conversions necessary
                return subImageData;
            case GL_RGB:
                return addAlphaChannel(subImageData, width, height);
            case GL_RED:
            case GL_GREEN:
            case GL_BLUE:
                // GL_RED, GL_GREEN and GL_BLUE are all supposed to fill those respective
                // channels, but we assume that the programmers intent was to use GL_ALPHA in order
                // to overcome the issue that GL_ALPHA cannot be used with float data.
                if (mType != GLEnum.GL_FLOAT) {
                    throw new RuntimeException();
                } else {
                    // fall through - assume that it is GL_ALPHA
                }
                //$FALL-THROUGH$
            case GL_ALPHA:
                return addRGBChannels(subImageData, width, height);
            case GL_LUMINANCE:
                return createRGBAFromLuminance(subImageData, width, height);
            case GL_LUMINANCE_ALPHA:
                return createRGBAFromLuminanceAlpha(subImageData, width, height);
            default:
                throw new RuntimeException();
        }
    }

    private byte[] unpackData(byte[] data, GLEnum type) {
        switch (type) {
            case GL_UNSIGNED_BYTE:
                return data;
            case GL_UNSIGNED_SHORT_4_4_4_4:
                return convertShortToUnsigned(data, 0xf000, 12, 0x0f00, 8, 0x00f0, 4, 0x000f, 0,
                        true);
            case GL_UNSIGNED_SHORT_5_6_5:
                return convertShortToUnsigned(data, 0xf800, 11, 0x07e0, 5, 0x001f, 0, 0, 0,
                        false);
            case GL_UNSIGNED_SHORT_5_5_5_1:
                return convertShortToUnsigned(data, 0xf800, 11, 0x07c0, 6, 0x003e, 1, 0x1, 0,
                        true);
            case GL_FLOAT:
                return convertFloatToUnsigned(data);
            default:
                return data;
        }
    }

   private byte[] convertFloatToUnsigned(byte[] data) {
       byte[] unsignedData = new byte[data.length];
       ByteBuffer floatBuffer = ByteBuffer.wrap(data);
       for (int i = 0; i < data.length / 4; i++) {
           float v = floatBuffer.getFloat(i);
           byte alpha = (byte)(v * 255);
           unsignedData[i*4 + 3] = alpha;
       }
       return unsignedData;
   }

   private byte[] convertShortToUnsigned(byte[] shortData,
           int rmask, int rshift,
           int gmask, int gshift,
           int bmask, int bshift,
           int amask, int ashift,
           boolean includeAlpha) {
       int numChannels = includeAlpha ? 4 : 3;
       byte[] unsignedData = new byte[(shortData.length/2) * numChannels];

       for (int i = 0; i < (shortData.length / 2); i++) {
           int hi = UnsignedBytes.toInt(shortData[i*2 + 0]);
           int lo = UnsignedBytes.toInt(shortData[i*2 + 1]);

           int x = hi << 8 | lo;

           int r = (x & rmask) >>> rshift;
           int g = (x & gmask) >>> gshift;
           int b = (x & bmask) >>> bshift;
           int a = (x & amask) >>> ashift;

           unsignedData[i * numChannels + 0] = UnsignedBytes.checkedCast(r);
           unsignedData[i * numChannels + 1] = UnsignedBytes.checkedCast(g);
           unsignedData[i * numChannels + 2] = UnsignedBytes.checkedCast(b);

           if (includeAlpha) {
               unsignedData[i * numChannels + 3] = UnsignedBytes.checkedCast(a);
           }
       }

       return unsignedData;
   }

   private byte[] addAlphaChannel(byte[] sourceData, int width, int height) {
        assert sourceData.length == 3 * width * height; // should have R, G & B channels

        byte[] data = new byte[4 * width * height];

        for (int src = 0, dst = 0; src < sourceData.length; src += 3, dst += 4) {
            data[dst + 0] = sourceData[src + 0]; // copy R byte
            data[dst + 1] = sourceData[src + 1]; // copy G byte
            data[dst + 2] = sourceData[src + 2]; // copy B byte
            data[dst + 3] = 1; // add alpha = 1
        }

        return data;
    }

    private byte[] addRGBChannels(byte[] sourceData, int width, int height) {
        assert sourceData.length == width * height; // should have a single alpha channel

        byte[] data = new byte[4 * width * height];

        for (int src = 0, dst = 0; src < sourceData.length; src++, dst += 4) {
            data[dst + 0] = data[dst + 1] = data[dst + 2] = 0; // set R = G = B = 0
            data[dst + 3] = sourceData[src];                 // copy over alpha
        }

        return data;
    }

    private byte[] createRGBAFromLuminance(byte[] sourceData, int width, int height) {
        assert sourceData.length == width * height; // should have a single luminance channel

        byte[] data = new byte[4 * width * height];

        for (int src = 0, dst = 0; src < sourceData.length; src++, dst += 4) {
            int l = sourceData[src] * 3;
            if (l > 255) { // clamp to 255
                l = 255;
            }

            data[dst + 0] = data[dst + 1] = data[dst + 2] = (byte) l; // set R = G = B = L * 3
            data[dst + 3] = 1;                                        // set alpha = 1
        }

        return data;
    }

    private byte[] createRGBAFromLuminanceAlpha(byte[] sourceData, int width, int height) {
        assert sourceData.length == 2 * width * height; // should have luminance & alpha channels

        byte[] data = new byte[4 * width * height];

        for (int src = 0, dst = 0; src < sourceData.length; src += 2, dst += 4) {
            int l = sourceData[src] * 3;
            if (l > 255) { // clamp to 255
                l = 255;
            }

            data[dst + 0] = data[dst + 1] = data[dst + 2] = (byte) l; // set R = G = B = L * 3
            data[dst + 3] = sourceData[src + 1];                    // copy over alpha
        }

        return data;
    }
}
