package org.wikipedia.page;

import android.animation.ArgbEvaluator;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;

import org.wikipedia.R;
import org.wikipedia.WikipediaApp;
import org.wikipedia.util.DimenUtil;
import org.wikipedia.views.TabCountsView;

import static org.wikipedia.util.ResourceUtil.getThemedColor;

public class PageToolbarHideHandler extends ViewHideHandler {
    private static final int FULL_OPACITY = 255;

    private ArgbEvaluator argbEvaluator = new ArgbEvaluator();
    private boolean fadeEnabled;
    private boolean forceNoFade;
    @NonNull private PageFragment pageFragment;
    @NonNull private Toolbar toolbar;
    @NonNull private Drawable toolbarBackground;
    @NonNull private TabCountsView tabsButton;

    @ColorInt private int themedIconColor;
    @ColorInt private int baseStatusBarColor;
    @ColorInt private int themedStatusBarColor;

    public PageToolbarHideHandler(@NonNull PageFragment pageFragment, @NonNull View hideableView,
                                  @NonNull Toolbar toolbar, @NonNull TabCountsView tabsButton) {
        super(hideableView, null, Gravity.TOP);
        this.pageFragment = pageFragment;
        this.toolbar = toolbar;
        this.toolbarBackground = hideableView.getBackground().mutate();
        this.tabsButton = tabsButton;

        themedIconColor = getThemedColor(toolbar.getContext(), R.attr.page_toolbar_icon_color);
        baseStatusBarColor = getThemedColor(toolbar.getContext(), R.attr.page_expanded_status_bar_color);
        themedStatusBarColor = getThemedColor(toolbar.getContext(), R.attr.page_status_bar_color);
    }

    /**
     * Whether to enable fading in/out of the search bar when near the top of the article.
     * @param enabled True to enable fading, false otherwise.
     */
    public void setFadeEnabled(boolean enabled) {
        fadeEnabled = enabled;
        update();
    }

    /**
     * Whether to temporarily disable fading of the search bar, even if fading is enabled otherwise.
     * May be used when displaying a temporary UI element that requires the search bar to be shown
     * fully, e.g. when the ToC is pulled out.
     * @param force True to temporarily disable fading, false otherwise.
     */
    public void setForceNoFade(boolean force) {
        forceNoFade = force;
        update();
    }

    @Override
    protected void onScrolled(int oldScrollY, int scrollY) {
        tabsButton.setTabCount(WikipediaApp.getInstance().getTabCount());

        int opacity = calculateScrollOpacity(scrollY);
        toolbarBackground.setAlpha(opacity);
        updateChildIconTint(toolbar, opacity);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            pageFragment.requireActivity().getWindow()
                    .setStatusBarColor(calculateStatusBarTintForOpacity(opacity));
        }
    }

    /** @return Alpha value between 0 and 0xff. */
    private int calculateScrollOpacity(int scrollY) {
        final int fadeHeight = 200;
        int opacity = FULL_OPACITY;
        if (fadeEnabled && !forceNoFade) {
            opacity = scrollY * FULL_OPACITY / (int) (fadeHeight * DimenUtil.getDensityScalar());
        }
        opacity = Math.max(0, opacity);
        opacity = Math.min(FULL_OPACITY, opacity);
        return opacity;
    }

    private void updateChildIconTint(@NonNull ViewGroup viewGroup, float opacity) {
        int iconColor = calculateIconTintForOpacity(opacity);
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            View childView = viewGroup.getChildAt(i);
            if (childView instanceof ImageView) {
                Drawable icon = ((ImageView) childView).getDrawable();
                if (icon != null) {
                    icon.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN);
                }
            } else if (childView instanceof TabCountsView) {
                ((TabCountsView) childView).setColor(iconColor);
            } else if (childView instanceof ViewGroup) {
                updateChildIconTint((ViewGroup) childView, opacity);
            }
        }
        if (toolbar.getOverflowIcon() != null) {
            toolbar.getOverflowIcon().setColorFilter(iconColor, PorterDuff.Mode.SRC_IN);
        }
    }

    /** @return A @ColorInt value between R.attr.page_toolbar_icon_color) and Color.WHITE. */
    @ColorInt
    private int calculateIconTintForOpacity(float opacity) {
        return (Integer) argbEvaluator.evaluate(opacity / FULL_OPACITY, Color.WHITE,
                themedIconColor);
    }

    @ColorInt
    private int calculateStatusBarTintForOpacity(float opacity) {
        return (Integer) argbEvaluator.evaluate(opacity / FULL_OPACITY, baseStatusBarColor,
                themedStatusBarColor);
    }
}

@@ -847,41 +847,8 @@
 ed;%0A
-    private boolean forceNoFade;%0A
     
@@ -887,24 +887,24 @@
 geFragment;%0A
+
     @NonNull
@@ -1164,16 +1164,48 @@
 Color;%0A%0A
+    private int toolbarHeight;%0A%0A
     publ
@@ -1619,25 +1619,24 @@
 tabsButton;%0A
-%0A
         them
@@ -1920,24 +1920,109 @@
 bar_color);%0A
+        toolbarHeight = DimenUtil.getToolbarHeightPx(pageFragment.requireContext());%0A
     %7D%0A%0A    /
@@ -2181,39 +2181,32 @@
 se.%0A     */%0A    
-public 
 void setFadeEnab
@@ -2288,446 +2288,8 @@
  %7D%0A%0A
-    /**%0A     * Whether to temporarily disable fading of the search bar, even if fading is enabled otherwise.%0A     * May be used when displaying a temporary UI element that requires the search bar to be shown%0A     * fully, e.g. when the ToC is pulled out.%0A     * @param force True to temporarily disable fading, false otherwise.%0A     */%0A    public void setForceNoFade(boolean force) %7B%0A        forceNoFade = force;%0A        update();%0A    %7D%0A%0A
     
@@ -2460,41 +2460,113 @@
 y = 
-calculateScrollOpacity(scrollY)
+fadeEnabled && scrollY %3C (pageFragment.getHeaderView().getHeight() - toolbarHeight) ? 0 : FULL_OPACITY
 ;%0A
+%0A
     
@@ -2849,24 +2849,24 @@
 (opacity));%0A
+
         %7D%0A  
@@ -2874,458 +2874,8 @@
  %7D%0A%0A
-    /** @return Alpha value between 0 and 0xff. */%0A    private int calculateScrollOpacity(int scrollY) %7B%0A        final int fadeHeight = 200;%0A        int opacity = FULL_OPACITY;%0A        if (fadeEnabled && !forceNoFade) %7B%0A            opacity = scrollY * FULL_OPACITY / (int) (fadeHeight * DimenUtil.getDensityScalar());%0A        %7D%0A        opacity = Math.max(0, opacity);%0A        opacity = Math.min(FULL_OPACITY, opacity);%0A        return opacity;%0A    %7D%0A%0A
     

Remove corss-fading on toolbar and its icons.