/*
 * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

enum DeviceOrientation {
    "portrait",
    "portrait-upsidedown",
    "landscape-left",
    "landscape-right"
};

enum ModifierKey {
    "alt",
    "capsLock",
    "ctrl",
    "meta", // Command key on Mac and iOS
    "shift"
};

interface UIScriptController {

    void doAsyncTask(object callback); // Used to test the harness.
    void uiScriptComplete(DOMString result);

    void doAfterPresentationUpdate(object callback); // Call the callback after sending a message to the WebProcess and receiving a subsequent update.
    void doAfterNextStablePresentationUpdate(object callback);
    void ensurePositionInformationIsUpToDateAt(long x, long y, object callback);
    void doAfterVisibleContentRectUpdate(object callback);

    void doAfterDoubleTapDelay(object callback);

    void simulateAccessibilitySettingsChangeNotification(object callback);

    // Interaction.
    // These functions post events asynchronously. The callback is fired when the events have been dispatched, but any
    // resulting behavior may also be asynchronous. Points are in "global" (WKWebView) coordinates.
    void touchDownAtPoint(long x, long y, long touchCount, object callback);
    void liftUpAtPoint(long x, long y, long touchCount, object callback);
    void singleTapAtPoint(long x, long y, object callback);
    void singleTapAtPointWithModifiers(long x, long y, object modifierArray, object callback);
    void twoFingerSingleTapAtPoint(long x, long y, object callback);
    void doubleTapAtPoint(long x, long y, float delay, object callback);
    void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, object callback);

    void activateAtPoint(long x, long y, object callback);

    void longPressAtPoint(long x, long y, object callback);

    void stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, object callback);
    void stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, object callback);
    void stylusUpAtPoint(long x, long y, object callback);
    void stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, object callback);
    void stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, object modifierArray, object callback);

    void enterText(DOMString text);
    void typeCharacterUsingHardwareKeyboard(DOMString character, object callback);

    void keyDown(DOMString character, object modifierArray);
    void toggleCapsLock(object callback);

    void rawKeyDown(DOMString key);
    void rawKeyUp(DOMString key);

    // eventsJSON describes a series of user events in JSON form. For the keys, see HIDEventGenerator.mm.
    // For example, this JSON describes a touch down followed by a touch up (i.e. a single tap).
    //  {
    //      "events" : [
    //          {
    //              "inputType" : "hand",
    //              "timeOffset" : 0,
    //              "coordinateSpace" : "content",
    //              "touches" : [
    //                  {
    //                      "inputType" : "finger",
    //                      "phase" : "began",
    //                      "id" : 1,
    //                      "x" : 100,
    //                      "y" : 120
    //                  }
    //              ]
    //          },
    //          // This is a basic force press
    //          {
    //              "interpolate" : "linear",
    //              "timestep" : 0.025,
    //              "coordinateSpace" : "global",
    //              "startEvent" : {
    //                  "inputType" : "hand",
    //                  "timeOffset" : 0.025,
    //                  "touches" : [
    //                      {
    //                          "inputType" : "finger",
    //                          "phase" : "began",
    //                          "id" : 1,
    //                          "x" : 100,
    //                          "y" : 120,
    //                          "pressure" : 0
    //                      }
    //                  ]
    //              },
    //              "endEvent" : {
    //                  "inputType" : "hand",
    //                  "timeOffset" : 3.0,
    //                  "touches" : [
    //                      {
    //                          "inputType" : "finger",
    //                          "phase" : "stationary",
    //                          "id" : 1,
    //                          "x" : 100,
    //                          "y" : 120,
    //                          "pressure" : 500
    //                      }
    //                  ]
    //              }
    //          },
    //          //This is a basic drag
    //          {
    //              "interpolate" : "linear",
    //              "timestep" : 0.025,
    //              "coordinateSpace" : "content",
    //              "startEvent" : {
    //                  "inputType" : "hand",
    //                  "timeOffset" : 3.025,
    //                  "touches" : [
    //                      {
    //                          "inputType" : "finger",
    //                          "phase" : "moved",
    //                          "id" : 1,
    //                          "x" : 100,
    //                          "y" : 120,
    //                          "pressure" : 0
    //                      }
    //                  ]
    //              },
    //              "endEvent" : {
    //                  "inputType" : "hand",
    //                  "timeOffset" : 4.0,
    //                  "touches" : [
    //                      {
    //                          "inputType" : "finger",
    //                          "phase" : "moved",
    //                          "id" : 1,
    //                          "x" : 20,
    //                          "y" : 40,
    //                          "pressure" : 0
    //                      }
    //                  ]
    //              }
    //          },
    //          //ending lift
    //          {
    //              "inputType" : "hand",
    //              "timeOffset" : 4.025, // seconds relative to the first event
    //              "coordinateSpace" : "content",
    //              "touches" : [
    //                  {
    //                      "inputType" : "finger",
    //                      "phase" : "ended",
    //                      "id" : 1,
    //                      "x" : 20,
    //                      "y" : 40
    //                  }
    //              ]
    //          },
    //      ]
    //  }
    void sendEventStream(DOMString eventsJSON, object callback);

    void beginBackSwipe(object callback);
    void completeBackSwipe(object callback);

    void playBackEventStream(DOMString eventStream, object callback);

    // Equivalent of pressing the Done button in the form accessory bar.
    void dismissFormAccessoryView();

    void dismissFilePicker(object callback);

    readonly attribute DOMString textContentType;

    // Form control handling
    attribute object didStartFormControlInteractionCallback;
    attribute object didEndFormControlInteractionCallback;

    // Pop Over preview handling
    attribute object didShowContextMenuCallback;
    attribute object didDismissContextMenuCallback;

    // <select> picker
    void selectFormAccessoryPickerRow(long rowIndex);
    readonly attribute DOMString selectFormPopoverTitle;
    readonly attribute DOMString formInputLabel;

    void setTimePickerValue(long hour, long minute);

    // Share sheet
    void setShareSheetCompletesImmediatelyWithResolution(boolean resolved);

    // <datalist>
    readonly attribute boolean isShowingDataListSuggestions;
    void activateDataListSuggestion(unsigned long index, object callback);

    void keyboardAccessoryBarNext();
    void keyboardAccessoryBarPrevious();

    void applyAutocorrection(DOMString newString, DOMString oldString, object callback);

    // Returned object is a dictionary with the passed in string as a key for returned object
    object contentsOfUserInterfaceItem(DOMString interfaceItem);

    // These callbacks also work for the form accessory views.
    attribute object didShowKeyboardCallback;
    attribute object didHideKeyboardCallback;
    readonly attribute boolean isShowingKeyboard;
    readonly attribute boolean hasInputSession;

    attribute object didShowMenuCallback;
    attribute object didHideMenuCallback;
    readonly attribute boolean isDismissingMenu;
    readonly attribute boolean isShowingMenu;
    readonly attribute object menuRect;
    object rectForMenuAction(DOMString action);
    void chooseMenuAction(DOMString action, object callback);
    void dismissMenu();

    readonly attribute boolean isShowingPopover;
    attribute object willPresentPopoverCallback;
    attribute object didDismissPopoverCallback;

    attribute object willBeginZoomingCallback;
    attribute object didEndZoomingCallback;

    attribute object willCreateNewPageCallback;

    void zoomToScale(double scale, object callback);

    void setViewScale(double scale);
    void setMinimumEffectiveWidth(double effectiveWidth);
    void setAllowsViewportShrinkToFit(boolean allows);

    void becomeFirstResponder();
    void resignFirstResponder();
    readonly attribute boolean isPresentingModally;

    void copyText(DOMString text);

    readonly attribute double contentOffsetX;
    readonly attribute double contentOffsetY;

    attribute boolean scrollUpdatesDisabled; // Turns off notifications back to the web process after scrolls (used for testing scrolling tree).

    void scrollToOffset(long x, long y); // Initiate an animated scroll in the UI process.
    attribute object didEndScrollingCallback;

    void immediateScrollToOffset(long x, long y); // Set the scroll position in the UI process without animation.
    void immediateZoomToScale(double scale); // Set the zoom scale in the UI process without animation.

    // Find the scroller for the given point in content ("absolute") coordinates, and do an immediate scroll.
    void immediateScrollElementAtContentPointToOffset(long x, long y, long xOffset, long yOffset);

    // View state
    readonly attribute double zoomScale;
    readonly attribute double minimumZoomScale;
    readonly attribute double maximumZoomScale;

    // Overides the "in stable state" behavior of WKWebView (only applies to iOS)
    // When false, content rect updates to the web process have inStableState=false, as if a scroll or zoom were in progress.
    attribute boolean? stableStateOverride;

    readonly attribute object contentVisibleRect; // Returned object has 'left', 'top', 'width', 'height' properties.

    readonly attribute object textSelectionRangeRects; // An array of objects with 'left', 'top', 'width', and 'height' properties.
    readonly attribute object textSelectionCaretRect; // An object with 'left', 'top', 'width', 'height' properties.
    readonly attribute object selectionStartGrabberViewRect;
    readonly attribute object selectionEndGrabberViewRect;
    readonly attribute object selectionCaretViewRect;
    readonly attribute object selectionRangeViewRects;
    readonly attribute object calendarType;
    void setDefaultCalendarType(DOMString calendarIdentifier);
    readonly attribute object inputViewBounds;

    void setKeyboardInputModeIdentifier(DOMString identifier);

    void replaceTextAtRange(DOMString text, long location, long length);
    void removeAllDynamicDictionaries();

    readonly attribute DOMString scrollingTreeAsText;

    object propertiesOfLayerWithID(unsigned long long layerID);

    void retrieveSpeakSelectionContent(object callback);
    readonly attribute DOMString accessibilitySpeakSelectionContent;
    
    void simulateRotation(DeviceOrientation orientation, object callback);
    void simulateRotationLikeSafari(DeviceOrientation orientation, object callback);

    void findString(DOMString string, unsigned long options, unsigned long maxCount);

    // Unparent and parent the web view, simulating, for example, tab switching.
    void removeViewFromWindow(object callback);
    void addViewToWindow(object callback);

    void overridePreference(DOMString preference, DOMString value);

    void setSafeAreaInsets(double top, double right, double bottom, double left);

    void firstResponderSuppressionForWebView(boolean shouldSuppress);
    void makeWindowContentViewFirstResponder();
    readonly attribute boolean isWindowContentViewFirstResponder;

    void setHardwareKeyboardAttached(boolean attached);

    object attachmentInfo(DOMString attachmentIdentifier);

    // Editing
    void drawSquareInEditableImage();
    readonly attribute long numberOfStrokesInEditableImage;
    readonly attribute DOMString lastUndoLabel;
    readonly attribute DOMString firstRedoLabel;
};
