/*
 * 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.graphics;

import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.ninepatch.NinePatchChunk;
import com.android.resources.Density;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.annotation.Nullable;
import com.android.layoutlib.bridge.util.NinePatchInputStream;
import android.graphics.BitmapFactory.Options;
import android.graphics.Bitmap_Delegate.BitmapCreateFlags;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.util.EnumSet;
import java.util.Set;

/**
 * Delegate implementing the native methods of android.graphics.BitmapFactory
 *
 * Through the layoutlib_create tool, the original native methods of BitmapFactory have been
 * replaced by calls to methods of the same name in this delegate class.
 *
 * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
 * around to map int to instance of the delegate.
 *
 */
/*package*/ class BitmapFactory_Delegate {

    // ------ Native Delegates ------

    @LayoutlibDelegate
    /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
            @Nullable Rect padding, @Nullable Options opts, long inBitmapHandle,
            long colorSpaceHandle) {
        Bitmap bm = null;

        Density density = Density.MEDIUM;
        Set<BitmapCreateFlags> bitmapCreateFlags = EnumSet.of(BitmapCreateFlags.MUTABLE);
        if (opts != null) {
            density = Density.getEnum(opts.inDensity);
            if (opts.inPremultiplied) {
                bitmapCreateFlags.add(BitmapCreateFlags.PREMULTIPLIED);
            }
            opts.inScaled = false;
        }

        try {
            if (is instanceof NinePatchInputStream) {
                NinePatchInputStream npis = (NinePatchInputStream) is;
                npis.disableFakeMarkSupport();

                // load the bitmap as a nine patch
                com.android.ninepatch.NinePatch ninePatch = com.android.ninepatch.NinePatch.load(
                        npis, true /*is9Patch*/, false /*convert*/);

                // get the bitmap and chunk objects.
                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags,
                        density);
                NinePatchChunk chunk = ninePatch.getChunk();

                // put the chunk in the bitmap
                bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));

                if (padding != null) {
                    // read the padding
                    int[] paddingArray = chunk.getPadding();
                    padding.left = paddingArray[0];
                    padding.top = paddingArray[1];
                    padding.right = paddingArray[2];
                    padding.bottom = paddingArray[3];
                }
            } else {
                // load the bitmap directly.
                bm = Bitmap_Delegate.createBitmap(is, bitmapCreateFlags, density);
            }
        } catch (IOException e) {
            Bridge.getLog().error(null, "Failed to load image", e, null, null);
        }

        return bm;
    }

    @LayoutlibDelegate
    /*package*/ static Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
            Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle) {
        if (opts != null) {
            opts.inBitmap = null;
        }
        return null;
    }

    @LayoutlibDelegate
    /*package*/ static Bitmap nativeDecodeAsset(long asset, Rect padding, Options opts,
            long inBitmapHandle, long colorSpaceHandle) {
        if (opts != null) {
            opts.inBitmap = null;
        }
        return null;
    }

    @LayoutlibDelegate
    /*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
            int length, Options opts, long inBitmapHandle, long colorSpaceHandle) {
        if (opts != null) {
            opts.inBitmap = null;
        }
        return null;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nativeIsSeekable(FileDescriptor fd) {
        return true;
    }

    /**
     * Set the newly decoded bitmap's density based on the Options.
     *
     * Copied from {@link BitmapFactory#setDensityFromOptions(Bitmap, Options)}.
     */
    @LayoutlibDelegate
    /*package*/ static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
        if (outputBitmap == null || opts == null) return;

        final int density = opts.inDensity;
        if (density != 0) {
            outputBitmap.setDensity(density);
            final int targetDensity = opts.inTargetDensity;
            if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
                return;
            }

            // --- Change from original implementation begins ---
            // LayoutLib doesn't scale the nine patch when decoding it. Hence, don't change the
            // density of the source bitmap in case of ninepatch.

            if (opts.inScaled) {
            // --- Change from original implementation ends. ---
                outputBitmap.setDensity(targetDensity);
            }
        } else if (opts.inBitmap != null) {
            // bitmap was reused, ensure density is reset
            outputBitmap.setDensity(Bitmap.getDefaultDensity());
        }
    }
}
