/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.launcher3;

import static com.android.launcher3.ButtonDropTarget.TOOLTIP_DEFAULT;
import static com.android.launcher3.ButtonDropTarget.TOOLTIP_LEFT;
import static com.android.launcher3.ButtonDropTarget.TOOLTIP_RIGHT;
import static com.android.launcher3.anim.AlphaUpdateListener.updateVisibility;

import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;

import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.testing.TestProtocol;

/*
 * The top bar containing various drop targets: Delete/App Info/Uninstall.
 */
public class DropTargetBar extends FrameLayout
        implements DragListener, Insettable {

    protected static final int DEFAULT_DRAG_FADE_DURATION = 175;
    protected static final TimeInterpolator DEFAULT_INTERPOLATOR = Interpolators.ACCEL;

    private final Runnable mFadeAnimationEndRunnable =
            () -> updateVisibility(DropTargetBar.this);

    @ViewDebug.ExportedProperty(category = "launcher")
    protected boolean mDeferOnDragEnd;

    @ViewDebug.ExportedProperty(category = "launcher")
    protected boolean mVisible = false;

    private ButtonDropTarget[] mDropTargets;
    private ViewPropertyAnimator mCurrentAnimation;

    private boolean mIsVertical = true;

    public DropTargetBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DropTargetBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mDropTargets = new ButtonDropTarget[getChildCount()];
        for (int i = 0; i < mDropTargets.length; i++) {
            mDropTargets[i] = (ButtonDropTarget) getChildAt(i);
            mDropTargets[i].setDropTargetBar(this);
        }
    }

    @Override
    public void setInsets(Rect insets) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
        DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
        mIsVertical = grid.isVerticalBarLayout();

        lp.leftMargin = insets.left;
        lp.topMargin = insets.top;
        lp.bottomMargin = insets.bottom;
        lp.rightMargin = insets.right;
        int tooltipLocation = TOOLTIP_DEFAULT;

        if (grid.isVerticalBarLayout()) {
            lp.width = grid.dropTargetBarSizePx;
            lp.height = grid.availableHeightPx - 2 * grid.edgeMarginPx;
            lp.gravity = grid.isSeascape() ? Gravity.RIGHT : Gravity.LEFT;
            tooltipLocation = grid.isSeascape() ? TOOLTIP_LEFT : TOOLTIP_RIGHT;
        } else {
            int gap;
            if (grid.isTablet) {
                // XXX: If the icon size changes across orientations, we will have to take
                //      that into account here too.
                gap = ((grid.widthPx - 2 * grid.edgeMarginPx
                        - (grid.inv.numColumns * grid.cellWidthPx))
                        / (2 * (grid.inv.numColumns + 1)))
                        + grid.edgeMarginPx;
            } else {
                gap = getContext().getResources()
                        .getDimensionPixelSize(R.dimen.drop_target_bar_margin_horizontal);
            }
            lp.width = grid.availableWidthPx - 2 * gap;

            lp.topMargin += grid.edgeMarginPx;
            lp.height = grid.dropTargetBarSizePx;
            lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        }
        setLayoutParams(lp);
        for (ButtonDropTarget button : mDropTargets) {
            button.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.dropTargetTextSizePx);
            button.setToolTipLocation(tooltipLocation);
        }
    }

    public void setup(DragController dragController) {
        dragController.addDragListener(this);
        for (int i = 0; i < mDropTargets.length; i++) {
            dragController.addDragListener(mDropTargets[i]);
            dragController.addDropTarget(mDropTargets[i]);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        int visibleCount = getVisibleButtonsCount();
        if (visibleCount == 0) {
            // do nothing
        } else if (mIsVertical) {
            int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
            int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);

            for (ButtonDropTarget button : mDropTargets) {
                if (button.getVisibility() != GONE) {
                    button.setTextVisible(false);
                    button.measure(widthSpec, heightSpec);
                }
            }
        } else {
            int availableWidth = width / visibleCount;
            boolean textVisible = true;
            for (ButtonDropTarget buttons : mDropTargets) {
                if (buttons.getVisibility() != GONE) {
                    textVisible = textVisible && !buttons.isTextTruncated(availableWidth);
                }
            }

            int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
            int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
            for (ButtonDropTarget button : mDropTargets) {
                if (button.getVisibility() != GONE) {
                    button.setTextVisible(textVisible);
                    button.measure(widthSpec, heightSpec);
                }
            }
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        int visibleCount = getVisibleButtonsCount();
        if (visibleCount == 0) {
            // do nothing
        } else if (mIsVertical) {
            int gap = getResources().getDimensionPixelSize(R.dimen.drop_target_vertical_gap);
            int start = gap;
            int end;

            for (ButtonDropTarget button : mDropTargets) {
                if (button.getVisibility() != GONE) {
                    end = start + button.getMeasuredHeight();
                    button.layout(0, start, button.getMeasuredWidth(), end);
                    start = end + gap;
                }
            }
        } else {
            int frameSize = (right - left) / visibleCount;

            int start = frameSize / 2;
            int halfWidth;
            for (ButtonDropTarget button : mDropTargets) {
                if (button.getVisibility() != GONE) {
                    halfWidth = button.getMeasuredWidth() / 2;
                    button.layout(start - halfWidth, 0,
                            start + halfWidth, button.getMeasuredHeight());
                    start = start + frameSize;
                }
            }
        }
    }

    private int getVisibleButtonsCount() {
        int visibleCount = 0;
        for (ButtonDropTarget buttons : mDropTargets) {
            if (buttons.getVisibility() != GONE) {
                visibleCount++;
            }
        }
        return visibleCount;
    }

    public void animateToVisibility(boolean isVisible) {
        if (TestProtocol.sDebugTracing) {
            Log.d(TestProtocol.NO_DROP_TARGET, "8");
        }
        if (mVisible != isVisible) {
            mVisible = isVisible;

            // Cancel any existing animation
            if (mCurrentAnimation != null) {
                mCurrentAnimation.cancel();
                mCurrentAnimation = null;
            }

            float finalAlpha = mVisible ? 1 : 0;
            if (Float.compare(getAlpha(), finalAlpha) != 0) {
                setVisibility(View.VISIBLE);
                mCurrentAnimation = animate().alpha(finalAlpha)
                        .setInterpolator(DEFAULT_INTERPOLATOR)
                        .setDuration(DEFAULT_DRAG_FADE_DURATION)
                        .withEndAction(mFadeAnimationEndRunnable);
            }

        }
    }

    /*
     * DragController.DragListener implementation
     */
    @Override
    public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
        if (TestProtocol.sDebugTracing) {
            Log.d(TestProtocol.NO_DROP_TARGET, "7");
        }
        animateToVisibility(true);
    }

    /**
     * This is called to defer hiding the delete drop target until the drop animation has completed,
     * instead of hiding immediately when the drag has ended.
     */
    protected void deferOnDragEnd() {
        mDeferOnDragEnd = true;
    }

    @Override
    public void onDragEnd() {
        if (!mDeferOnDragEnd) {
            animateToVisibility(false);
        } else {
            mDeferOnDragEnd = false;
        }
    }

    public ButtonDropTarget[] getDropTargets() {
        return mDropTargets;
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (TestProtocol.sDebugTracing) {
            if (visibility == VISIBLE) {
                Log.d(TestProtocol.NO_DROP_TARGET, "9");
            } else {
                Log.d(TestProtocol.NO_DROP_TARGET, "Hiding drop target", new Exception());
            }
        }
    }
}
