/*
 * Copyright (C) 2014 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.systemui.statusbar;

import static java.lang.Float.isNaN;

import android.annotation.NonNull;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

import androidx.core.graphics.ColorUtils;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.drawable.ScrimDrawable;

/**
 * A view which can draw a scrim
 */
public class ScrimView extends View {
    private final ColorExtractor.GradientColors mColors;
    private float mViewAlpha = 1.0f;
    private Drawable mDrawable;
    private PorterDuffColorFilter mColorFilter;
    private int mTintColor;
    private Runnable mChangeRunnable;

    public ScrimView(Context context) {
        this(context, null);
    }

    public ScrimView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScrimView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        mDrawable = new ScrimDrawable();
        mDrawable.setCallback(this);
        mColors = new ColorExtractor.GradientColors();
        updateColorWithTint(false);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawable.getAlpha() > 0) {
            mDrawable.draw(canvas);
        }
    }

    public void setDrawable(Drawable drawable) {
        mDrawable = drawable;
        mDrawable.setCallback(this);
        mDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom());
        mDrawable.setAlpha((int) (255 * mViewAlpha));
        invalidate();
    }

    @Override
    public void invalidateDrawable(@NonNull Drawable drawable) {
        super.invalidateDrawable(drawable);
        if (drawable == mDrawable) {
            invalidate();
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed) {
            mDrawable.setBounds(left, top, right, bottom);
            invalidate();
        }
    }

    public void setColors(@NonNull ColorExtractor.GradientColors colors) {
        setColors(colors, false);
    }

    public void setColors(@NonNull ColorExtractor.GradientColors colors, boolean animated) {
        if (colors == null) {
            throw new IllegalArgumentException("Colors cannot be null");
        }
        if (mColors.equals(colors)) {
            return;
        }
        mColors.set(colors);
        updateColorWithTint(animated);
    }

    @VisibleForTesting
    Drawable getDrawable() {
        return mDrawable;
    }

    public ColorExtractor.GradientColors getColors() {
        return mColors;
    }

    public void setTint(int color) {
        setTint(color, false);
    }

    public void setTint(int color, boolean animated) {
        if (mTintColor == color) {
            return;
        }
        mTintColor = color;
        updateColorWithTint(animated);
    }

    private void updateColorWithTint(boolean animated) {
        if (mDrawable instanceof ScrimDrawable) {
            // Optimization to blend colors and avoid a color filter
            ScrimDrawable drawable = (ScrimDrawable) mDrawable;
            float tintAmount = Color.alpha(mTintColor) / 255f;
            int mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), mTintColor,
                    tintAmount);
            drawable.setColor(mainTinted, animated);
        } else {
            boolean hasAlpha = Color.alpha(mTintColor) != 0;
            if (hasAlpha) {
                PorterDuff.Mode targetMode = mColorFilter == null ? Mode.SRC_OVER :
                    mColorFilter.getMode();
                if (mColorFilter == null || mColorFilter.getColor() != mTintColor) {
                    mColorFilter = new PorterDuffColorFilter(mTintColor, targetMode);
                }
            } else {
                mColorFilter = null;
            }

            mDrawable.setColorFilter(mColorFilter);
            mDrawable.invalidateSelf();
        }

        if (mChangeRunnable != null) {
            mChangeRunnable.run();
        }
    }

    public int getTint() {
        return mTintColor;
    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
    }

    /**
     * It might look counterintuitive to have another method to set the alpha instead of
     * only using {@link #setAlpha(float)}. In this case we're in a hardware layer
     * optimizing blend modes, so it makes sense.
     *
     * @param alpha Gradient alpha from 0 to 1.
     */
    public void setViewAlpha(float alpha) {
        if (isNaN(alpha)) {
            throw new IllegalArgumentException("alpha cannot be NaN: " + alpha);
        }
        if (alpha != mViewAlpha) {
            mViewAlpha = alpha;

            mDrawable.setAlpha((int) (255 * alpha));
            if (mChangeRunnable != null) {
                mChangeRunnable.run();
            }
        }
    }

    public float getViewAlpha() {
        return mViewAlpha;
    }

    public void setChangeRunnable(Runnable changeRunnable) {
        mChangeRunnable = changeRunnable;
    }

    @Override
    protected boolean canReceivePointerEvents() {
        return false;
    }
}
