/*
 * Copyright (C) 2015 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.widget.espresso;

import static android.support.test.espresso.action.ViewActions.actionWithAssertions;

import android.graphics.Rect;
import android.support.test.espresso.PerformException;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.CoordinatesProvider;
import android.support.test.espresso.action.GeneralLocation;
import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.Tap;
import android.support.test.espresso.util.HumanReadables;
import android.text.Layout;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Editor;
import android.widget.Editor.HandleView;
import android.widget.TextView;

/**
 * A collection of actions on a {@link android.widget.TextView}.
 */
public final class TextViewActions {

    private TextViewActions() {}

    /**
     * Returns an action that clicks on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to click on.
     */
    public static ViewAction clickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new ViewClickAction(Tap.SINGLE, new TextCoordinates(index), Press.FINGER));
    }


    /**
     * Returns an action that single-clicks by mouse on the View.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a View displayed on screen
     * <ul>
     */
    public static ViewAction mouseClick() {
        return actionWithAssertions(new MouseClickAction(Tap.SINGLE, GeneralLocation.VISIBLE_CENTER,
                MotionEvent.BUTTON_PRIMARY));
    }

    /**
     * Returns an action that clicks by mouse on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to click on.
     */
    public static ViewAction mouseClickOnTextAtIndex(int index) {
        return mouseClickOnTextAtIndex(index, MotionEvent.BUTTON_PRIMARY);
    }

    /**
     * Returns an action that clicks by mouse on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to click on.
     * @param button the mouse button to use.
     */
    public static ViewAction mouseClickOnTextAtIndex(int index,
            @MouseUiController.MouseButton int button) {
        return actionWithAssertions(
                new MouseClickAction(Tap.SINGLE, new TextCoordinates(index), button));
    }

    /**
     * Returns an action that double-clicks on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to double-click on.
     */
    public static ViewAction doubleClickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new ViewClickAction(Tap.DOUBLE, new TextCoordinates(index), Press.FINGER));
    }

    /**
     * Returns an action that double-clicks by mouse on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to double-click on.
     */
    public static ViewAction mouseDoubleClickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new MouseClickAction(Tap.DOUBLE, new TextCoordinates(index)));
    }

    /**
     * Returns an action that long presses on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to long press on.
     */
    public static ViewAction longPressOnTextAtIndex(int index) {
        return actionWithAssertions(
                new ViewClickAction(Tap.LONG, new TextCoordinates(index), Press.FINGER));
    }

    /**
     * Returns an action that long click by mouse on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to long click on.
     */
    public static ViewAction mouseLongClickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new MouseClickAction(Tap.LONG, new TextCoordinates(index)));
    }

    /**
     * Returns an action that triple-clicks by mouse on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to triple-click on.
     */
    public static ViewAction mouseTripleClickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new MouseClickAction(MouseClickAction.CLICK.TRIPLE, new TextCoordinates(index)));
    }

    /**
     * Returns an action that long presses then drags on text from startIndex to endIndex on the
     * TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param startIndex The index of the TextView's text to start a drag from
     * @param endIndex The index of the TextView's text to end the drag at
     */
    public static ViewAction longPressAndDragOnText(int startIndex, int endIndex) {
        return actionWithAssertions(
                new DragAction(
                        DragAction.Drag.LONG_PRESS,
                        new TextCoordinates(startIndex),
                        new TextCoordinates(endIndex),
                        Press.FINGER,
                        TextView.class));
    }

    /**
     * Returns an action that double taps then drags on text from startIndex to endIndex on the
     * TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param startIndex The index of the TextView's text to start a drag from
     * @param endIndex The index of the TextView's text to end the drag at
     */
    public static ViewAction doubleTapAndDragOnText(int startIndex, int endIndex) {
        return actionWithAssertions(
                new DragAction(
                        DragAction.Drag.DOUBLE_TAP,
                        new TextCoordinates(startIndex),
                        new TextCoordinates(endIndex),
                        Press.FINGER,
                        TextView.class));
    }

    /**
     * Returns an action that click then drags by mouse on text from startIndex to endIndex on the
     * TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param startIndex The index of the TextView's text to start a drag from
     * @param endIndex The index of the TextView's text to end the drag at
     */
    public static ViewAction mouseDragOnText(int startIndex, int endIndex) {
        return actionWithAssertions(
                new DragAction(
                        DragAction.Drag.MOUSE_DOWN,
                        new TextCoordinates(startIndex),
                        new TextCoordinates(endIndex),
                        Press.PINPOINT,
                        TextView.class));
    }

    /**
     * Returns an action that double click then drags by mouse on text from startIndex to endIndex
     * on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param startIndex The index of the TextView's text to start a drag from
     * @param endIndex The index of the TextView's text to end the drag at
     */
    public static ViewAction mouseDoubleClickAndDragOnText(int startIndex, int endIndex) {
        return actionWithAssertions(
                new DragAction(
                        DragAction.Drag.MOUSE_DOUBLE_CLICK,
                        new TextCoordinates(startIndex),
                        new TextCoordinates(endIndex),
                        Press.PINPOINT,
                        TextView.class));
    }

    /**
     * Returns an action that long click then drags by mouse on text from startIndex to endIndex
     * on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param startIndex The index of the TextView's text to start a drag from
     * @param endIndex The index of the TextView's text to end the drag at
     */
    public static ViewAction mouseLongClickAndDragOnText(int startIndex, int endIndex) {
        return actionWithAssertions(
                new DragAction(
                        DragAction.Drag.MOUSE_LONG_CLICK,
                        new TextCoordinates(startIndex),
                        new TextCoordinates(endIndex),
                        Press.PINPOINT,
                        TextView.class));
    }

    /**
    * Returns an action that triple click then drags by mouse on text from startIndex to endIndex
    * on the TextView.<br>
    * <br>
    * View constraints:
    * <ul>
    * <li>must be a TextView displayed on screen
    * <ul>
    *
    * @param startIndex The index of the TextView's text to start a drag from
    * @param endIndex The index of the TextView's text to end the drag at
    */
   public static ViewAction mouseTripleClickAndDragOnText(int startIndex, int endIndex) {
       return actionWithAssertions(
               new DragAction(
                       DragAction.Drag.MOUSE_TRIPLE_CLICK,
                       new TextCoordinates(startIndex),
                       new TextCoordinates(endIndex),
                       Press.PINPOINT,
                       TextView.class));
   }

    public enum Handle {
        SELECTION_START,
        SELECTION_END,
        INSERTION
    };

    /**
     * Returns an action that tap then drags on the handle from the current position to endIndex on
     * the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView's drag-handle displayed on screen
     * <ul>
     *
     * @param textView TextView the handle is on
     * @param handleType Type of the handle
     * @param endIndex The index of the TextView's text to end the drag at
     */
    public static ViewAction dragHandle(TextView textView, Handle handleType, int endIndex) {
        return dragHandle(textView, handleType, endIndex, true);
    }

    /**
     * Returns an action that tap then drags on the handle from the current position to endIndex on
     * the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView's drag-handle displayed on screen
     * <ul>
     *
     * @param textView TextView the handle is on
     * @param handleType Type of the handle
     * @param endIndex The index of the TextView's text to end the drag at
     * @param primary whether to use primary direction to get coordinate form index when endIndex is
     * at a direction boundary.
     */
    public static ViewAction dragHandle(TextView textView, Handle handleType, int endIndex,
            boolean primary) {
        return actionWithAssertions(
                new DragAction(
                        DragAction.Drag.TAP,
                        new CurrentHandleCoordinates(textView),
                        new HandleCoordinates(textView, handleType, endIndex, primary),
                        Press.FINGER,
                        Editor.HandleView.class));
    }

    /**
     * A provider of the x, y coordinates of the handle dragging point.
     */
    private static final class CurrentHandleCoordinates implements CoordinatesProvider {
        // Must be larger than Editor#LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS.
        private final TextView mTextView;
        private final String mActionDescription;


        public CurrentHandleCoordinates(TextView textView) {
            mTextView = textView;
            mActionDescription = "Could not locate handle.";
        }

        @Override
        public float[] calculateCoordinates(View view) {
            try {
                return locateHandle(view);
            } catch (StringIndexOutOfBoundsException e) {
                throw new PerformException.Builder()
                        .withActionDescription(mActionDescription)
                        .withViewDescription(HumanReadables.describe(view))
                        .withCause(e)
                        .build();
            }
        }

        private float[] locateHandle(View view) {
            final Rect bounds = new Rect();
            view.getBoundsOnScreen(bounds);
            final Rect visibleDisplayBounds = new Rect();
            mTextView.getWindowVisibleDisplayFrame(visibleDisplayBounds);
            visibleDisplayBounds.right -= 1;
            visibleDisplayBounds.bottom -= 1;
            if (!visibleDisplayBounds.intersect(bounds)) {
                throw new PerformException.Builder()
                        .withActionDescription(mActionDescription
                                + " The handle is entirely out of the visible display frame of"
                                + "the TextView's window.")
                        .withViewDescription(HumanReadables.describe(view))
                        .build();
            }
            final float dragPointX = Math.max(Math.min(bounds.centerX(),
                    visibleDisplayBounds.right), visibleDisplayBounds.left);
            final float verticalOffset = bounds.height() * 0.7f;
            final float dragPointY = Math.max(Math.min(bounds.top + verticalOffset,
                    visibleDisplayBounds.bottom), visibleDisplayBounds.top);
            return new float[] {dragPointX, dragPointY};
        }
    }

    /**
     * A provider of the x, y coordinates of the handle that points the specified text index in a
     * text view.
     */
    private static final class HandleCoordinates implements CoordinatesProvider {
        // Must be larger than Editor#LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS.
        private final static float LINE_SLOP_MULTIPLIER = 0.6f;
        private final TextView mTextView;
        private final Handle mHandleType;
        private final int mIndex;
        private final boolean mPrimary;
        private final String mActionDescription;

        public HandleCoordinates(TextView textView, Handle handleType, int index, boolean primary) {
            mTextView = textView;
            mHandleType = handleType;
            mIndex = index;
            mPrimary = primary;
            mActionDescription = "Could not locate " + handleType.toString()
                    + " handle that points text index: " + index
                    + " (" + (primary ? "primary" : "secondary" ) + ")";
        }

        @Override
        public float[] calculateCoordinates(View view) {
            try {
                return locateHandlePointsTextIndex(view);
            } catch (StringIndexOutOfBoundsException e) {
                throw new PerformException.Builder()
                        .withActionDescription(mActionDescription)
                        .withViewDescription(HumanReadables.describe(view))
                        .withCause(e)
                        .build();
            }
        }

        private float[] locateHandlePointsTextIndex(View view) {
            if (!(view instanceof HandleView)) {
                throw new PerformException.Builder()
                        .withActionDescription(mActionDescription + " The view is not a HandleView")
                        .withViewDescription(HumanReadables.describe(view))
                        .build();
            }
            final HandleView handleView = (HandleView) view;
            final int currentOffset = mHandleType == Handle.SELECTION_START ?
                    mTextView.getSelectionStart() : mTextView.getSelectionEnd();

            final Layout layout = mTextView.getLayout();

            final int currentLine = layout.getLineForOffset(currentOffset);
            final int targetLine = layout.getLineForOffset(mIndex);
            final float currentX = handleView.getHorizontal(layout, currentOffset);
            final float currentY = layout.getLineTop(currentLine);
            final float[] currentCoordinates =
                    TextCoordinates.convertToScreenCoordinates(mTextView, currentX, currentY);
            final float[] targetCoordinates =
                    (new TextCoordinates(mIndex, mPrimary)).calculateCoordinates(mTextView);
            final Rect bounds = new Rect();
            view.getBoundsOnScreen(bounds);
            final Rect visibleDisplayBounds = new Rect();
            mTextView.getWindowVisibleDisplayFrame(visibleDisplayBounds);
            visibleDisplayBounds.right -= 1;
            visibleDisplayBounds.bottom -= 1;
            if (!visibleDisplayBounds.intersect(bounds)) {
                throw new PerformException.Builder()
                        .withActionDescription(mActionDescription
                                + " The handle is entirely out of the visible display frame of"
                                + "the TextView's window.")
                        .withViewDescription(HumanReadables.describe(view))
                        .build();
            }
            final float dragPointX = Math.max(Math.min(bounds.centerX(),
                    visibleDisplayBounds.right), visibleDisplayBounds.left);
            final float diffX = dragPointX - currentCoordinates[0];
            final float verticalOffset = bounds.height() * 0.7f;
            final float dragPointY = Math.max(Math.min(bounds.top + verticalOffset,
                    visibleDisplayBounds.bottom), visibleDisplayBounds.top);
            float diffY = dragPointY - currentCoordinates[1];
            if (currentLine > targetLine) {
                diffY -= mTextView.getLineHeight() * LINE_SLOP_MULTIPLIER;
            } else if (currentLine < targetLine) {
                diffY += mTextView.getLineHeight() * LINE_SLOP_MULTIPLIER;
            }
            return new float[] {targetCoordinates[0] + diffX, targetCoordinates[1] + diffY};
        }
    }

    /**
     * A provider of the x, y coordinates of the text at the specified index in a text view.
     */
    private static final class TextCoordinates implements CoordinatesProvider {

        private final int mIndex;
        private final boolean mPrimary;
        private final String mActionDescription;

        public TextCoordinates(int index) {
            this(index, true);
        }

        public TextCoordinates(int index, boolean primary) {
            mIndex = index;
            mPrimary = primary;
            mActionDescription = "Could not locate text at index: " + mIndex
                    + " (" + (primary ? "primary" : "secondary" ) + ")";
        }

        @Override
        public float[] calculateCoordinates(View view) {
            try {
                return locateTextAtIndex((TextView) view, mIndex, mPrimary);
            } catch (ClassCastException e) {
                throw new PerformException.Builder()
                        .withActionDescription(mActionDescription)
                        .withViewDescription(HumanReadables.describe(view))
                        .withCause(e)
                        .build();
            } catch (StringIndexOutOfBoundsException e) {
                throw new PerformException.Builder()
                        .withActionDescription(mActionDescription)
                        .withViewDescription(HumanReadables.describe(view))
                        .withCause(e)
                        .build();
            }
        }

        /**
         * @throws StringIndexOutOfBoundsException
         */
        private float[] locateTextAtIndex(TextView textView, int index, boolean primary) {
            if (index < 0 || index > textView.getText().length()) {
                throw new StringIndexOutOfBoundsException(index);
            }
            final Layout layout = textView.getLayout();
            final int line = layout.getLineForOffset(index);
            return convertToScreenCoordinates(textView,
                    (primary ? layout.getPrimaryHorizontal(index)
                            : layout.getSecondaryHorizontal(index)),
                    layout.getLineTop(line));
        }

        /**
         * Convert TextView's local coordinates to on screen coordinates.
         * @param textView the TextView
         * @param x local horizontal coordinate
         * @param y local vertical coordinate
         * @return
         */
        public static float[] convertToScreenCoordinates(TextView textView, float x, float y) {
            final int[] xy = new int[2];
            textView.getLocationOnScreen(xy);
            return new float[]{ x + textView.getTotalPaddingLeft() - textView.getScrollX() + xy[0],
                    y + textView.getTotalPaddingTop() - textView.getScrollY() + xy[1] };
        }
    }
}
