/*
 * Copyright (C) 2015 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.support.v17.leanback.graphics;

import android.support.annotation.RequiresApi;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.NonNull;
import android.util.IntProperty;
import android.util.Property;

/**
 * Subclass of {@link Drawable} that can be used to draw a bitmap into a region. Bitmap
 * will be scaled to fit the full width of the region and will be aligned to the top left corner.
 * Any region outside the bounds will be clipped during {@link #draw(Canvas)} call. Top
 * position of the bitmap can be controlled by {@link #setVerticalOffset(int)} call or
 * {@link #PROPERTY_VERTICAL_OFFSET}.
 */
public class FitWidthBitmapDrawable extends Drawable {

    static class BitmapState extends Drawable.ConstantState {
        Paint mPaint;
        Bitmap mBitmap;
        Rect mSource;
        final Rect mDefaultSource = new Rect();
        int mOffset;

        BitmapState() {
            mPaint = new Paint();
        }

        BitmapState(BitmapState other) {
            mBitmap = other.mBitmap;
            mPaint = new Paint(other.mPaint);
            mSource = other.mSource != null ? new Rect(other.mSource) : null;
            mDefaultSource.set(other.mDefaultSource);
            mOffset = other.mOffset;
        }

        @NonNull
        @Override
        public Drawable newDrawable() {
            return new FitWidthBitmapDrawable(this);
        }

        @Override
        public int getChangingConfigurations() {
            return 0;
        }
    }

    final Rect mDest = new Rect();
    BitmapState mBitmapState;
    boolean mMutated = false;

    public FitWidthBitmapDrawable() {
        mBitmapState = new BitmapState();
    }

    FitWidthBitmapDrawable(BitmapState state) {
        mBitmapState = state;
    }

    @Override
    public ConstantState getConstantState() {
        return mBitmapState;
    }

    @Override
    public Drawable mutate() {
        if (!mMutated && super.mutate() == this) {
            mBitmapState = new BitmapState(mBitmapState);
            mMutated = true;
        }
        return this;
    }

    /**
     * Sets the bitmap.
     */
    public void setBitmap(Bitmap bitmap) {
        mBitmapState.mBitmap = bitmap;
        if (bitmap != null) {
            mBitmapState.mDefaultSource.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
        } else {
            mBitmapState.mDefaultSource.set(0, 0, 0, 0);
        }
        mBitmapState.mSource = null;
    }

    /**
     * Returns the bitmap.
     */
    public Bitmap getBitmap() {
        return mBitmapState.mBitmap;
    }

    /**
     * Sets the {@link Rect} used for extracting the bitmap.
     */
    public void setSource(Rect source) {
        mBitmapState.mSource = source;
    }

    /**
     * Returns the {@link Rect} used for extracting the bitmap.
     */
    public Rect getSource() {
        return mBitmapState.mSource;
    }

    /**
     * Sets the vertical offset which will be used for drawing the bitmap. The bitmap drawing
     * will start the provided vertical offset.
     * @see #PROPERTY_VERTICAL_OFFSET
     */
    public void setVerticalOffset(int offset) {
        mBitmapState.mOffset = offset;
        invalidateSelf();
    }

    /**
     * Returns the current vertical offset.
     * @see #PROPERTY_VERTICAL_OFFSET
     */
    public int getVerticalOffset() {
        return mBitmapState.mOffset;
    }

    @Override
    public void draw(Canvas canvas) {
        if (mBitmapState.mBitmap != null) {
            Rect bounds = getBounds();
            mDest.left = 0;
            mDest.top = mBitmapState.mOffset;
            mDest.right = bounds.width();

            Rect source = validateSource();
            float scale = (float) bounds.width() / source.width();
            mDest.bottom = mDest.top + (int) (source.height() * scale);
            int i = canvas.save();
            canvas.clipRect(bounds);
            canvas.drawBitmap(mBitmapState.mBitmap, source, mDest, mBitmapState.mPaint);
            canvas.restoreToCount(i);
        }
    }

    @Override
    public void setAlpha(int alpha) {
        final int oldAlpha = mBitmapState.mPaint.getAlpha();
        if (alpha != oldAlpha) {
            mBitmapState.mPaint.setAlpha(alpha);
            invalidateSelf();
        }
    }

    /**
     * @return Alpha value between 0(inclusive) and 255(inclusive)
     */
    @Override
    public int getAlpha() {
        return mBitmapState.mPaint.getAlpha();
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        mBitmapState.mPaint.setColorFilter(colorFilter);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        final Bitmap bitmap = mBitmapState.mBitmap;
        return (bitmap == null || bitmap.hasAlpha() || mBitmapState.mPaint.getAlpha() < 255)
                ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
    }

    private Rect validateSource() {
        if (mBitmapState.mSource == null) {
            return mBitmapState.mDefaultSource;
        } else {
            return mBitmapState.mSource;
        }
    }

    /**
     * Property for {@link #setVerticalOffset(int)} and {@link #getVerticalOffset()}.
     */
    public static final Property<FitWidthBitmapDrawable, Integer> PROPERTY_VERTICAL_OFFSET;

    static {
        if (Build.VERSION.SDK_INT >= 24) {
            // use IntProperty
            PROPERTY_VERTICAL_OFFSET = getVerticalOffsetIntProperty();
        } else {
            // use Property
            PROPERTY_VERTICAL_OFFSET = new Property<FitWidthBitmapDrawable, Integer>(Integer.class,
                    "verticalOffset") {
                @Override
                public void set(FitWidthBitmapDrawable object, Integer value) {
                    object.setVerticalOffset(value);
                }

                @Override
                public Integer get(FitWidthBitmapDrawable object) {
                    return object.getVerticalOffset();
                }
            };
        }
    }

    @RequiresApi(24)
    static IntProperty<FitWidthBitmapDrawable> getVerticalOffsetIntProperty() {
        return new IntProperty<FitWidthBitmapDrawable>("verticalOffset") {
            @Override
            public void setValue(FitWidthBitmapDrawable fitWidthBitmapDrawable, int value) {
                fitWidthBitmapDrawable.setVerticalOffset(value);
            }

            @Override
            public Integer get(FitWidthBitmapDrawable fitWidthBitmapDrawable) {
                return fitWidthBitmapDrawable.getVerticalOffset();
            }
        };
    }
}
