/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.gecko.toolbar;

import java.util.Arrays;

import android.support.v4.content.ContextCompat;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.animation.ViewHelper;
import org.mozilla.gecko.widget.themed.ThemedImageButton;
import org.mozilla.gecko.widget.themed.ThemedImageView;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.ImageView;

/**
 * A base implementations of the browser toolbar for phones.
 * This class manages any Views, variables, etc. that are exclusive to phone.
 */
abstract class BrowserToolbarPhoneBase extends BrowserToolbar {

    protected final ImageView urlBarTranslatingEdge;
    protected final View editCancel;

    private final Path roundCornerShape;
    private final Paint roundCornerPaint;

    private final Interpolator buttonsInterpolator = new AccelerateInterpolator();

    public BrowserToolbarPhoneBase(final Context context, final AttributeSet attrs) {
        super(context, attrs);
        final Resources res = context.getResources();

        urlBarTranslatingEdge = (ImageView) findViewById(R.id.url_bar_translating_edge);

        // This will clip the translating edge's image at 60% of its width
        urlBarTranslatingEdge.getDrawable().setLevel(6000);

        editCancel = findViewById(R.id.edit_cancel);

        focusOrder.add(this);
        focusOrder.addAll(urlDisplayLayout.getFocusOrder());
        focusOrder.addAll(Arrays.asList(tabsButton, menuButton));

        roundCornerShape = new Path();
        updateRoundCornerShape();

        roundCornerPaint = new Paint();
        roundCornerPaint.setAntiAlias(true);
        roundCornerPaint.setColor(ContextCompat.getColor(context, R.color.text_and_tabs_tray_grey));
        roundCornerPaint.setStrokeWidth(0.0f);
    }

    private void updateRoundCornerShape() {
        roundCornerShape.reset();
        if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
            int right = getRight();
            roundCornerShape.moveTo(right, 0);
            roundCornerShape.lineTo(right - 30, 0);
            roundCornerShape.cubicTo(right, 0, right, 0, right, 30);
            roundCornerShape.lineTo(right, 0);
        } else {
            roundCornerShape.moveTo(0, 0);
            roundCornerShape.lineTo(30, 0);
            roundCornerShape.cubicTo(0, 0, 0, 0, 0, 30);
            roundCornerShape.lineTo(0, 0);
        }
    }

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

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();

        editCancel.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // If we exit editing mode during the animation,
                // we're put into an inconsistent state (bug 1017276).
                if (!isAnimating()) {
                    Telemetry.sendUIEvent(TelemetryContract.Event.CANCEL,
                            TelemetryContract.Method.ACTIONBAR,
                            getResources().getResourceEntryName(editCancel.getId()));
                    cancelEdit();
                }
            }
        });
    }

    @Override
    public void setPrivateMode(final boolean isPrivate) {
        super.setPrivateMode(isPrivate);

        ((ThemedImageButton) editCancel).setPrivateMode(isPrivate);
    }

    @Override
    protected boolean isTabsButtonOffscreen() {
        return isEditing();
    }

    @Override
    public boolean addActionItem(final View actionItem) {
        // We have no action item bar.
        return false;
    }

    @Override
    public void removeActionItem(final View actionItem) {
        // We have no action item bar.
    }

    @Override
    protected void updateNavigationButtons(final Tab tab) {
        // We have no navigation buttons so do nothing.
    }

    @Override
    public void triggerTabsPanelTransition(final PropertyAnimator animator, final boolean areTabsShown) {
        if (areTabsShown) {
            ViewHelper.setAlpha(tabsCounter, 0.0f);
            ViewHelper.setAlpha(menuButton, 0.0f);
            return;
        }

        final PropertyAnimator buttonsAnimator =
                new PropertyAnimator(animator.getDuration(), buttonsInterpolator);
        buttonsAnimator.attach(tabsCounter,
                               PropertyAnimator.Property.ALPHA,
                               1.0f);

        buttonsAnimator.attach(menuButton,
                               PropertyAnimator.Property.ALPHA,
                               1.0f);

        buttonsAnimator.start();
    }

    /**
     * Returns the number of pixels the url bar translating edge
     * needs to translate to the right to enter its editing mode state.
     * A negative value means the edge must translate to the left.
     */
    protected int getUrlBarEntryTranslation() {
        // Find the distance from the right-edge of the url bar (where we're translating from) to
        // the left-edge of the cancel button (where we're translating to; note that the cancel
        // button must be laid out, i.e. not View.GONE).
        if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
            return editCancel.getRight() - urlBarEntry.getLeft();
        } else {
            return editCancel.getLeft() - urlBarEntry.getRight();
        }
    }

    protected int getUrlBarCurveTranslation() {
        if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
            return 0 - tabsButton.getRight();
        } else {
            return getWidth() - tabsButton.getLeft();
        }
    }

    protected void updateTabCountAndAnimate(final int count) {
        // Don't animate if the toolbar is hidden.
        if (!isVisible()) {
            updateTabCount(count);
            return;
        }

        // If toolbar is in edit mode on a phone, this means the entry is expanded
        // and the tabs button is translated offscreen. Don't trigger tabs counter
        // updates until the tabs button is back on screen.
        // See stopEditing()
        if (!isTabsButtonOffscreen()) {
            tabsCounter.setCount(count);

            tabsButton.setContentDescription((count > 1) ?
                                             activity.getString(R.string.num_tabs, count) :
                                             activity.getString(R.string.one_tab));
        }
    }

    @Override
    protected void setUrlEditLayoutVisibility(final boolean showEditLayout,
            final PropertyAnimator animator) {
        super.setUrlEditLayoutVisibility(showEditLayout, animator);

        if (animator == null) {
            editCancel.setVisibility(showEditLayout ? View.VISIBLE : View.INVISIBLE);
            return;
        }

        animator.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
            @Override
            public void onPropertyAnimationStart() {
                if (!showEditLayout) {
                    editCancel.setVisibility(View.INVISIBLE);
                }
            }

            @Override
            public void onPropertyAnimationEnd() {
                if (showEditLayout) {
                    editCancel.setVisibility(View.VISIBLE);
                }
            }
        });
    }

    @Override
    public void onLightweightThemeChanged() {
        super.onLightweightThemeChanged();

        ((ThemedImageButton) editCancel).onLightweightThemeChanged();
    }

    @Override
    public void onLightweightThemeReset() {
        super.onLightweightThemeReset();

        ((ThemedImageButton) editCancel).onLightweightThemeReset();
    }
}
