/*
 * Copyright (C) 2010 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 android.view;

import android.compat.annotation.UnsupportedAppUsage;
import android.content.ClipData;
import android.content.ClipDescription;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.view.IDragAndDropPermissions;

//TODO: Improve Javadoc
/**
 * Represents an event that is sent out by the system at various times during a drag and drop
 * operation. It is a data structure that contains several important pieces of data about
 * the operation and the underlying data.
 * <p>
 *  View objects that receive a DragEvent call {@link #getAction()}, which returns
 *  an action type that indicates the state of the drag and drop operation. This allows a View
 *  object to react to a change in state by changing its appearance or performing other actions.
 *  For example, a View can react to the {@link #ACTION_DRAG_ENTERED} action type by
 *  by changing one or more colors in its displayed image.
 * </p>
 * <p>
 *  During a drag and drop operation, the system displays an image that the user drags. This image
 *  is called a drag shadow. Several action types reflect the position of the drag shadow relative
 *  to the View receiving the event.
 * </p>
 * <p>
 *  Most methods return valid data only for certain event actions. This is summarized in the
 *  following table. Each possible {@link #getAction()} value is listed in the first column. The
 *  other columns indicate which method or methods return valid data for that getAction() value:
 * </p>
 * <table>
 *  <tr>
 *      <th scope="col">getAction() Value</th>
 *      <th scope="col">getClipDescription()</th>
 *      <th scope="col">getLocalState()</th>
 *      <th scope="col">getX()</th>
 *      <th scope="col">getY()</th>
 *      <th scope="col">getClipData()</th>
 *      <th scope="col">getResult()</th>
 *  </tr>
 *  <tr>
 *      <td>ACTION_DRAG_STARTED</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *  </tr>
 *  <tr>
 *      <td>ACTION_DRAG_ENTERED</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *  </tr>
 *  <tr>
 *      <td>ACTION_DRAG_LOCATION</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *  </tr>
 *  <tr>
 *      <td>ACTION_DRAG_EXITED</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *  </tr>
 *  <tr>
 *      <td>ACTION_DROP</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *  </tr>
 *  <tr>
 *      <td>ACTION_DRAG_ENDED</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">X</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">&nbsp;</td>
 *      <td style="text-align: center;">X</td>
 *  </tr>
 * </table>
 * <p>
 *  The {@link android.view.DragEvent#getAction()},
 *  {@link android.view.DragEvent#getLocalState()}
 *  {@link android.view.DragEvent#describeContents()},
 *  {@link android.view.DragEvent#writeToParcel(Parcel,int)}, and
 *  {@link android.view.DragEvent#toString()} methods always return valid data.
 * </p>
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For a guide to implementing drag and drop features, read the
 * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
 * </div>
 */
public class DragEvent implements Parcelable {
    private static final boolean TRACK_RECYCLED_LOCATION = false;

    int mAction;
    float mX, mY;
    @UnsupportedAppUsage
    ClipDescription mClipDescription;
    @UnsupportedAppUsage
    ClipData mClipData;
    IDragAndDropPermissions mDragAndDropPermissions;

    Object mLocalState;
    boolean mDragResult;
    boolean mEventHandlerWasCalled;

    private DragEvent mNext;
    private RuntimeException mRecycledLocation;
    private boolean mRecycled;

    private static final int MAX_RECYCLED = 10;
    private static final Object gRecyclerLock = new Object();
    private static int gRecyclerUsed = 0;
    private static DragEvent gRecyclerTop = null;

    /**
     * Action constant returned by {@link #getAction()}: Signals the start of a
     * drag and drop operation. The View should return {@code true} from its
     * {@link View#onDragEvent(DragEvent) onDragEvent()} handler method or
     * {@link View.OnDragListener#onDrag(View,DragEvent) OnDragListener.onDrag()} listener
     * if it can accept a drop. The onDragEvent() or onDrag() methods usually inspect the metadata
     * from {@link #getClipDescription()} to determine if they can accept the data contained in
     * this drag. For an operation that doesn't represent data transfer, these methods may
     * perform other actions to determine whether or not the View should accept the data.
     * If the View wants to indicate that it is a valid drop target, it can also react by
     * changing its appearance.
     * <p>
     *  Views added or becoming visible for the first time during a drag operation receive this
     *  event when they are added or becoming visible.
     * </p>
     * <p>
     *  A View only receives further drag events for the drag operation if it returns {@code true}
     *  in response to ACTION_DRAG_STARTED.
     * </p>
     * @see #ACTION_DRAG_ENDED
     * @see #getX()
     * @see #getY()
     */
    public static final int ACTION_DRAG_STARTED = 1;

    /**
     * Action constant returned by {@link #getAction()}: Sent to a View after
     * {@link #ACTION_DRAG_ENTERED} while the drag shadow is still within the View object's bounding
     * box, but not within a descendant view that can accept the data. The {@link #getX()} and
     * {@link #getY()} methods supply
     * the X and Y position of of the drag point within the View object's bounding box.
     * <p>
     * A View receives an {@link #ACTION_DRAG_ENTERED} event before receiving any
     * ACTION_DRAG_LOCATION events.
     * </p>
     * <p>
     * The system stops sending ACTION_DRAG_LOCATION events to a View once the user moves the
     * drag shadow out of the View object's bounding box or into a descendant view that can accept
     * the data. If the user moves the drag shadow back into the View object's bounding box or out
     * of a descendant view that can accept the data, the View receives an ACTION_DRAG_ENTERED again
     * before receiving any more ACTION_DRAG_LOCATION events.
     * </p>
     * @see #ACTION_DRAG_ENTERED
     * @see #getX()
     * @see #getY()
     */
    public static final int ACTION_DRAG_LOCATION = 2;

    /**
     * Action constant returned by {@link #getAction()}: Signals to a View that the user
     * has released the drag shadow, and the drag point is within the bounding box of the View and
     * not within a descendant view that can accept the data.
     * The View should retrieve the data from the DragEvent by calling {@link #getClipData()}.
     * The methods {@link #getX()} and {@link #getY()} return the X and Y position of the drop point
     * within the View object's bounding box.
     * <p>
     * The View should return {@code true} from its {@link View#onDragEvent(DragEvent)}
     * handler or {@link View.OnDragListener#onDrag(View,DragEvent) OnDragListener.onDrag()}
     * listener if it accepted the drop, and {@code false} if it ignored the drop.
     * </p>
     * <p>
     * The View can also react to this action by changing its appearance.
     * </p>
     * @see #getClipData()
     * @see #getX()
     * @see #getY()
     */
    public static final int ACTION_DROP = 3;

    /**
     * Action constant returned by {@link #getAction()}:  Signals to a View that the drag and drop
     * operation has concluded.  A View that changed its appearance during the operation should
     * return to its usual drawing state in response to this event.
     * <p>
     *  All views with listeners that returned boolean <code>true</code> for the ACTION_DRAG_STARTED
     *  event will receive the ACTION_DRAG_ENDED event even if they are not currently visible when
     *  the drag ends. Views removed during the drag operation won't receive the ACTION_DRAG_ENDED
     *  event.
     * </p>
     * <p>
     *  The View object can call {@link #getResult()} to see the result of the operation.
     *  If a View returned {@code true} in response to {@link #ACTION_DROP}, then
     *  getResult() returns {@code true}, otherwise it returns {@code false}.
     * </p>
     * @see #ACTION_DRAG_STARTED
     * @see #getResult()
     */
    public static final int ACTION_DRAG_ENDED = 4;

    /**
     * Action constant returned by {@link #getAction()}: Signals to a View that the drag point has
     * entered the bounding box of the View.
     * <p>
     *  If the View can accept a drop, it can react to ACTION_DRAG_ENTERED
     *  by changing its appearance in a way that tells the user that the View is the current
     *  drop target.
     * </p>
     * The system stops sending ACTION_DRAG_LOCATION events to a View once the user moves the
     * drag shadow out of the View object's bounding box or into a descendant view that can accept
     * the data. If the user moves the drag shadow back into the View object's bounding box or out
     * of a descendant view that can accept the data, the View receives an ACTION_DRAG_ENTERED again
     * before receiving any more ACTION_DRAG_LOCATION events.
     * </p>
     * @see #ACTION_DRAG_ENTERED
     * @see #ACTION_DRAG_LOCATION
     */
    public static final int ACTION_DRAG_ENTERED = 5;

    /**
     * Action constant returned by {@link #getAction()}: Signals that the user has moved the
     * drag shadow out of the bounding box of the View or into a descendant view that can accept
     * the data.
     * The View can react by changing its appearance in a way that tells the user that
     * View is no longer the immediate drop target.
     * <p>
     *  After the system sends an ACTION_DRAG_EXITED event to the View, the View receives no more
     *  ACTION_DRAG_LOCATION events until the user drags the drag shadow back over the View.
     * </p>
     *
     */
     public static final int ACTION_DRAG_EXITED = 6;

    private DragEvent() {
    }

    private void init(int action, float x, float y, ClipDescription description, ClipData data,
            IDragAndDropPermissions dragAndDropPermissions, Object localState, boolean result) {
        mAction = action;
        mX = x;
        mY = y;
        mClipDescription = description;
        mClipData = data;
        this.mDragAndDropPermissions = dragAndDropPermissions;
        mLocalState = localState;
        mDragResult = result;
    }

    static DragEvent obtain() {
        return DragEvent.obtain(0, 0f, 0f, null, null, null, null, false);
    }

    /** @hide */
    public static DragEvent obtain(int action, float x, float y, Object localState,
            ClipDescription description, ClipData data,
            IDragAndDropPermissions dragAndDropPermissions, boolean result) {
        final DragEvent ev;
        synchronized (gRecyclerLock) {
            if (gRecyclerTop == null) {
                ev = new DragEvent();
                ev.init(action, x, y, description, data, dragAndDropPermissions, localState,
                        result);
                return ev;
            }
            ev = gRecyclerTop;
            gRecyclerTop = ev.mNext;
            gRecyclerUsed -= 1;
        }
        ev.mRecycledLocation = null;
        ev.mRecycled = false;
        ev.mNext = null;

        ev.init(action, x, y, description, data, dragAndDropPermissions, localState, result);

        return ev;
    }

    /** @hide */
    @UnsupportedAppUsage
    public static DragEvent obtain(DragEvent source) {
        return obtain(source.mAction, source.mX, source.mY, source.mLocalState,
                source.mClipDescription, source.mClipData, source.mDragAndDropPermissions,
                source.mDragResult);
    }

    /**
     * Inspect the action value of this event.
     * @return One of the following action constants, in the order in which they usually occur
     * during a drag and drop operation:
     * <ul>
     *  <li>{@link #ACTION_DRAG_STARTED}</li>
     *  <li>{@link #ACTION_DRAG_ENTERED}</li>
     *  <li>{@link #ACTION_DRAG_LOCATION}</li>
     *  <li>{@link #ACTION_DROP}</li>
     *  <li>{@link #ACTION_DRAG_EXITED}</li>
     *  <li>{@link #ACTION_DRAG_ENDED}</li>
     * </ul>
     */
    public int getAction() {
        return mAction;
    }

    /**
     * Gets the X coordinate of the drag point. The value is only valid if the event action is
     * {@link #ACTION_DRAG_STARTED}, {@link #ACTION_DRAG_LOCATION} or {@link #ACTION_DROP}.
     * @return The current drag point's X coordinate
     */
    public float getX() {
        return mX;
    }

    /**
     * Gets the Y coordinate of the drag point. The value is only valid if the event action is
     * {@link #ACTION_DRAG_STARTED}, {@link #ACTION_DRAG_LOCATION} or {@link #ACTION_DROP}.
     * @return The current drag point's Y coordinate
     */
    public float getY() {
        return mY;
    }

    /**
     * Returns the {@link android.content.ClipData} object sent to the system as part of the call
     * to
     * {@link android.view.View#startDragAndDrop(ClipData,View.DragShadowBuilder,Object,int)
     * startDragAndDrop()}.
     * This method only returns valid data if the event action is {@link #ACTION_DROP}.
     * @return The ClipData sent to the system by startDragAndDrop().
     */
    public ClipData getClipData() {
        return mClipData;
    }

    /**
     * Returns the {@link android.content.ClipDescription} object contained in the
     * {@link android.content.ClipData} object sent to the system as part of the call to
     * {@link android.view.View#startDragAndDrop(ClipData,View.DragShadowBuilder,Object,int)
     * startDragAndDrop()}.
     * The drag handler or listener for a View can use the metadata in this object to decide if the
     * View can accept the dragged View object's data.
     * <p>
     * This method returns valid data for all event actions except for {@link #ACTION_DRAG_ENDED}.
     * @return The ClipDescription that was part of the ClipData sent to the system by
     *     startDragAndDrop().
     */
    public ClipDescription getClipDescription() {
        return mClipDescription;
    }

    /** @hide */
    public IDragAndDropPermissions getDragAndDropPermissions() {
        return mDragAndDropPermissions;
    }

    /**
     * Returns the local state object sent to the system as part of the call to
     * {@link android.view.View#startDragAndDrop(ClipData,View.DragShadowBuilder,Object,int)
     * startDragAndDrop()}.
     * The object is intended to provide local information about the drag and drop operation. For
     * example, it can indicate whether the drag and drop operation is a copy or a move.
     * <p>
     * The local state is available only to views in the activity which has started the drag
     * operation. In all other activities this method will return null
     * </p>
     * <p>
     *  This method returns valid data for all event actions.
     * </p>
     * @return The local state object sent to the system by startDragAndDrop().
     */
    public Object getLocalState() {
        return mLocalState;
    }

    /**
     * <p>
     * Returns an indication of the result of the drag and drop operation.
     * This method only returns valid data if the action type is {@link #ACTION_DRAG_ENDED}.
     * The return value depends on what happens after the user releases the drag shadow.
     * </p>
     * <p>
     * If the user releases the drag shadow on a View that can accept a drop, the system sends an
     * {@link #ACTION_DROP} event to the View object's drag event listener. If the listener
     * returns {@code true}, then getResult() will return {@code true}.
     * If the listener returns {@code false}, then getResult() returns {@code false}.
     * </p>
     * <p>
     * Notice that getResult() also returns {@code false} if no {@link #ACTION_DROP} is sent. This
     * happens, for example, when the user releases the drag shadow over an area outside of the
     * application. In this case, the system sends out {@link #ACTION_DRAG_ENDED} for the current
     * operation, but never sends out {@link #ACTION_DROP}.
     * </p>
     * @return {@code true} if a drag event listener returned {@code true} in response to
     * {@link #ACTION_DROP}. If the system did not send {@link #ACTION_DROP} before
     * {@link #ACTION_DRAG_ENDED}, or if the listener returned {@code false} in response to
     * {@link #ACTION_DROP}, then {@code false} is returned.
     */
    public boolean getResult() {
        return mDragResult;
    }

    /**
     * Recycle the DragEvent, to be re-used by a later caller.  After calling
     * this function you must never touch the event again.
     *
     * @hide
     */
    public final void recycle() {
        // Ensure recycle is only called once!
        if (TRACK_RECYCLED_LOCATION) {
            if (mRecycledLocation != null) {
                throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
            }
            mRecycledLocation = new RuntimeException("Last recycled here");
        } else {
            if (mRecycled) {
                throw new RuntimeException(toString() + " recycled twice!");
            }
            mRecycled = true;
        }

        mClipData = null;
        mClipDescription = null;
        mLocalState = null;
        mEventHandlerWasCalled = false;

        synchronized (gRecyclerLock) {
            if (gRecyclerUsed < MAX_RECYCLED) {
                gRecyclerUsed++;
                mNext = gRecyclerTop;
                gRecyclerTop = this;
            }
        }
    }

    /**
     * Returns a string containing a concise, human-readable representation of this DragEvent
     * object.
     * @return A string representation of the DragEvent object.
     */
    @Override
    public String toString() {
        return "DragEvent{" + Integer.toHexString(System.identityHashCode(this))
        + " action=" + mAction + " @ (" + mX + ", " + mY + ") desc=" + mClipDescription
        + " data=" + mClipData + " local=" + mLocalState + " result=" + mDragResult
        + "}";
    }

    /* Parcelable interface */

    /**
     * Returns information about the {@link android.os.Parcel} representation of this DragEvent
     * object.
     * @return Information about the {@link android.os.Parcel} representation.
     */
    public int describeContents() {
        return 0;
    }

    /**
     * Creates a {@link android.os.Parcel} object from this DragEvent object.
     * @param dest A {@link android.os.Parcel} object in which to put the DragEvent object.
     * @param flags Flags to store in the Parcel.
     */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mAction);
        dest.writeFloat(mX);
        dest.writeFloat(mY);
        dest.writeInt(mDragResult ? 1 : 0);
        if (mClipData == null) {
            dest.writeInt(0);
        } else {
            dest.writeInt(1);
            mClipData.writeToParcel(dest, flags);
        }
        if (mClipDescription == null) {
            dest.writeInt(0);
        } else {
            dest.writeInt(1);
            mClipDescription.writeToParcel(dest, flags);
        }
        if (mDragAndDropPermissions == null) {
            dest.writeInt(0);
        } else {
            dest.writeInt(1);
            dest.writeStrongBinder(mDragAndDropPermissions.asBinder());
        }
    }

    /**
     * A container for creating a DragEvent from a Parcel.
     */
    public static final @android.annotation.NonNull Parcelable.Creator<DragEvent> CREATOR =
        new Parcelable.Creator<DragEvent>() {
        public DragEvent createFromParcel(Parcel in) {
            DragEvent event = DragEvent.obtain();
            event.mAction = in.readInt();
            event.mX = in.readFloat();
            event.mY = in.readFloat();
            event.mDragResult = (in.readInt() != 0);
            if (in.readInt() != 0) {
                event.mClipData = ClipData.CREATOR.createFromParcel(in);
            }
            if (in.readInt() != 0) {
                event.mClipDescription = ClipDescription.CREATOR.createFromParcel(in);
            }
            if (in.readInt() != 0) {
                event.mDragAndDropPermissions =
                        IDragAndDropPermissions.Stub.asInterface(in.readStrongBinder());;
            }
            return event;
        }

        public DragEvent[] newArray(int size) {
            return new DragEvent[size];
        }
    };
}
