/* -*- 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.ThemedImageView;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
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 ThemedImageView 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 = (ThemedImageView) findViewById(R.id.edit_cancel);

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

        roundCornerShape = new Path();
        roundCornerShape.moveTo(0, 0);
        roundCornerShape.lineTo(30, 0);
        roundCornerShape.cubicTo(0, 0, 0, 0, 0, 30);
        roundCornerShape.lineTo(0, 0);

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

    @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);
        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 draw(final Canvas canvas) {
        super.draw(canvas);

        if (uiMode == UIMode.DISPLAY) {
            canvas.drawPath(roundCornerShape, roundCornerPaint);
        }
    }

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

        final PropertyAnimator buttonsAnimator =
                new PropertyAnimator(animator.getDuration(), buttonsInterpolator);
        buttonsAnimator.attach(tabsCounter,
                               PropertyAnimator.Property.ALPHA,
                               1.0f);
        buttonsAnimator.attach(menuIcon,
                               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).
        return editCancel.getLeft() - urlBarEntry.getRight();
    }

    protected int getUrlBarCurveTranslation() {
        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();
        editCancel.onLightweightThemeChanged();
    }

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