/*
 * Copyright (C) 2011 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 android.opengl.cts;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.opengl.ETC1;
import android.opengl.ETC1Util;
import android.opengl.GLES20;

import java.io.InputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashMap;

public class CompressedTextureLoader {
    public static final String TEXTURE_UNCOMPRESSED = "UNCOMPRESSED";
    public static final String TEXTURE_ETC1 = "ETC1";
    public static final String TEXTURE_S3TC = "S3TC";
    public static final String TEXTURE_ATC = "ATC";
    public static final String TEXTURE_PVRTC = "PVRTC";

    public static class Texture {
        public Texture(int width, int height, int internalformat, ByteBuffer data,
                       String formatName) {
            mWidth = width;
            mHeight = height;
            mInternalFormat = internalformat;
            mData = data;
            mFormatName = formatName;
        }

        /**
         * Get the width of the texture in pixels.
         * @return the width of the texture in pixels.
         */
        public int getWidth() { return mWidth; }

        /**
         * Get the height of the texture in pixels.
         * @return the width of the texture in pixels.
         */
        public int getHeight() { return mHeight; }

        /**
         * Get the compressed data of the texture.
         * @return the texture data.
         */
        public ByteBuffer getData() { return mData; }

        /**
         * Get the format of the texture.
         * @return the internal format.
         */
        public int getFormat() { return mInternalFormat; }

        /**
         * Get the format of the texture.
         * @return the internal format.
         */
        public boolean isSupported() { return isFormatSupported(mFormatName); }

        private int mWidth;
        private int mHeight;
        private int mInternalFormat;
        private ByteBuffer mData;
        private String mFormatName;
    }

    /*  .pvr header is described by the following c struct
        typedef struct PVR_TEXTURE_HEADER_TAG{
            unsigned int  dwHeaderSize;   // size of the structure
            unsigned int  dwHeight;    // height of surface to be created
            unsigned int  dwWidth;    // width of input surface
            unsigned int  dwMipMapCount;   // number of MIP-map levels requested
            unsigned int  dwpfFlags;   // pixel format flags
            unsigned int  dwDataSize;   // Size of the compress data
            unsigned int  dwBitCount;   // number of bits per pixel
            unsigned int  dwRBitMask;   // mask for red bit
            unsigned int  dwGBitMask;   // mask for green bits
            unsigned int  dwBBitMask;   // mask for blue bits
            unsigned int  dwAlphaBitMask;   // mask for alpha channel
            unsigned int  dwPVR;    // should be 'P' 'V' 'R' '!'
            unsigned int  dwNumSurfs;   //number of slices for volume textures or skyboxes
        } PVR_TEXTURE_HEADER;
    */
    static final int PVR_HEADER_SIZE = 13 * 4;
    static final int PVR_2BPP = 24;
    static final int PVR_4BPP = 25;
    static final int PVR_MAGIC_NUMBER = 559044176;

    static final int GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
    static final int GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01;
    static final int GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
    static final int GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03;

    static class PVRHeader {
        int mHeaderSize;   // size of the structure
        int mHeight;    // height of surface to be created
        int mWidth;    // width of input surface
        int mMipMapCount;   // number of MIP-map levels requested
        int mpfFlags;   // pixel format flags
        int mDataSize;   // Size of the compress data
        int mBitCount;   // number of bits per pixel
        int mRBitMask;   // mask for red bit
        int mGBitMask;   // mask for green bits
        int mBBitMask;   // mask for blue bits
        int mAlphaBitMask;   // mask for alpha channel
        int mPVR;    // should be 'P' 'V' 'R' '!'
        int mNumSurfs;   //number of slices for volume textures or skyboxes
    }

    protected static PVRHeader readPVRHeader(InputStream is) {

        byte[] headerData = new byte[PVR_HEADER_SIZE];
        try {
            is.read(headerData);
        } catch (Exception e) {
            throw new RuntimeException("Unable to read data");
        }

        ByteBuffer headerBuffer = ByteBuffer.allocateDirect(PVR_HEADER_SIZE)
                .order(ByteOrder.nativeOrder());
        headerBuffer.put(headerData, 0, PVR_HEADER_SIZE).position(0);

        PVRHeader header = new PVRHeader();

        header.mHeaderSize = headerBuffer.getInt();
        header.mHeight = headerBuffer.getInt();
        header.mWidth = headerBuffer.getInt();
        header.mMipMapCount = headerBuffer.getInt();
        header.mpfFlags = headerBuffer.getInt();
        header.mDataSize = headerBuffer.getInt();
        header.mBitCount = headerBuffer.getInt();
        header.mRBitMask = headerBuffer.getInt();
        header.mGBitMask = headerBuffer.getInt();
        header.mBBitMask = headerBuffer.getInt();
        header.mAlphaBitMask = headerBuffer.getInt();
        header.mPVR = headerBuffer.getInt();
        header.mNumSurfs = headerBuffer.getInt();

        if (header.mHeaderSize != PVR_HEADER_SIZE ||
            header.mPVR != PVR_MAGIC_NUMBER) {
            throw new RuntimeException("Invalid header data");
        }

        return header;
    }

    public static Texture loadTextureATC(Resources res, int id) {
        Texture tex = new Texture(0, 0, 0, null, "Cts!");
        return tex;
    }

    private static ETC1Util.ETC1Texture compressTexture(Buffer input,
                                                        int width, int height,
                                                        int pixelSize, int stride){
        int encodedImageSize = ETC1.getEncodedDataSize(width, height);
        ByteBuffer compressedImage = ByteBuffer.allocateDirect(encodedImageSize).
            order(ByteOrder.nativeOrder());
        ETC1.encodeImage(input, width, height, pixelSize, stride, compressedImage);
        return new ETC1Util.ETC1Texture(width, height, compressedImage);
    }

    public static Texture createFromUncompressedETC1(Bitmap bitmap) {
        int dataSize = bitmap.getRowBytes() * bitmap.getHeight();

        ByteBuffer dataBuffer;
        dataBuffer = ByteBuffer.allocateDirect(dataSize).order(ByteOrder.nativeOrder());
        bitmap.copyPixelsToBuffer(dataBuffer);
        dataBuffer.position(0);

        int bytesPerPixel = bitmap.getRowBytes() / bitmap.getWidth();
        ETC1Util.ETC1Texture compressed = compressTexture(dataBuffer,
                                                          bitmap.getWidth(),
                                                          bitmap.getHeight(),
                                                          bytesPerPixel,
                                                          bitmap.getRowBytes());

        Texture tex = new Texture(compressed.getWidth(), compressed.getHeight(),
                                  ETC1.ETC1_RGB8_OES, compressed.getData(), TEXTURE_ETC1);

        return tex;
    }

    private static ByteBuffer read(InputStream is, int dataSize) {
        ByteBuffer dataBuffer;
        dataBuffer = ByteBuffer.allocateDirect(dataSize).order(ByteOrder.nativeOrder());
        byte[] ioBuffer = new byte[4096];
        for (int i = 0; i < dataSize; ) {
            int chunkSize = Math.min(ioBuffer.length, dataSize - i);
            try {
                is.read(ioBuffer, 0, chunkSize);
            } catch (Exception e) {
                throw new RuntimeException("Unable to read data");
            }
            dataBuffer.put(ioBuffer, 0, chunkSize);
            i += chunkSize;
        }
        dataBuffer.position(0);
        return dataBuffer;
    }

    public static Texture loadTexturePVRTC(Resources res, int id) {
        InputStream is = null;
        try {
            is = res.openRawResource(id);
        } catch (Exception e) {
            throw new RuntimeException("Unable to open resource " + id);
        }

        PVRHeader header = readPVRHeader(is);

        int format = header.mpfFlags & 0xFF;
        int internalFormat = 0;
        if (format == PVR_2BPP && header.mAlphaBitMask == 1) {
            internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
        } else if (format == PVR_2BPP && header.mAlphaBitMask == 0) {
            internalFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
        } else if (format == PVR_4BPP && header.mAlphaBitMask == 1) {
            internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
        } else if (format == PVR_4BPP && header.mAlphaBitMask == 0) {
            internalFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
        }

        // only load the first mip level for now
        int dataSize = (header.mWidth * header.mHeight * header.mBitCount) >> 3;
        ByteBuffer dataBuffer = read(is, dataSize);
        Texture tex = new Texture(header.mWidth, header.mHeight,
                                  internalFormat, dataBuffer,
                                  TEXTURE_PVRTC);
        try {
            is.close();
        } catch (Exception e) {
            throw new RuntimeException("Unable to close resource stream " + id);
        }
        return tex;
    }

    /* DDS Header is described by the following structs
       typedef struct {
          DWORD           dwSize;
          DWORD           dwFlags;
          DWORD           dwHeight;
          DWORD           dwWidth;
          DWORD           dwPitchOrLinearSize;
          DWORD           dwDepth;
          DWORD           dwMipMapCount;
          DWORD           dwReserved1[11];
          DDS_PIXELFORMAT ddspf;
          DWORD           dwCaps;
          DWORD           dwCaps2;
          DWORD           dwCaps3;
          DWORD           dwCaps4;
          DWORD           dwReserved2;
        } DDS_HEADER;

        struct DDS_PIXELFORMAT {
          DWORD dwSize;
          DWORD dwFlags;
          DWORD dwFourCC;
          DWORD dwRGBBitCount;
          DWORD dwRBitMask;
          DWORD dwGBitMask;
          DWORD dwBBitMask;
          DWORD dwABitMask;
        };

        In the file it looks like this
        DWORD               dwMagic;
        DDS_HEADER          header;
        DDS_HEADER_DXT10    header10; // If the DDS_PIXELFORMAT dwFlags is set to DDPF_FOURCC
                                      // and dwFourCC is DX10

    */

    static final int DDS_HEADER_STRUCT_SIZE = 124;
    static final int DDS_PIXELFORMAT_STRUCT_SIZE = 32;
    static final int DDS_HEADER_SIZE = 128;
    static final int DDS_MAGIC_NUMBER = 0x20534444;
    static final int DDS_DDPF_FOURCC = 0x4;
    static final int DDS_DXT1 = 0x31545844;
    static final int DDS_DXT5 = 0x35545844;

    static final int COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
    static final int COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
    static final int COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;

    static class DDSHeader {
        int mMagic;
        int mSize;
        int mFlags;
        int mHeight;
        int mWidth;
        int mPitchOrLinearSize;
        int mDepth;
        int mMipMapCount;
        int[] mReserved1;
        // struct DDS_PIXELFORMAT {
            int mPixelFormatSize;
            int mPixelFormatFlags;
            int mPixelFormatFourCC;
            int mPixelFormatRGBBitCount;
            int mPixelFormatRBitMask;
            int mPixelFormatGBitMask;
            int mPixelFormatBBitMask;
            int mPixelFormatABitMask;
        // };
        int mCaps;
        int mCaps2;
        int mCaps3;
        int mCaps4;
        int mReserved2;

        DDSHeader() {
            mReserved1 = new int[11];
        }
    }

    protected static DDSHeader readDDSHeader(InputStream is) {

        byte[] headerData = new byte[DDS_HEADER_SIZE];
        try {
            is.read(headerData);
        } catch (Exception e) {
            throw new RuntimeException("Unable to read data");
        }

        ByteBuffer headerBuffer = ByteBuffer.allocateDirect(DDS_HEADER_SIZE)
                .order(ByteOrder.nativeOrder());
        headerBuffer.put(headerData, 0, DDS_HEADER_SIZE).position(0);

        DDSHeader header = new DDSHeader();

        header.mMagic = headerBuffer.getInt();
        header.mSize = headerBuffer.getInt();
        header.mFlags = headerBuffer.getInt();
        header.mHeight = headerBuffer.getInt();
        header.mWidth = headerBuffer.getInt();
        header.mPitchOrLinearSize = headerBuffer.getInt();
        header.mDepth = headerBuffer.getInt();
        header.mMipMapCount = headerBuffer.getInt();
        for (int i = 0; i < header.mReserved1.length; i ++) {
            header.mReserved1[i] = headerBuffer.getInt();
        }
        // struct DDS_PIXELFORMAT {
            header.mPixelFormatSize = headerBuffer.getInt();
            header.mPixelFormatFlags = headerBuffer.getInt();
            header.mPixelFormatFourCC = headerBuffer.getInt();
            header.mPixelFormatRGBBitCount = headerBuffer.getInt();
            header.mPixelFormatRBitMask = headerBuffer.getInt();
            header.mPixelFormatGBitMask = headerBuffer.getInt();
            header.mPixelFormatBBitMask = headerBuffer.getInt();
            header.mPixelFormatABitMask = headerBuffer.getInt();
        // };
        header.mCaps = headerBuffer.getInt();
        header.mCaps2 = headerBuffer.getInt();
        header.mCaps3 = headerBuffer.getInt();
        header.mCaps4 = headerBuffer.getInt();
        header.mReserved2 = headerBuffer.getInt();

        if (header.mSize != DDS_HEADER_STRUCT_SIZE ||
            header.mPixelFormatSize != DDS_PIXELFORMAT_STRUCT_SIZE ||
            header.mMagic != DDS_MAGIC_NUMBER) {
            throw new RuntimeException("Invalid header data");
        }

        return header;
    }

    // Very simple loader that only reads in the header and a DXT1 mip level 0
    public static Texture loadTextureDXT(Resources res, int id) {
        InputStream is = null;
        try {
            is = res.openRawResource(id);
        } catch (Exception e) {
            throw new RuntimeException("Unable to open resource " + id);
        }

        DDSHeader header = readDDSHeader(is);

        if (header.mPixelFormatFlags != DDS_DDPF_FOURCC) {
            throw new RuntimeException("Unsupported DXT data");
        }

        int internalFormat = 0;
        int bpp = 0;
        switch (header.mPixelFormatFourCC) {
        case DDS_DXT1:
            internalFormat = COMPRESSED_RGB_S3TC_DXT1_EXT;
            bpp = 4;
            break;
        case DDS_DXT5:
            internalFormat = COMPRESSED_RGBA_S3TC_DXT5_EXT;
            bpp = 8;
            break;
        default:
            throw new RuntimeException("Unsupported DXT data");
        }

        // only load the first mip level for now
        int dataSize = (header.mWidth * header.mHeight * bpp) >> 3;
        if (dataSize != header.mPitchOrLinearSize) {
            throw new RuntimeException("Expected data and header mismatch");
        }
        ByteBuffer dataBuffer = read(is, dataSize);

        Texture tex = new Texture(header.mWidth, header.mHeight, internalFormat,
                                  dataBuffer, TEXTURE_S3TC);
        return tex;
    }

    static HashMap<String, Boolean> sExtensionMap;
    static HashMap<String, Boolean> sFormatMap;

    private static synchronized void updateSupportedFormats() {
        if (sExtensionMap != null) {
            return;
        }

        sExtensionMap = new HashMap<String, Boolean>();
        sFormatMap = new HashMap<String, Boolean>();
        String extensionList = GLES20.glGetString(GLES20.GL_EXTENSIONS);

        for (String extension : extensionList.split(" ")) {
            sExtensionMap.put(extension, true);
        }

        // Check ETC1
        sFormatMap.put(TEXTURE_ETC1, ETC1Util.isETC1Supported());
        // Check ATC
        if (sExtensionMap.get("GL_AMD_compressed_ATC_texture") != null ||
            sExtensionMap.get("GL_ATI_compressed_texture_atitc") != null ||
            sExtensionMap.get("GL_ATI_texture_compression_atitc") != null) {
            sFormatMap.put(TEXTURE_ATC, true);
        }
        // Check DXT
        if (sExtensionMap.get("GL_EXT_texture_compression_dxt1") != null ||
            sExtensionMap.get("GL_EXT_texture_compression_s3tc") != null ||
            sExtensionMap.get("OES_texture_compression_S3TC") != null) {
            sFormatMap.put(TEXTURE_S3TC, true);
        }
        // Check DXT
        if (sExtensionMap.get("GL_IMG_texture_compression_pvrtc") != null) {
            sFormatMap.put(TEXTURE_PVRTC, true);
        }

        /*Log.i(TAG, "mIsSupportedETC1 " + sFormatMap.get(TEXTURE_ETC1));
        Log.i(TAG, "mIsSupportedATC " + sFormatMap.get(TEXTURE_ATC));
        Log.i(TAG, "mIsSupportedDXT " + sFormatMap.get(TEXTURE_S3TC));
        Log.i(TAG, "mIsSupportedPVRTC " + sFormatMap.get(TEXTURE_PVRTC));*/
    }

    private static boolean isFormatSupported(String format) {
        updateSupportedFormats();
        Boolean supported = sFormatMap.get(format);
        return supported != null ? supported : false;
    }
}
