/*
 * Copyright (C) 2018 xuexiangjys(xuexiangjys@163.com)
 *
 * 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.xuexiang.xui.widget.progress.materialprogressbar;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.util.Log;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.xuexiang.xui.R;
import com.xuexiang.xui.utils.ThemeUtils;

class BaseProgressLayerDrawable<
        ProgressDrawableType extends IntrinsicPaddingDrawable & ShowBackgroundDrawable
                & TintableDrawable, BackgroundDrawableType extends IntrinsicPaddingDrawable
                & ShowBackgroundDrawable & TintableDrawable>
        extends LayerDrawable implements IntrinsicPaddingDrawable, MaterialProgressDrawable,
        ShowBackgroundDrawable, TintableDrawable {

    private float mBackgroundAlpha;

    private BackgroundDrawableType mBackgroundDrawable;
    private ProgressDrawableType mSecondaryProgressDrawable;
    private ProgressDrawableType mProgressDrawable;

    public BaseProgressLayerDrawable(Drawable[] layers, Context context) {
        super(layers);

        mBackgroundAlpha = ThemeUtils.resolveFloat(context, android.R.attr.disabledAlpha, 0);

        setId(0, android.R.id.background);
        //noinspection unchecked
        mBackgroundDrawable = (BackgroundDrawableType) getDrawable(0);
        setId(1, android.R.id.secondaryProgress);
        //noinspection unchecked
        mSecondaryProgressDrawable = (ProgressDrawableType) getDrawable(1);
        setId(2, android.R.id.progress);
        //noinspection unchecked
        mProgressDrawable = (ProgressDrawableType) getDrawable(2);

        int controlActivatedColor = ThemeUtils.getColorFromAttrRes(com.google.android.material.R.attr.colorControlActivated,
                Color.BLACK, context);
        setTint(controlActivatedColor);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean getShowBackground() {
        return mBackgroundDrawable.getShowBackground();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setShowBackground(boolean show) {
        if (mBackgroundDrawable.getShowBackground() != show) {
            mBackgroundDrawable.setShowBackground(show);
            mSecondaryProgressDrawable.setShowBackground(!show);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean getUseIntrinsicPadding() {
        return mBackgroundDrawable.getUseIntrinsicPadding();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setUseIntrinsicPadding(boolean useIntrinsicPadding) {
        mBackgroundDrawable.setUseIntrinsicPadding(useIntrinsicPadding);
        mSecondaryProgressDrawable.setUseIntrinsicPadding(useIntrinsicPadding);
        mProgressDrawable.setUseIntrinsicPadding(useIntrinsicPadding);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setTint(@ColorInt int tintColor) {
        // Modulate alpha of tintColor against mBackgroundAlpha.
        int backgroundTintColor = androidx.core.graphics.ColorUtils.setAlphaComponent(
                tintColor, Math.round(Color.alpha(tintColor) * mBackgroundAlpha));
        mBackgroundDrawable.setTint(backgroundTintColor);
        mSecondaryProgressDrawable.setTint(backgroundTintColor);
        mProgressDrawable.setTint(tintColor);
    }

    /**
     * {@inheritDoc}
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void setTintList(@Nullable ColorStateList tint) {
        ColorStateList backgroundTint;
        if (tint != null) {
            if (!tint.isOpaque()) {
                Log.w(getClass().getSimpleName(), "setTintList() called with a non-opaque" +
                        " ColorStateList, its original alpha will be discarded");
            }
            backgroundTint = tint.withAlpha(Math.round(0xFF * mBackgroundAlpha));
        } else {
            backgroundTint = null;
        }
        mBackgroundDrawable.setTintList(backgroundTint);
        mSecondaryProgressDrawable.setTintList(backgroundTint);
        mProgressDrawable.setTintList(tint);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setTintMode(@NonNull PorterDuff.Mode tintMode) {
        mBackgroundDrawable.setTintMode(tintMode);
        mSecondaryProgressDrawable.setTintMode(tintMode);
        mProgressDrawable.setTintMode(tintMode);
    }
}
