// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.ntp;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v4.view.MarginLayoutParamsCompat;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.TraceEvent;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider;
import org.chromium.chrome.browser.explore_sites.ExperimentalExploreSitesSection;
import org.chromium.chrome.browser.locale.LocaleManager;
import org.chromium.chrome.browser.ntp.NewTabPage.OnSearchBoxScrollListener;
import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.suggestions.SiteSection;
import org.chromium.chrome.browser.suggestions.SiteSectionViewHolder;
import org.chromium.chrome.browser.suggestions.SuggestionsConfig;
import org.chromium.chrome.browser.suggestions.SuggestionsDependencyFactory;
import org.chromium.chrome.browser.suggestions.Tile;
import org.chromium.chrome.browser.suggestions.TileGridLayout;
import org.chromium.chrome.browser.suggestions.TileGroup;
import org.chromium.chrome.browser.suggestions.TileRenderer;
import org.chromium.chrome.browser.suggestions.TileView;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.util.MathUtils;
import org.chromium.chrome.browser.util.ViewUtils;
import org.chromium.chrome.browser.vr.VrModeObserver;
import org.chromium.chrome.browser.vr.VrModuleProvider;
import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
import org.chromium.ui.base.DeviceFormFactor;

/**
 * Layout for the new tab page. This positions the page elements in the correct vertical positions.
 * There are no separate phone and tablet UIs; this layout adapts based on the available space.
 */
public class NewTabPageLayout extends LinearLayout implements TileGroup.Observer, VrModeObserver {
    private static final String TAG = "NewTabPageLayout";

    /**
     * Parameter for the simplified NTP ablation experiment arm which removes the additional
     * suggestions sections without replacing them with shortcut buttons.
     */
    private static final String PARAM_SIMPLIFIED_NTP_ABLATION = "simplified_ntp_ablation";

    private final int mTileGridLayoutBleed;
    private final int mSearchboxShadowWidth;

    private View mMiddleSpacer; // Spacer between toolbar and Most Likely.

    private LogoView mSearchProviderLogoView;
    private View mSearchBoxView;
    private ViewGroup mSiteSectionView;
    private SiteSectionViewHolder mSiteSectionViewHolder;
    private ImageView mVoiceSearchButton;
    private View mTileGridPlaceholder;
    private View mNoSearchLogoSpacer;
    private ViewGroup mShortcutsView;

    @Nullable
    private View mExploreSectionView; // View is null if explore flag is disabled.
    @Nullable
    private ExperimentalExploreSitesSection mExploreSection; // Null when explore sites disabled.

    private OnSearchBoxScrollListener mSearchBoxScrollListener;

    private NewTabPageManager mManager;
    private Tab mTab;
    private LogoDelegateImpl mLogoDelegate;
    private TileGroup mTileGroup;
    private UiConfig mUiConfig;

    /**
     * Whether the tiles shown in the layout have finished loading.
     * With {@link #mHasShownView}, it's one of the 2 flags used to track initialisation progress.
     */
    private boolean mTilesLoaded;

    /**
     * Whether the view has been shown at least once.
     * With {@link #mTilesLoaded}, it's one of the 2 flags used to track initialization progress.
     */
    private boolean mHasShownView;

    private boolean mSearchProviderHasLogo = true;
    private boolean mSearchProviderIsGoogle;

    private boolean mInitialized;

    private float mUrlFocusChangePercent;
    private boolean mDisableUrlFocusChangeAnimations;
    private boolean mIsViewMoving;

    /** Flag used to request some layout changes after the next layout pass is completed. */
    private boolean mTileCountChanged;
    private boolean mSnapshotTileGridChanged;

    /**
     * Vertical inset to add to the top and bottom of the search box bounds. May be 0 if no inset
     * should be applied. See {@link Rect#inset(int, int)}.
     */
    private int mSearchBoxBoundsVerticalInset;

    private ScrollDelegate mScrollDelegate;

    /**
     * @return Whether the simplified NTP ablation experiment arm which removes the additional
     *         suggestions sections without replacing them with shortcut buttons is enabled.
     */
    public static boolean isSimplifiedNtpAblationEnabled() {
        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
                ChromeFeatureList.SIMPLIFIED_NTP, PARAM_SIMPLIFIED_NTP_ABLATION, false);
    }

    /**
     * A delegate used to obtain information about scroll state and perform various scroll
     * functions.
     */
    public interface ScrollDelegate {
        /**
         * @return Whether the scroll view is initialized. If false, the other delegate methods
         *         may not be valid.
         */
        boolean isScrollViewInitialized();

        /**
         * Checks whether the child at a given position is visible.
         * @param position The position of the child to check.
         * @return True if the child is at least partially visible.
         */
        boolean isChildVisibleAtPosition(int position);

        /**
         * @return The vertical scroll offset of the view containing this layout in pixels. Not
         *         valid until scroll view is initialized.
         */
        int getVerticalScrollOffset();

        /**
         * Snaps the scroll point of the scroll view to prevent the user from scrolling to midway
         * through a transition.
         */
        void snapScroll();
    }

    /**
     * Constructor for inflating from XML.
     */
    public NewTabPageLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        Resources res = getResources();
        mTileGridLayoutBleed = res.getDimensionPixelSize(R.dimen.tile_grid_layout_bleed);
        mSearchboxShadowWidth = res.getDimensionPixelOffset(R.dimen.ntp_search_box_shadow_width);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mMiddleSpacer = findViewById(R.id.ntp_middle_spacer);
        mSearchProviderLogoView = findViewById(R.id.search_provider_logo);
        mSearchBoxView = findViewById(R.id.search_box);
        insertSiteSectionView();
        if (ChromeFeatureList.isEnabled(ChromeFeatureList.EXPLORE_SITES)) {
            ViewStub exploreStub = findViewById(R.id.explore_sites_stub);
            mExploreSectionView = exploreStub.inflate();
        }
    }

    /**
     * Initializes the NewTabPageLayout. This must be called immediately after inflation, before
     * this object is used in any other way.
     *
     * @param manager NewTabPageManager used to perform various actions when the user interacts
     *                with the page.
     * @param tab The Tab that is showing this new tab page.
     * @param searchProviderHasLogo Whether the search provider has a logo.
     * @param searchProviderIsGoogle Whether the search provider is Google.
     * @param scrollDelegate The delegate used to obtain information about scroll state.
     * @param contextMenuManager The manager for long-press context menus.
     * @param uiConfig UiConfig that provides display information about this view.
     */
    public void initialize(NewTabPageManager manager, Tab tab, TileGroup.Delegate tileGroupDelegate,
            boolean searchProviderHasLogo, boolean searchProviderIsGoogle,
            ScrollDelegate scrollDelegate, ContextMenuManager contextMenuManager,
            UiConfig uiConfig) {
        TraceEvent.begin(TAG + ".initialize()");
        mScrollDelegate = scrollDelegate;
        mTab = tab;
        mManager = manager;
        mUiConfig = uiConfig;

        Profile profile = Profile.getLastUsedProfile();
        OfflinePageBridge offlinePageBridge =
                SuggestionsDependencyFactory.getInstance().getOfflinePageBridge(profile);
        TileRenderer tileRenderer =
                new TileRenderer(mTab.getActivity(), SuggestionsConfig.getTileStyle(mUiConfig),
                        getTileTitleLines(), mManager.getImageFetcher());
        mTileGroup = new TileGroup(tileRenderer, mManager, contextMenuManager, tileGroupDelegate,
                /* observer = */ this, offlinePageBridge);

        mSiteSectionViewHolder = SiteSection.createViewHolder(getSiteSectionView(), mUiConfig);
        mSiteSectionViewHolder.bindDataSource(mTileGroup, tileRenderer);

        if (ChromeFeatureList.isEnabled(ChromeFeatureList.EXPLORE_SITES)) {
            mExploreSection = new ExperimentalExploreSitesSection(
                    mExploreSectionView, profile, mManager.getNavigationDelegate());
        }

        mSearchProviderLogoView = findViewById(R.id.search_provider_logo);
        mLogoDelegate = new LogoDelegateImpl(
                mManager.getNavigationDelegate(), mSearchProviderLogoView, profile);

        mSearchBoxView = findViewById(R.id.search_box);
        if (SuggestionsConfig.useModernLayout()) {
            mSearchBoxView.setBackgroundResource(R.drawable.ntp_search_box);
            mSearchBoxView.getLayoutParams().height =
                    getResources().getDimensionPixelSize(R.dimen.ntp_search_box_height_modern);

            if (!DeviceFormFactor.isWindowOnTablet(mTab.getWindowAndroid())) {
                mSearchBoxBoundsVerticalInset = getResources().getDimensionPixelSize(
                        R.dimen.ntp_search_box_bounds_vertical_inset_modern);
            }
        }
        mNoSearchLogoSpacer = findViewById(R.id.no_search_logo_spacer);

        initializeShortcuts();
        initializeSearchBoxTextView();
        initializeVoiceSearchButton();
        initializeLayoutChangeListener();
        setSearchProviderInfo(searchProviderHasLogo, searchProviderIsGoogle);
        mSearchProviderLogoView.showSearchProviderInitialView();

        mTileGroup.startObserving(getMaxTileRows() * getMaxTileColumns());

        VrModuleProvider.registerVrModeObserver(this);
        if (VrModuleProvider.getDelegate().isInVr()) onEnterVr();

        manager.addDestructionObserver(NewTabPageLayout.this ::onDestroy);

        mInitialized = true;

        TraceEvent.end(TAG + ".initialize()");
    }

    /**
     * @return The {@link ScrollDelegate} for this class.
     */
    ScrollDelegate getScrollDelegate() {
        return mScrollDelegate;
    }

    /**
     * Sets up the hint text and event handlers for the search box text view.
     */
    private void initializeSearchBoxTextView() {
        TraceEvent.begin(TAG + ".initializeSearchBoxTextView()");

        final TextView searchBoxTextView = mSearchBoxView.findViewById(R.id.search_box_text);
        String hintText = getResources().getString(R.string.search_or_type_web_address);
        if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext())
                || SuggestionsConfig.useModernLayout()) {
            searchBoxTextView.setHint(hintText);
        } else {
            searchBoxTextView.setContentDescription(hintText);
        }
        searchBoxTextView.setOnClickListener(v -> mManager.focusSearchBox(false, null));
        searchBoxTextView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {}

            @Override
            public void afterTextChanged(Editable s) {
                if (s.length() == 0) return;
                mManager.focusSearchBox(false, s.toString());
                searchBoxTextView.setText("");
            }
        });
        TraceEvent.end(TAG + ".initializeSearchBoxTextView()");
    }

    /**
     * Updates the small search engine logo shown in the search box.
     */
    private void updateSearchBoxLogo() {
        TextView searchBoxTextView = mSearchBoxView.findViewById(R.id.search_box_text);
        LocaleManager localeManager = LocaleManager.getInstance();
        if (mSearchProviderIsGoogle && !localeManager.hasCompletedSearchEnginePromo()
                && !localeManager.hasShownSearchEnginePromoThisSession()
                && ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SHOW_GOOGLE_G_IN_OMNIBOX)) {
            searchBoxTextView.setCompoundDrawablePadding(
                    getResources().getDimensionPixelOffset(R.dimen.ntp_search_box_logo_padding));
            ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
                    searchBoxTextView, R.drawable.ic_logo_googleg_24dp, 0, 0, 0);
        } else {
            searchBoxTextView.setCompoundDrawablePadding(0);

            // Not using the relative version of this call because we only want to clear
            // the drawables.
            searchBoxTextView.setCompoundDrawables(null, null, null, null);
        }
    }

    private void initializeVoiceSearchButton() {
        TraceEvent.begin(TAG + ".initializeVoiceSearchButton()");
        mVoiceSearchButton = findViewById(R.id.voice_search_button);
        mVoiceSearchButton.setOnClickListener(v -> mManager.focusSearchBox(true, null));

        if (SuggestionsConfig.useModernLayout()
                && !DeviceFormFactor.isWindowOnTablet(mTab.getWindowAndroid())) {
            MarginLayoutParamsCompat.setMarginEnd(
                    (MarginLayoutParams) mVoiceSearchButton.getLayoutParams(),
                    getResources().getDimensionPixelSize(
                            R.dimen.ntp_search_box_voice_search_margin_end_modern));
        }

        TraceEvent.end(TAG + ".initializeVoiceSearchButton()");
    }

    private void initializeLayoutChangeListener() {
        TraceEvent.begin(TAG + ".initializeLayoutChangeListener()");
        addOnLayoutChangeListener(
                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
                    int oldHeight = oldBottom - oldTop;
                    int newHeight = bottom - top;

                    if (oldHeight == newHeight && !mTileCountChanged) return;
                    mTileCountChanged = false;

                    // Re-apply the url focus change amount after a rotation to ensure the views are
                    // correctly placed with their new layout configurations.
                    onUrlFocusAnimationChanged();
                    updateSearchBoxOnScroll();

                    // The positioning of elements may have been changed (since the elements expand
                    // to fill the available vertical space), so adjust the scroll.
                    mScrollDelegate.snapScroll();
                });
        TraceEvent.end(TAG + ".initializeLayoutChangeListener()");
    }

    /**
     * Updates the search box when the parent view's scroll position is changed.
     */
    void updateSearchBoxOnScroll() {
        if (mDisableUrlFocusChangeAnimations || mIsViewMoving) return;

        // When the page changes (tab switching or new page loading), it is possible that events
        // (e.g. delayed view change notifications) trigger calls to these methods after
        // the current page changes. We check it again to make sure we don't attempt to update the
        // wrong page.
        if (!mManager.isCurrentPage()) return;

        if (mSearchBoxScrollListener != null) {
            mSearchBoxScrollListener.onNtpScrollChanged(getToolbarTransitionPercentage());
        }
    }

    /**
     * Calculates the percentage (between 0 and 1) of the transition from the search box to the
     * omnibox at the top of the New Tab Page, which is determined by the amount of scrolling and
     * the position of the search box.
     *
     * @return the transition percentage
     */
    private float getToolbarTransitionPercentage() {
        // During startup the view may not be fully initialized.
        if (!mScrollDelegate.isScrollViewInitialized()) return 0f;

        if (!mScrollDelegate.isChildVisibleAtPosition(0)) {
            // getVerticalScrollOffset is valid only for the scroll view if the first item is
            // visible. If the first item is not visible, we must have scrolled quite far and we
            // know the toolbar transition should be 100%. This might be the initial scroll position
            // due to the scroll restore feature, so the search box will not have been laid out yet.
            return 1f;
        }

        // During startup the view may not be fully initialized, so we only calculate the current
        // percentage if some basic view properties (position of the search box) are sane.
        int searchBoxTop = mSearchBoxView.getTop();
        if (searchBoxTop == 0) return 0f;

        // For all other calculations, add the search box padding, because it defines where the
        // visible "border" of the search box is.
        searchBoxTop += mSearchBoxView.getPaddingTop();

        final int scrollY = mScrollDelegate.getVerticalScrollOffset();
        // Use int pixel size instead of float dimension to avoid precision error on the percentage.
        final float transitionLength =
                getResources().getDimensionPixelSize(R.dimen.ntp_search_box_transition_length);
        // Tab strip height is zero on phones, nonzero on tablets.
        int tabStripHeight = getResources().getDimensionPixelSize(R.dimen.tab_strip_height);

        // |scrollY - searchBoxTop + tabStripHeight| gives the distance the search bar is from the
        // top of the tab.
        return MathUtils.clamp(
                (scrollY - searchBoxTop + tabStripHeight + transitionLength) / transitionLength, 0f,
                1f);
    }

    private void insertSiteSectionView() {
        mSiteSectionView = SiteSection.inflateSiteSection(this);
        ViewGroup.LayoutParams layoutParams = mSiteSectionView.getLayoutParams();
        layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
        mSiteSectionView.setLayoutParams(layoutParams);

        int insertionPoint = indexOfChild(mMiddleSpacer) + 1;
        addView(mSiteSectionView, insertionPoint);
    }

    /**
     * @return the embedded {@link TileGridLayout}.
     */
    public ViewGroup getSiteSectionView() {
        return mSiteSectionView;
    }

    /**
     * @return The fake search box view.
     */
    public View getSearchBoxView() {
        return mSearchBoxView;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        unifyElementWidths();
    }

    /**
     * @return The placeholder that is shown above the fold when there is no other content to show,
     *         or null if it has not been inflated yet.
     */
    @VisibleForTesting
    @Nullable
    public View getPlaceholder() {
        return mTileGridPlaceholder;
    }

    @VisibleForTesting
    public TileGroup getTileGroup() {
        return mTileGroup;
    }

    /**
     * Should be called every time one of the flags used to track initialization progress changes.
     * Finalizes initialization once all the preliminary steps are complete.
     *
     * @see #mHasShownView
     * @see #mTilesLoaded
     */
    private void onInitializationProgressChanged() {
        if (!hasLoadCompleted()) return;

        mManager.onLoadingComplete();

        // Load the logo after everything else is finished, since it's lower priority.
        loadSearchProviderLogo();
    }

    /**
     * To be called to notify that the tiles have finished loading. Will do nothing if a load was
     * previously completed.
     */
    public void onTilesLoaded() {
        if (mTilesLoaded) return;
        mTilesLoaded = true;

        onInitializationProgressChanged();
    }

    /**
     * Loads the search provider logo (e.g. Google doodle), if any.
     */
    public void loadSearchProviderLogo() {
        if (!mSearchProviderHasLogo) return;

        mSearchProviderLogoView.showSearchProviderInitialView();

        mLogoDelegate.getSearchProviderLogo((logo, fromCache) -> {
            if (logo == null && fromCache) return;

            mSearchProviderLogoView.setDelegate(mLogoDelegate);
            mSearchProviderLogoView.updateLogo(logo);
            mSnapshotTileGridChanged = true;
        });
    }

    /**
     * Changes the layout depending on whether the selected search provider (e.g. Google, Bing)
     * has a logo.
     * @param hasLogo Whether the search provider has a logo.
     * @param isGoogle Whether the search provider is Google.
     */
    public void setSearchProviderInfo(boolean hasLogo, boolean isGoogle) {
        if (hasLogo == mSearchProviderHasLogo && isGoogle == mSearchProviderIsGoogle
                && mInitialized) {
            return;
        }
        mSearchProviderHasLogo = hasLogo;
        mSearchProviderIsGoogle = isGoogle;

        updateTileGridPadding();

        // Hide or show the views above the tile grid as needed, including logo, search box, and
        // spacers.
        int visibility = mSearchProviderHasLogo ? View.VISIBLE : View.GONE;
        int logoVisibility = shouldShowLogo() ? View.VISIBLE : View.GONE;
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (mShortcutsView != null && child == mShortcutsView) break;
            if (child == mSiteSectionViewHolder.itemView) break;

            // Don't change the visibility of a ViewStub as that will automagically inflate it.
            if (child instanceof ViewStub) continue;

            if (child == mSearchProviderLogoView) {
                child.setVisibility(logoVisibility);
            } else {
                child.setVisibility(visibility);
            }
        }

        updateTileGridPlaceholderVisibility();

        onUrlFocusAnimationChanged();

        updateSearchBoxLogo();

        mSnapshotTileGridChanged = true;
    }

    /**
     * Updates the padding for the tile grid based on what is shown above it.
     */
    private void updateTileGridPadding() {
        int paddingTop;
        if (mShortcutsView != null) {
            // If the shortcuts view is visible, padding will be built into that view.
            paddingTop = 0;
        } else {
            int paddingWithLogoId = SuggestionsConfig.useModernLayout()
                    ? R.dimen.tile_grid_layout_modern_padding_top
                    : R.dimen.tile_grid_layout_padding_top;
            // Set a bit more top padding on the tile grid if there is no logo.
            paddingTop = getResources().getDimensionPixelSize(shouldShowLogo()
                            ? paddingWithLogoId
                            : R.dimen.tile_grid_layout_no_logo_padding_top);
        }

        mSiteSectionViewHolder.itemView.setPadding(
                0, paddingTop, 0, mSiteSectionViewHolder.itemView.getPaddingBottom());
    }

    /**
     * Updates whether the NewTabPage should animate on URL focus changes.
     * @param disable Whether to disable the animations.
     */
    void setUrlFocusAnimationsDisabled(boolean disable) {
        if (disable == mDisableUrlFocusChangeAnimations) return;
        mDisableUrlFocusChangeAnimations = disable;
        if (!disable) onUrlFocusAnimationChanged();
    }

    /**
     * @return Whether URL focus animations are currently disabled.
     */
    boolean urlFocusAnimationsDisabled() {
        return mDisableUrlFocusChangeAnimations;
    }

    /**
     * Specifies the percentage the URL is focused during an animation.  1.0 specifies that the URL
     * bar has focus and has completed the focus animation.  0 is when the URL bar is does not have
     * any focus.
     *
     * @param percent The percentage of the URL bar focus animation.
     */
    void setUrlFocusChangeAnimationPercent(float percent) {
        mUrlFocusChangePercent = percent;
        onUrlFocusAnimationChanged();
    }

    /**
     * @return The percentage that the URL bar is focused during an animation.
     */
    @VisibleForTesting
    float getUrlFocusChangeAnimationPercent() {
        return mUrlFocusChangePercent;
    }

    void onUrlFocusAnimationChanged() {
        if (mDisableUrlFocusChangeAnimations || mIsViewMoving) return;

        // Translate so that the search box is at the top, but only upwards.
        float percent = mSearchProviderHasLogo ? mUrlFocusChangePercent : 0;
        int basePosition = mScrollDelegate.getVerticalScrollOffset() + getPaddingTop();
        int target = Math.max(basePosition,
                mSearchBoxView.getBottom() - mSearchBoxView.getPaddingBottom()
                        - mSearchBoxBoundsVerticalInset);

        setTranslationY(percent * (basePosition - target));
    }

    /**
     * Sets whether this view is currently moving within its parent view. When the view is moving
     * certain animations will be disabled or prevented.
     * @param isViewMoving Whether this view is currently moving.
     */
    void setIsViewMoving(boolean isViewMoving) {
        mIsViewMoving = isViewMoving;
    }

    /**
     * Updates the opacity of the search box when scrolling.
     *
     * @param alpha opacity (alpha) value to use.
     */
    public void setSearchBoxAlpha(float alpha) {
        mSearchBoxView.setAlpha(alpha);

        // Disable the search box contents if it is the process of being animated away.
        ViewUtils.setEnabledRecursive(mSearchBoxView, mSearchBoxView.getAlpha() == 1.0f);
    }

    /**
     * Updates the opacity of the search provider logo when scrolling.
     *
     * @param alpha opacity (alpha) value to use.
     */
    public void setSearchProviderLogoAlpha(float alpha) {
        mSearchProviderLogoView.setAlpha(alpha);
    }

    /**
     * Set the search box background drawable.
     *
     * @param drawable The search box background.
     */
    public void setSearchBoxBackground(Drawable drawable) {
        mSearchBoxView.setBackground(drawable);
    }

    /**
     * Get the bounds of the search box in relation to the top level {@code parentView}.
     *
     * @param bounds The current drawing location of the search box.
     * @param translation The translation applied to the search box by the parent view hierarchy up
     *                    to the {@code parentView}.
     * @param parentView The top level parent view used to translate search box bounds.
     */
    void getSearchBoxBounds(Rect bounds, Point translation, View parentView) {
        int searchBoxX = (int) mSearchBoxView.getX();
        int searchBoxY = (int) mSearchBoxView.getY();
        bounds.set(searchBoxX + mSearchBoxView.getPaddingLeft(),
                searchBoxY + mSearchBoxView.getPaddingTop(),
                searchBoxX + mSearchBoxView.getWidth() - mSearchBoxView.getPaddingRight(),
                searchBoxY + mSearchBoxView.getHeight() - mSearchBoxView.getPaddingBottom());

        translation.set(0, 0);

        View view = mSearchBoxView;
        while (true) {
            view = (View) view.getParent();
            if (view == null) {
                // The |mSearchBoxView| is not a child of this view. This can happen if the
                // RecyclerView detaches the NewTabPageLayout after it has been scrolled out of
                // view. Set the translation to the minimum Y value as an approximation.
                translation.y = Integer.MIN_VALUE;
                break;
            }
            translation.offset(-view.getScrollX(), -view.getScrollY());
            if (view == parentView) break;
            translation.offset((int) view.getX(), (int) view.getY());
        }
        bounds.offset(translation.x, translation.y);

        if (translation.y != Integer.MIN_VALUE) {
            bounds.inset(0, mSearchBoxBoundsVerticalInset);
        }
    }

    /**
     * Sets the listener for search box scroll changes.
     * @param listener The listener to be notified on changes.
     */
    void setSearchBoxScrollListener(OnSearchBoxScrollListener listener) {
        mSearchBoxScrollListener = listener;
        if (mSearchBoxScrollListener != null) updateSearchBoxOnScroll();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        assert mManager != null;

        if (!mHasShownView) {
            mHasShownView = true;
            onInitializationProgressChanged();
            NewTabPageUma.recordSearchAvailableLoadTime(mTab.getActivity());
            TraceEvent.instant("NewTabPageSearchAvailable)");
        }
    }

    /**
     * Update the visibility of the voice search button based on whether the feature is currently
     * enabled.
     */
    void updateVoiceSearchButtonVisibility() {
        mVoiceSearchButton.setVisibility(mManager.isVoiceSearchEnabled() ? VISIBLE : GONE);
    }

    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);

        // On first run, the NewTabPageLayout is initialized behind the First Run Experience,
        // meaning the UiConfig will pickup the screen layout then. However onConfigurationChanged
        // is not called on orientation changes until the FRE is completed. This means that if a
        // user starts the FRE in one orientation, changes an orientation and then leaves the FRE
        // the UiConfig will have the wrong orientation. https://crbug.com/683886.
        mUiConfig.updateDisplayStyle();

        if (visibility == VISIBLE) {
            updateVoiceSearchButtonVisibility();
        }
    }

    /**
     * @see InvalidationAwareThumbnailProvider#shouldCaptureThumbnail()
     */
    public boolean shouldCaptureThumbnail() {
        return mSnapshotTileGridChanged;
    }

    /**
     * Should be called before a thumbnail of the parent view is captured.
     * @see InvalidationAwareThumbnailProvider#captureThumbnail(Canvas)
     */
    public void onPreCaptureThumbnail() {
        mSearchProviderLogoView.endFadeAnimation();
        mSnapshotTileGridChanged = false;
    }

    /**
     * Shows the most visited placeholder ("Nothing to see here") if there are no most visited
     * items and there is no search provider logo.
     */
    private void updateTileGridPlaceholderVisibility() {
        boolean showPlaceholder =
                mTileGroup.hasReceivedData() && mTileGroup.isEmpty() && !mSearchProviderHasLogo;

        mNoSearchLogoSpacer.setVisibility(
                (mSearchProviderHasLogo || showPlaceholder) ? View.GONE : View.INVISIBLE);

        mSiteSectionViewHolder.itemView.setVisibility(showPlaceholder ? GONE : VISIBLE);

        if (showPlaceholder) {
            if (mTileGridPlaceholder == null) {
                ViewStub placeholderStub = findViewById(R.id.tile_grid_placeholder_stub);
                mTileGridPlaceholder = placeholderStub.inflate();
            }
            mTileGridPlaceholder.setVisibility(VISIBLE);
        } else if (mTileGridPlaceholder != null) {
            mTileGridPlaceholder.setVisibility(GONE);
        }
    }

    private static int getMaxTileRows() {
        return 2;
    }

    /**
     * Determines The maximum number of tiles to try and fit in a row. On smaller screens, there
     * may not be enough space to fit all of them.
     */
    private int getMaxTileColumns() {
        if (!mUiConfig.getCurrentDisplayStyle().isSmall()
                && SuggestionsConfig.getTileStyle(mUiConfig) == TileView.Style.CLASSIC_CONDENSED) {
            return 5;
        }
        return 4;
    }

    private static int getTileTitleLines() {
        return 1;
    }

    private boolean shouldShowLogo() {
        return mSearchProviderHasLogo;
    }

    private boolean hasLoadCompleted() {
        return mHasShownView && mTilesLoaded;
    }

    // TileGroup.Observer interface.

    @Override
    public void onTileDataChanged() {
        mSiteSectionViewHolder.refreshData();
        mSnapshotTileGridChanged = true;

        // The page contents are initially hidden; otherwise they'll be drawn centered on the page
        // before the tiles are available and then jump upwards to make space once the tiles are
        // available.
        if (getVisibility() != View.VISIBLE) setVisibility(View.VISIBLE);
    }

    @Override
    public void onTileCountChanged() {
        // If the number of tile rows change while the URL bar is focused, the icons'
        // position will be wrong. Schedule the translation to be updated.
        if (mUrlFocusChangePercent == 1f) mTileCountChanged = true;
        updateTileGridPlaceholderVisibility();
    }

    @Override
    public void onTileIconChanged(Tile tile) {
        mSiteSectionViewHolder.updateIconView(tile);
        mSnapshotTileGridChanged = true;
    }

    @Override
    public void onTileOfflineBadgeVisibilityChanged(Tile tile) {
        mSiteSectionViewHolder.updateOfflineBadge(tile);
        mSnapshotTileGridChanged = true;
    }

    @Override
    public void onEnterVr() {
        mSearchBoxView.setVisibility(GONE);
    }

    @Override
    public void onExitVr() {
        mSearchBoxView.setVisibility(VISIBLE);
    }

    private void onDestroy() {
        VrModuleProvider.unregisterVrModeObserver(this);
    }

    private void initializeShortcuts() {
        if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SIMPLIFIED_NTP)
                || isSimplifiedNtpAblationEnabled()) {
            return;
        }

        ViewStub shortcutsStub = findViewById(R.id.shortcuts_stub);
        mShortcutsView = (ViewGroup) shortcutsStub.inflate();

        mShortcutsView.findViewById(R.id.bookmarks_button)
                .setOnClickListener(view -> mManager.getNavigationDelegate().navigateToBookmarks());

        mShortcutsView.findViewById(R.id.downloads_button)
                .setOnClickListener(
                        view -> mManager.getNavigationDelegate().navigateToDownloadManager());
    }

    /**
     * Makes the Search Box and Logo as wide as Most Visited.
     */
    private void unifyElementWidths() {
        if (mSiteSectionView.getVisibility() != GONE) {
            final int width = mSiteSectionView.getMeasuredWidth() - mTileGridLayoutBleed;
            measureExactly(mSearchBoxView,
                    width + mSearchboxShadowWidth, mSearchBoxView.getMeasuredHeight());
            measureExactly(mSearchProviderLogoView,
                    width, mSearchProviderLogoView.getMeasuredHeight());
        } else if (mExploreSectionView != null) {
            final int exploreWidth = mExploreSectionView.getMeasuredWidth() - mTileGridLayoutBleed;
            measureExactly(mSearchBoxView, exploreWidth + mSearchboxShadowWidth,
                    mSearchBoxView.getMeasuredHeight());
            measureExactly(mSearchProviderLogoView, exploreWidth,
                    mSearchProviderLogoView.getMeasuredHeight());
        }
    }

    /**
     * Convenience method to call measure() on the given View with MeasureSpecs converted from the
     * given dimensions (in pixels) with MeasureSpec.EXACTLY.
     */
    private static void measureExactly(View view, int widthPx, int heightPx) {
        view.measure(MeasureSpec.makeMeasureSpec(widthPx, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(heightPx, MeasureSpec.EXACTLY));
    }

    /**
     * Provides the additional capabilities needed for the SearchBox container layout.
     */
    public static class SearchBoxContainerView extends LinearLayout {
        /** Constructor for inflating from XML. */
        public SearchBoxContainerView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
                    && ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
                if (getBackground() instanceof RippleDrawable) {
                    ((RippleDrawable) getBackground()).setHotspot(ev.getX(), ev.getY());
                }
            }
            return super.onInterceptTouchEvent(ev);
        }
    }
}
