// 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.omnibox;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.TouchDelegate;
import android.view.View;
import android.widget.FrameLayout;

import org.chromium.base.TraceEvent;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.ui.interpolators.BakedBezierInterpolator;

import java.util.List;

/**
 * A location bar implementation specific for smaller/phone screens.
 */
public class LocationBarPhone extends LocationBarLayout implements LocationBar.Phone {
    private static final int ACTION_BUTTON_TOUCH_OVERFLOW_LEFT = 15;

    private View mFirstVisibleFocusedView;
    private View mUrlBar;
    private View mStatusView;

    /**
     * Constructor used to inflate from XML.
     */
    public LocationBarPhone(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        mUrlBar = findViewById(R.id.url_bar);
        mStatusView = findViewById(R.id.location_bar_status);
        // Assign the first visible view here only if it hasn't been set by the DSE icon experiment.
        // See onNativeLibrary ready for when this variable is set for the DSE icon case.
        mFirstVisibleFocusedView =
                mFirstVisibleFocusedView == null ? mUrlBar : mFirstVisibleFocusedView;

        Rect delegateArea = new Rect();
        mUrlActionContainer.getHitRect(delegateArea);
        delegateArea.left -= ACTION_BUTTON_TOUCH_OVERFLOW_LEFT;
        TouchDelegate touchDelegate = new TouchDelegate(delegateArea, mUrlActionContainer);
        assert mUrlActionContainer.getParent() == this;
        mCompositeTouchDelegate.addDelegateForDescendantView(touchDelegate);
    }

    @Override
    protected void updateSearchEngineStatusIcon(boolean shouldShowSearchEngineLogo,
            boolean isSearchEngineGoogle, String searchEngineUrl) {
        super.updateSearchEngineStatusIcon(
                shouldShowSearchEngineLogo, isSearchEngineGoogle, searchEngineUrl);

        // The search engine icon will be the first visible focused view when it's showing.
        shouldShowSearchEngineLogo = SearchEngineLogoUtils.shouldShowSearchEngineLogo(
                getToolbarDataProvider().isIncognito());

        // This branch will be hit if the search engine logo experiment is enabled.
        if (SearchEngineLogoUtils.isSearchEngineLogoEnabled()) {
            // Setup the padding once we're loaded, the focused padding changes will happen with
            // post-layout positioning via setTranslation. This is a byproduct of the way we do the
            // omnibox un/focus animation which is by writing a function f(x) where x ranges from
            // 0 (totally unfocused) to 1 (totally focused). Positioning the location bar and it's
            // children this way doesn't affect the views' bounds (including hit rect). But these
            // hit rects are preserved for the views that matter (the icon and the url actions
            // container).
            int lateralPadding = getResources().getDimensionPixelOffset(
                    R.dimen.sei_location_bar_lateral_padding);
            setPaddingRelative(lateralPadding, getPaddingTop(), lateralPadding, getPaddingBottom());
        }

        // This branch will be hit if the search engine logo experiment is enabled and we should
        // show the logo.
        if (shouldShowSearchEngineLogo) {
            // When the search engine icon is enabled, icons are translations into the parent view's
            // padding area. Set clip padding to false to prevent them from getting clipped.
            setClipToPadding(false);
        }
        setShowIconsWhenUrlFocused(shouldShowSearchEngineLogo);
    }

    /**
     * @return Width of child views before the first view that would be visible when location bar is
     *         focused. The first visible, focused view should be either url bar or status icon.
     */
    @Override
    public int getOffsetOfFirstVisibleFocusedView() {
        int visibleWidth = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            if (child == mFirstVisibleFocusedView) break;
            if (child.getVisibility() == GONE) continue;
            visibleWidth += child.getMeasuredWidth();
        }
        return visibleWidth;
    }

    /**
     * Populates fade animators of status icon for location bar focus change animation.
     * @param animators The target list to add animators to.
     * @param startDelayMs Start delay of fade animation in milliseconds.
     * @param durationMs Duration of fade animation in milliseconds.
     * @param targetAlpha Target alpha value.
     */
    @Override
    public void populateFadeAnimations(
            List<Animator> animators, long startDelayMs, long durationMs, float targetAlpha) {
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            if (child == mFirstVisibleFocusedView) break;
            Animator animator = ObjectAnimator.ofFloat(child, ALPHA, targetAlpha);
            animator.setStartDelay(startDelayMs);
            animator.setDuration(durationMs);
            animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
            animators.add(animator);
        }
    }

    /**
     * Calculates the offset required for the focused LocationBar to appear as it's still unfocused
     * so it can animate to a focused state.
     *
     * @param hasFocus True if the LocationBar has focus, this will be true between the focus
     *                 animation starting and the unfocus animation starting.
     * @return The offset for the location bar when showing the dse icon.
     */
    @Override
    public int getLocationBarOffsetForFocusAnimation(boolean hasFocus) {
        if (mStatusCoordinator == null) return 0;

        // No offset is required if the experiment is disabled.
        if (!SearchEngineLogoUtils.shouldShowSearchEngineLogo(
                    getToolbarDataProvider().isIncognito())) {
            return 0;
        }

        // On non-NTP pages, there will always be an icon when unfocused.
        if (mToolbarDataProvider.getNewTabPageForCurrentTab() == null) return 0;

        // This offset is only required when the focus animation is running.
        if (!hasFocus) return 0;

        // We're on the NTP with the fakebox showing.
        // The value returned changes based on if the layout is LTR OR RTL.
        // For LTR, the value is negative because we are making space on the left-hand side.
        // For RTL, the value is positive because we are pushing the icon further to the
        // right-hand side.
        int offset = mStatusCoordinator.getStatusIconWidth() - getAdditionalOffsetForNTP();
        return getLayoutDirection() == LAYOUT_DIRECTION_RTL ? offset : -offset;
    }

    /**
     * Function used to position the url bar inside the location bar during omnibox animation.
     *
     * @param urlExpansionPercent The current expansion percent, 1 is fully focused and 0 is
     *                            completely unfocused.
     *  @param hasFocus True if the LocationBar has focus, this will be true between the focus
     *                 animation starting and the unfocus animation starting.
     *  @return The X translation for the URL bar, used in the toolbar animation.
     */
    @Override
    public float getUrlBarTranslationXForToolbarAnimation(
            float urlExpansionPercent, boolean hasFocus) {
        // This will be called before status view is ready.
        if (mStatusCoordinator == null) return 0;

        // No offset is required if the experiment is disabled.
        if (!SearchEngineLogoUtils.shouldShowSearchEngineLogo(
                    getToolbarDataProvider().isIncognito())) {
            return 0;
        }

        boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
        // The calculation here is:  the difference in padding between the focused vs unfocused
        // states and also accounts for the translation that the status icon will do. In the end,
        // this translation will be the distance that the url bar needs to travel to arrive at the
        // desired padding when focused.
        float translation =
                urlExpansionPercent * mStatusCoordinator.getEndPaddingPixelSizeOnFocusDelta();

        if (!hasFocus && mStatusCoordinator.isSearchEngineStatusIconVisible()
                && SearchEngineLogoUtils.currentlyOnNTP(mToolbarDataProvider)) {
            // When:
            // 1. unfocusing the LocationBar on the NTP.
            // 2. scrolling the fakebox to the LocationBar on the NTP.
            // The status icon and the URL bar text overlap in the animation.
            //
            // This branch calculates the negative distance the URL bar needs to travel to
            // completely overlap the status icon and end up in a state that matches the fakebox.
            float overStatusIconTranslation = translation
                    - (1f - urlExpansionPercent)
                            * (mStatusCoordinator.getStatusIconWidth()
                                    - getAdditionalOffsetForNTP());
            // The value returned changes based on if the layout is LTR or RTL.
            // For LTR, the value is negative because the status icon is left of the url bar on the
            // x/y plane.
            // For RTL, the value is positive because the status icon is right of the url bar on the
            // x/y plane.
            return isRtl ? -overStatusIconTranslation : overStatusIconTranslation;
        }

        return isRtl ? -translation : translation;
    }

    /**
     * Updates progress of current the URL focus change animation.
     *
     * @param fraction 1.0 is 100% focused, 0 is completely unfocused.
     */
    @Override
    public void setUrlFocusChangeFraction(float fraction) {
        super.setUrlFocusChangeFraction(fraction);

        if (fraction > 0f) {
            mUrlActionContainer.setVisibility(VISIBLE);
        } else if (fraction == 0f && !isUrlFocusChangeInProgress()) {
            // If a URL focus change is in progress, then it will handle setting the visibility
            // correctly after it completes.  If done here, it would cause the URL to jump due
            // to a badly timed layout call.
            mUrlActionContainer.setVisibility(GONE);
        }

        updateButtonVisibility();
        mStatusCoordinator.setUrlFocusChangePercent(fraction);
    }

    @Override
    public void onUrlFocusChange(boolean hasFocus) {
        if (hasFocus) {
            // Remove the focus of this view once the URL field has taken focus as this view no
            // longer needs it.
            setFocusable(false);
            setFocusableInTouchMode(false);
        }
        setUrlFocusChangeInProgress(true);
        updateShouldAnimateIconChanges();
        super.onUrlFocusChange(hasFocus);
    }

    @Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        boolean needsCanvasRestore = false;
        if (child == mUrlBar && mUrlActionContainer.getVisibility() == VISIBLE) {
            canvas.save();

            // Clip the URL bar contents to ensure they do not draw under the URL actions during
            // focus animations.  Based on the RTL state of the location bar, the url actions
            // container can be on the left or right side, so clip accordingly.
            if (mUrlBar.getLeft() < mUrlActionContainer.getLeft()) {
                canvas.clipRect(0, 0, (int) mUrlActionContainer.getX(), getBottom());
            } else {
                canvas.clipRect(mUrlActionContainer.getX() + mUrlActionContainer.getWidth(), 0,
                        getWidth(), getBottom());
            }
            needsCanvasRestore = true;
        }
        boolean retVal = super.drawChild(canvas, child, drawingTime);
        if (needsCanvasRestore) {
            canvas.restore();
        }
        return retVal;
    }

    @Override
    public void finishUrlFocusChange(boolean hasFocus) {
        super.finishUrlFocusChange(hasFocus);
        if (!hasFocus) {
            mUrlActionContainer.setVisibility(GONE);
        }
        mStatusCoordinator.onUrlAnimationFinished(hasFocus);
    }

    @Override
    public FrameLayout.LayoutParams getFrameLayoutParams() {
        return (FrameLayout.LayoutParams) getLayoutParams();
    }

    @Override
    protected void updateButtonVisibility() {
        super.updateButtonVisibility();
        updateMicButtonVisibility();
    }

    @Override
    public void updateShouldAnimateIconChanges() {
        notifyShouldAnimateIconChanges(isUrlBarFocused() || isUrlFocusChangeInProgress());
    }

    @Override
    public void setShowIconsWhenUrlFocused(boolean showIcon) {
        super.setShowIconsWhenUrlFocused(showIcon);
        mFirstVisibleFocusedView = showIcon ? mStatusView : mUrlBar;
        mStatusCoordinator.setShowIconsWhenUrlFocused(showIcon);
    }

    private int getAdditionalOffsetForNTP() {
        return getResources().getDimensionPixelSize(R.dimen.sei_search_box_lateral_padding)
                - getResources().getDimensionPixelSize(R.dimen.sei_location_bar_lateral_padding);
    }

    @Override
    public void updateVisualsForState() {
        super.updateVisualsForState();
        boolean isIncognito = getToolbarDataProvider().isIncognito();
        setShowIconsWhenUrlFocused(SearchEngineLogoUtils.shouldShowSearchEngineLogo(isIncognito));
        updateStatusVisibility();
    }

    @Override
    public void onTabLoadingNTP(NewTabPage ntp) {
        super.onTabLoadingNTP(ntp);
        updateStatusVisibility();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        try (TraceEvent e = TraceEvent.scoped("LocationBarPhone.onMeasure")) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        try (TraceEvent e = TraceEvent.scoped("LocationBarPhone.onLayout")) {
            super.onLayout(changed, left, top, right, bottom);
        }
    }

    @Override
    public View getViewForDrawing() {
        return this;
    }

    /** Update the status visibility according to the current state held in LocationBar. */
    private void updateStatusVisibility() {
        boolean incognito = getToolbarDataProvider().isIncognito();
        if (!SearchEngineLogoUtils.shouldShowSearchEngineLogo(incognito)) {
            return;
        }

        if (SearchEngineLogoUtils.currentlyOnNTP(mToolbarDataProvider)) {
            mStatusCoordinator.setStatusIconShown(hasFocus());
        } else {
            mStatusCoordinator.setStatusIconShown(true);
        }
    }
}
