/*
 * Copyright 2021 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 androidx.draganddrop;

import android.app.Activity;
import android.content.ClipData;
import android.os.Build;
import android.view.DragAndDropPermissions;
import android.view.DragEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.widget.EditText;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.core.view.ContentInfoCompat;
import androidx.core.view.OnReceiveContentListener;
import androidx.core.view.ViewCompat;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Helper class used to configure {@link View}s to receive data dropped by a drag and drop
 * operation. Includes support for content insertion using an
 * {@link OnReceiveContentListener OnReceiveContentListener}. Adds highlighting during the drag
 * interaction to indicate to the user where the drop action can successfully take place.
 *
 * <p>To ensure that drop target highlighting and text data handling work correctly, all
 * {@link EditText} elements in the drop target view's descendant tree (that is, any
 * {@code EditText} elements contained within the drop target) must be provided as arguments to a
 * call to {@link DropHelper.Options.Builder#addInnerEditTexts(EditText...)}. Otherwise, an
 * {@code EditText} within the target will steal the focus during the drag and drop operation,
 * possibly causing undesired highlighting behavior.
 *
 * <p>Also, if the user is dragging text data and URI data in the drag and drop {@link ClipData},
 * one of the {@code EditText} elements in the drop target is automatically chosen to handle the
 * text data. See {@link DropHelper.Options.Builder#addInnerEditTexts(EditText...)} for the order of
 * precedence in selecting the {@code EditText} that handles the text data.
 *
 * <p>This helper attaches an {@link OnReceiveContentListener OnReceiveContentListener} to drop
 * targets and configures drop targets to listen for drag and drop events (see
 * {@link #configureView(Activity, View, String[], OnReceiveContentListener) configureView}). Do not
 * attach an {@link OnDragListener OnDragListener} or additional {@code OnReceiveContentLister} to
 * drop targets when using {@link DropHelper}.
 *
 * <p><b>Note:</b> This class requires Android API level 24 or higher.
 *
 * @see <a href="https://developer.android.com/guide/topics/ui/drag-drop">Drag and drop</a>
 * @see <a href="https://developer.android.com/guide/topics/large-screens/multi-window-support#dnd">
 *     Multi-window support</a>
 */
@RequiresApi(Build.VERSION_CODES.N)
public final class DropHelper {

    private static final String TAG = "DropHelper";

    private DropHelper() {}

    /**
     * Configures a {@code View} for drag and drop operations, including the highlighting that
     * indicates the view is a drop target. Sets a listener that enables the view to handle dropped
     * data.
     * <p>
     * Same as <code>{@link #configureView(Activity, View, String[], Options,
     * OnReceiveContentListener)}</code> but with default configuration options.
     * <p>
     * <b>Note:</b> If the drop target contains {@link EditText} elements, you must use
     * {@link #configureView(Activity, View, String[], Options, OnReceiveContentListener)}. The
     * {@code Options} argument enables you to specify a list of the {@code EditText} elements
     * (see {@link Options.Builder#addInnerEditTexts(EditText...)}).
     *
     * @param activity The current {@code Activity} (used for URI permissions).
     * @param dropTarget A {@code View} that accepts the drag and drop data.
     * @param mimeTypes The MIME types the drop target can accept from the dropped data.
     * @param onReceiveContentListener A listener that handles the dropped data.
     */
    public static void configureView(
            @NonNull Activity activity,
            @NonNull View dropTarget,
            @NonNull String[] mimeTypes,
            @NonNull @SuppressWarnings("ExecutorRegistration")
                    OnReceiveContentListener onReceiveContentListener) {
        configureView(
                activity,
                dropTarget,
                mimeTypes,
                new Options.Builder().build(),
                onReceiveContentListener);
    }

    /**
     * Configures a {@code View} for drag and drop operations, including the highlighting that
     * indicates the view is a drop target. Sets a listener that enables the view to handle dropped
     * data.
     * <p>
     * If the drop target's view hierarchy contains any {@code EditText} elements, they all must be
     * specified in {@code options} (see {@link Options.Builder#addInnerEditTexts(EditText...)}).
     * <p>
     * View highlighting occurs for a drag action only if a MIME type in the
     * {@link android.content.ClipDescription ClipDescription} matches a MIME type provided in
     * {@code mimeTypes}; wildcards are allowed (for example, "image/*"). A drop can be executed
     * and passed on to the {@code OnReceiveContentListener} even if the MIME type is not matched.
     * <p>
     * See {@link DropHelper} for more information.
     *
     * @param activity The current {@code Activity} (used for URI permissions).
     * @param dropTarget A {@code View} that accepts the drag and drop data.
     * @param mimeTypes The MIME types the drop target can accept from the dropped data.
     * @param options Configuration options for the drop target (see {@link DropHelper.Options}).
     * @param onReceiveContentListener A listener that handles the dropped data.
     */
    public static void configureView(
            @NonNull Activity activity,
            @NonNull View dropTarget,
            @NonNull String[] mimeTypes,
            @NonNull Options options,
            @NonNull @SuppressWarnings("ExecutorRegistration")
                    OnReceiveContentListener onReceiveContentListener) {
        DropAffordanceHighlighter.Builder highlighterBuilder = DropAffordanceHighlighter.forView(
                dropTarget,
                clipDescription -> {
                    if (clipDescription == null) {
                        return false;
                    }
                    for (String mimeType : mimeTypes) {
                        if (clipDescription.hasMimeType(mimeType)) {
                            return true;
                        }
                    }
                    return false;
                });
        if (options.hasHighlightColor()) {
            highlighterBuilder.setHighlightColor(options.getHighlightColor());
        }
        if (options.hasHighlightCornerRadiusPx()) {
            highlighterBuilder.setHighlightCornerRadiusPx(options.getHighlightCornerRadiusPx());
        }
        DropAffordanceHighlighter highlighter = highlighterBuilder.build();
        List<EditText> innerEditTexts = options.getInnerEditTexts();
        if (!innerEditTexts.isEmpty()) {
            // Any inner EditTexts need to know how to handle the drop.
            for (EditText innerEditText : innerEditTexts) {
                setHighlightingAndHandling(innerEditText, mimeTypes, highlighter,
                        onReceiveContentListener, activity);
            }
            // When handling drops to the outer view, delegate to the correct inner EditText.
            dropTarget.setOnDragListener(createDelegatingHighlightingOnDragListener(
                    activity, highlighter, innerEditTexts));
        } else {
            // With no inner EditTexts, the main View can handle everything.
            setHighlightingAndHandling(
                    dropTarget, mimeTypes, highlighter, onReceiveContentListener, activity);
        }
    }

    private static void setHighlightingAndHandling(
            View view,
            String[] mimeTypes,
            DropAffordanceHighlighter highlighter,
            OnReceiveContentListener onReceiveContentListener,
            Activity activity) {
        ViewCompat.setOnReceiveContentListener(view, mimeTypes, onReceiveContentListener);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || view instanceof AppCompatEditText) {
            // In AppCompatEditText, or in S+, the OnReceiveContentListener will handle the drop.
            // We just need to add highlighting.
            view.setOnDragListener(highlighter::onDrag);
        } else {
            // Otherwise, trigger the OnReceiveContentListener from an OnDragListener.
            view.setOnDragListener(createHighlightingOnDragListener(highlighter, activity));
        }
    }

    /*
     * Creates an OnDragListener that performs highlighting and triggers the
     * OnReceiveContentListener.
     */
    private static OnDragListener createHighlightingOnDragListener(
            DropAffordanceHighlighter highlighter,
            Activity activity) {
        return (v, dragEvent) -> {
            if (dragEvent.getAction() == DragEvent.ACTION_DROP) {
                ContentInfoCompat data = new ContentInfoCompat.Builder(
                        dragEvent.getClipData(), ContentInfoCompat.SOURCE_DRAG_AND_DROP).build();
                try {
                    requestPermissionsIfNeeded(activity, dragEvent);
                } catch (CouldNotObtainPermissionsException e) {
                    return false;
                }
                ViewCompat.performReceiveContent(v, data);
            }
            return highlighter.onDrag(v, dragEvent);
        };
    }

    private static void requestPermissionsIfNeeded(Activity activity, DragEvent dragEvent)
            throws CouldNotObtainPermissionsException {
        ClipData clipData = dragEvent.getClipData();
        if (clipData != null && hasUris(clipData)) {
            DragAndDropPermissions permissions = activity.requestDragAndDropPermissions(dragEvent);
            if (permissions == null) {
                throw new CouldNotObtainPermissionsException("Couldn't get DragAndDropPermissions");
            }
        }
    }

    private static class CouldNotObtainPermissionsException extends Exception {
        CouldNotObtainPermissionsException(String msg) {
            super(msg);
        }
    }

    private static boolean hasUris(ClipData clipData) {
        for (int i = 0; i < clipData.getItemCount(); i++) {
            if (clipData.getItemAt(i).getUri() != null) {
                return true;
            }
        }
        return false;
    }

    /*
     * Creates an OnDragListener that performs highlighting and delegates to an inner EditText.
     */
    private static OnDragListener createDelegatingHighlightingOnDragListener(
            Activity activity, DropAffordanceHighlighter highlighter, List<EditText> editTexts) {
        return (v, dragEvent) -> {
            if (dragEvent.getAction() == DragEvent.ACTION_DROP) {
                ContentInfoCompat data = new ContentInfoCompat.Builder(
                        dragEvent.getClipData(), ContentInfoCompat.SOURCE_DRAG_AND_DROP).build();
                try {
                    requestPermissionsIfNeeded(activity, dragEvent);
                } catch (CouldNotObtainPermissionsException e) {
                    return false;
                }
                for (EditText editText : editTexts) {
                    if (editText.hasFocus()) {
                        ViewCompat.performReceiveContent(editText, data);
                        return true;
                    }
                }
                // If none had focus, default to the first one provided.
                ViewCompat.performReceiveContent(editTexts.get(0), data);
                return true;
            }
            return highlighter.onDrag(v, dragEvent);
        };
    }

    /**
     * Options for configuring drop targets specified by {@link DropHelper}.
     */
    @RequiresApi(Build.VERSION_CODES.N)
    public static final class Options {
        private final @ColorInt int mHighlightColor;
        private final boolean mHighlightColorHasBeenSupplied;
        private final int mHighlightCornerRadiusPx;
        private final boolean mHighlightCornerRadiusPxHasBeenSupplied;
        private final @NonNull List<EditText> mInnerEditTexts;

        Options(
                @ColorInt int highlightColor,
                boolean highlightColorHasBeenSupplied,
                int highlightCornerRadiusPx,
                boolean highlightCornerRadiusPxHasBeenSupplied,
                @Nullable List<EditText> innerEditTexts) {
            this.mHighlightColor = highlightColor;
            this.mHighlightColorHasBeenSupplied = highlightColorHasBeenSupplied;
            this.mHighlightCornerRadiusPx = highlightCornerRadiusPx;
            this.mHighlightCornerRadiusPxHasBeenSupplied = highlightCornerRadiusPxHasBeenSupplied;
            this.mInnerEditTexts =
                    innerEditTexts != null ? new ArrayList<>(innerEditTexts) : new ArrayList<>();
        }

        /**
         * Returns the color used to highlight the drop target.
         *
         * @return The drop target highlight color.
         * @see #hasHighlightColor()
         */
        public @ColorInt int getHighlightColor() {
            return mHighlightColor;
        }

        /**
         * Indicates whether or not a drop target highlight color has been set. If not, a default
         * is used.
         *
         * @return True if a highlight color has been set, false otherwise.
         */
        public boolean hasHighlightColor() {
            return mHighlightColorHasBeenSupplied;
        }

        /**
         * Returns the corner radius of the drop target highlighting.
         *
         * @return The drop target highlighting corner radius.
         * @see #hasHighlightCornerRadiusPx()
         */
        public int getHighlightCornerRadiusPx() {
            return mHighlightCornerRadiusPx;
        }

        /**
         * Indicates whether or not a corner radius has been set for the drop target highlighting.
         * If not, a default is used.
         *
         * @return True if a corner radius has been set, false otherwise.
         */
        public boolean hasHighlightCornerRadiusPx() {
            return mHighlightCornerRadiusPxHasBeenSupplied;
        }

        /**
         * Returns a list of the {@link EditText} elements contained in the drop target view
         * hierarchy. A list of {@code EditText} elements is supplied when building this
         * {@link DropHelper.Options} instance (see
         * {@link Builder#addInnerEditTexts(EditText...)}).
         *
         * @return The list of drop target {@code EditText} elements.
         */
        public @NonNull List<EditText> getInnerEditTexts() {
            return Collections.unmodifiableList(mInnerEditTexts);
        }

        /**
         * Builder for constructing a {@link DropHelper.Options} instance.
         */
        @RequiresApi(Build.VERSION_CODES.N)
        public static final class Builder {
            private @ColorInt int mHighlightColor;
            private boolean mHighlightColorHasBeenSupplied = false;
            private int mHighlightCornerRadiusPx;
            private boolean mHighlightCornerRadiusPxHasBeenSupplied = false;
            private @Nullable List<EditText> mInnerEditTexts;

            /**
             * Builds a new {@link DropHelper.Options} instance.
             *
             * @return A new {@link DropHelper.Options} instance.
             */
            public @NonNull Options build() {
                return new Options(
                        mHighlightColor,
                        mHighlightColorHasBeenSupplied,
                        mHighlightCornerRadiusPx,
                        mHighlightCornerRadiusPxHasBeenSupplied,
                        mInnerEditTexts);
            }

            /**
             * Enables you to specify the {@link EditText} elements contained within the drop
             * target. To ensure proper drop target highlighting, all {@code EditText} elements in
             * the drop target view hierarchy must be included in a call to this method. Otherwise,
             * an {@code EditText} within the target, rather than the target view itself, acquires
             * focus during the drag and drop operation.
             * <p>
             * If the user is dragging text data and URI data in the drag and drop
             * {@link ClipData}, one of the {@code EditText} elements in the drop target is
             * selected to handle the text data. Selection is based on the following order of
             * precedence:
             * <ol>
             *     <li>The {@code EditText} (if any) on which the {@code ClipData} was dropped
             *     <li>The {@code EditText} (if any) that contains the text cursor (caret)
             *     <li>The first {@code EditText} provided in {@code editTexts}
             * </ol>
             * <p>
             * To set the default {@code EditText}, make it the first argument of the
             * {@code editTexts} parameter. For example, if your drop target handles images and
             * contains two editable text fields, T1 and T2, make T2 the default by calling
             * <code>addInnerEditTexts(T2, T1)</code>.
             * <p>
             * <b>Note:</b> Behavior is undefined if {@code EditText}s are added to or removed
             * from the drop target after this method has been called.
             * <p>
             * See {@link DropHelper} for more information.
             *
             * @param editTexts The {@code EditText} elements contained in the drop target.
             * @return This {@link DropHelper.Options.Builder} instance.
             */
            public @NonNull Options.Builder addInnerEditTexts(
                    @NonNull EditText... editTexts) {
                if (this.mInnerEditTexts == null) {
                    this.mInnerEditTexts = new ArrayList<>();
                }
                Collections.addAll(this.mInnerEditTexts, editTexts);
                return this;
            }

            /**
             * Sets the color of the drop target highlight. The highlight is shown during a drag
             * and drop operation when data is dragged over the drop target and a MIME type in the
             * {@link android.content.ClipDescription ClipDescription} matches a MIME type provided
             * to
             * {@link DropHelper#configureView(Activity, View, String[], OnReceiveContentListener)
             * DropHelper#configureView}.
             * <p>
             * <b>Note:</b> Opacity, if provided, is ignored.
             *
             * @param highlightColor The highlight color.
             * @return This {@link DropHelper.Options.Builder} instance.
             */
            public @NonNull Options.Builder setHighlightColor(@ColorInt int highlightColor) {
                this.mHighlightColor = highlightColor;
                this.mHighlightColorHasBeenSupplied = true;
                return this;
            }

            /**
             * Sets the corner radius of the drop target highlight. The highlight is shown during
             * a drag and drop operation when data is dragged over the drop target and a MIME type
             * in the {@link android.content.ClipDescription ClipDescription} matches a MIME type
             * provided to
             * {@link DropHelper#configureView(Activity, View, String[], OnReceiveContentListener)
             * DropHelper#configureView}.
             *
             * @param highlightCornerRadiusPx The highlight corner radius in pixels.
             * @return This {@link DropHelper.Options.Builder} instance.
             */
            public @NonNull Options.Builder setHighlightCornerRadiusPx(
                    int highlightCornerRadiusPx) {
                this.mHighlightCornerRadiusPx = highlightCornerRadiusPx;
                this.mHighlightCornerRadiusPxHasBeenSupplied = true;
                return this;
            }
        }
    }
}
