/*
 * Copyright (C) 2011 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.
 */

[
    Conditional=ACCESSIBILITY,
] interface AccessibilityUIElement {
    boolean isEqual(AccessibilityUIElement otherElement);
    readonly attribute DOMString domIdentifier;
    readonly attribute boolean isIsolatedObject;

    // Document information
    readonly attribute DOMString documentEncoding;
    readonly attribute DOMString documentURI;

    // Element access.
    AccessibilityUIElement elementAtPoint(long x, long y);
    AccessibilityUIElement childAtIndex(unsigned long index);
    unsigned long indexOfChild(AccessibilityUIElement child);
    AccessibilityUIElement linkedUIElementAtIndex(unsigned long index);
    AccessibilityUIElement selectedChildAtIndex(unsigned long index);
    undefined setSelectedChild(AccessibilityUIElement element);
    undefined setSelectedChildAtIndex(unsigned long index);
    undefined removeSelectionAtIndex(unsigned long index);
    undefined clearSelectedChildren();
    AccessibilityUIElement titleUIElement();
    AccessibilityUIElement parentElement();
    
    readonly attribute DOMString role;
    readonly attribute DOMString subrole;
    readonly attribute DOMString roleDescription;
    readonly attribute DOMString computedRoleString;
    readonly attribute DOMString title;
    readonly attribute DOMString description;
    readonly attribute DOMString language;
    readonly attribute DOMString helpText;
    readonly attribute DOMString valueDescription;
    readonly attribute DOMString url;
    readonly attribute DOMString speakAs;
    readonly attribute DOMString orientation;
    readonly attribute long insertionPointLineNumber;
    readonly attribute DOMString selectedTextRange;

    DOMString stringDescriptionOfAttributeValue(DOMString attr);
    DOMString stringAttributeValue(DOMString attr);
    double numberAttributeValue(DOMString attr);
    object uiElementArrayAttributeValue(DOMString attr);
    AccessibilityUIElement uiElementAttributeValue(DOMString attr);  
    boolean boolAttributeValue(DOMString attr);
    undefined attributeValueAsync(DOMString attributeName, object callbackFunction);
    undefined setBoolAttributeValue(DOMString attr, boolean value);
    boolean isAttributeSupported(DOMString attr);
    boolean isAttributeSettable(DOMString attr);
    boolean isPressActionSupported();
    boolean isIncrementActionSupported();
    boolean isDecrementActionSupported();
    undefined setValue(DOMString value);

    readonly attribute DOMString stringValue;
    readonly attribute long intValue;
    readonly attribute long minValue;
    readonly attribute long maxValue;
    
    readonly attribute boolean isEnabled;
    readonly attribute boolean isRequired;
    readonly attribute boolean isFocused;
    readonly attribute boolean isFocusable;
    readonly attribute boolean isSelectable;
    readonly attribute boolean isSelected;
    readonly attribute boolean isSelectedOptionActive;
    readonly attribute boolean isMultiSelectable;
    readonly attribute boolean isExpanded;
    readonly attribute boolean isChecked;
    readonly attribute DOMString currentStateValue;
    readonly attribute DOMString sortDirection;
    readonly attribute boolean isIndeterminate;
    readonly attribute boolean isVisible;
    readonly attribute boolean isCollapsed;
    readonly attribute boolean hasPopup;
    readonly attribute DOMString popupValue;
    readonly attribute boolean isIgnored;
    readonly attribute boolean isSingleLine;
    readonly attribute boolean isMultiLine;
    readonly attribute boolean isOnScreen;
    readonly attribute boolean isOffScreen;
    readonly attribute boolean isValid;
    readonly attribute long hierarchicalLevel;
    readonly attribute boolean ariaIsGrabbed;
    readonly attribute DOMString ariaDropEffects;
    readonly attribute DOMString classList;
    readonly attribute DOMString embeddedImageDescription;
    readonly attribute object imageOverlayElements;

    readonly attribute long x;
    readonly attribute long y;
    readonly attribute long width;
    readonly attribute long height;
    readonly attribute long clickPointX;
    readonly attribute long clickPointY;
    readonly attribute DOMString lineRectsAndText;

    readonly attribute object children;
    readonly attribute long childrenCount;
    readonly attribute long selectedChildrenCount;
    readonly attribute long rowCount;
    readonly attribute long columnCount;

    // Actions.
    undefined increment();
    undefined decrement();
    undefined asyncIncrement();
    undefined asyncDecrement();
    undefined press();
    undefined syncPress();
    undefined showMenu();
    undefined dismiss();

    // Attribute info.
    DOMString allAttributes();
    DOMString attributesOfChildren();
    DOMString attributesOfLinkedUIElements();
    DOMString attributesOfDocumentLinks();

    // Text info.
    DOMString characterAtOffset(long offset);
    DOMString wordAtOffset(long offset);
    DOMString lineAtOffset(long offset);
    DOMString sentenceAtOffset(long offset);
    
    // Table info.
    DOMString attributesOfColumnHeaders();
    DOMString attributesOfRowHeaders();
    DOMString attributesOfColumns();
    DOMString attributesOfRows();
    DOMString attributesOfVisibleCells();
    DOMString attributesOfHeader();
    AccessibilityUIElement cellForColumnAndRow(unsigned long column, unsigned long row);
    AccessibilityUIElement selectedRowAtIndex(unsigned long index);
    AccessibilityUIElement disclosedByRow();
    AccessibilityUIElement disclosedRowAtIndex(unsigned long index);
    AccessibilityUIElement rowAtIndex(unsigned long index);
    boolean isInTableCell();
    readonly attribute boolean isInTable;
    readonly attribute boolean isInLandmark;
    readonly attribute boolean isInList;
    long indexInTable();
    DOMString rowIndexRange();
    DOMString columnIndexRange();
    long rowCount();
    long columnCount();
    object columnHeaders();
    object rowHeaders();

    object detailsElements();
    object errorMessageElements();
    AccessibilityUIElement ariaOwnsElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaOwnsReferencingElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaFlowToElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaFlowToReferencingElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaControlsElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaControlsReferencingElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaLabelledByElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaLabelledByReferencingElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaDescribedByElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaDescribedByReferencingElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaDetailsElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaDetailsReferencingElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaErrorMessageElementAtIndex(unsigned long index);
    AccessibilityUIElement ariaErrorMessageReferencingElementAtIndex(unsigned long index);

    // Paramaterized attributes.
    DOMString parameterizedAttributeNames();
    long lineForIndex(long index);
    DOMString rangeForLine(long index);
    DOMString rangeForPosition(long x, long y);
    DOMString boundsForRange(unsigned long location, unsigned long length);
    DOMString stringForRange(unsigned long location, unsigned long length);
    DOMString attributedStringForRange(unsigned long location, unsigned long length);
    DOMString attributedStringForElement();
    boolean attributedStringRangeIsMisspelled(unsigned long location, unsigned long length);
    [PassContext] unsigned long uiElementCountForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText, boolean visibleOnly, boolean immediateDescendantsOnly);
    [PassContext] AccessibilityUIElement uiElementForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText, boolean visibleOnly, boolean immediateDescendantsOnly);
    [PassContext] DOMString selectTextWithCriteria(DOMString ambiguityResolution, object searchStrings, DOMString replacementString, DOMString activity);
    [PassContext] object searchTextWithCriteria(object searchStrings, DOMString startFrom, DOMString direction);
    boolean setSelectedTextRange(unsigned long location, unsigned long length);

    // Scroll area attributes.
    readonly attribute AccessibilityUIElement horizontalScrollbar;
    readonly attribute AccessibilityUIElement verticalScrollbar;

    undefined scrollToMakeVisible();
    undefined scrollToGlobalPoint(long x, long y);
    undefined scrollToMakeVisibleWithSubFocus(long x, long y, long width, long height);

    undefined takeFocus();
    boolean scrollPageDown();
    boolean scrollPageUp();
    boolean scrollPageLeft();
    boolean scrollPageRight();

    // Text markers.
    AccessibilityTextMarkerRange lineTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
    long lineIndexForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarkerRange misspellingTextMarkerRange(AccessibilityTextMarkerRange start, boolean forward);
    AccessibilityTextMarkerRange textMarkerRangeForElement(AccessibilityUIElement element);
    AccessibilityTextMarkerRange textMarkerRangeForMarkers(AccessibilityTextMarker startMarker, AccessibilityTextMarker endMarker);
    AccessibilityTextMarkerRange textMarkerRangeForRange(unsigned long location, unsigned long length);
    AccessibilityTextMarkerRange selectedTextMarkerRange();
    undefined resetSelectedTextMarkerRange();
    boolean replaceTextInRange(DOMString string, long position, long length);
    boolean insertText(DOMString text);
    AccessibilityTextMarker startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange range);
    AccessibilityTextMarker endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange range);
    AccessibilityTextMarker endTextMarkerForBounds(long x, long y, long width, long height);
    AccessibilityTextMarker startTextMarkerForBounds(long x, long y, long width, long height);
    AccessibilityTextMarker textMarkerForPoint(long x, long y);
    AccessibilityTextMarker previousTextMarker(AccessibilityTextMarker marker);
    AccessibilityTextMarker nextTextMarker(AccessibilityTextMarker marker);
    AccessibilityUIElement accessibilityElementForTextMarker(AccessibilityTextMarker marker);
    DOMString stringForTextMarkerRange(AccessibilityTextMarkerRange range);
    DOMString rectsForTextMarkerRange(AccessibilityTextMarkerRange range, DOMString searchText);
    DOMString attributedStringForTextMarkerRange(AccessibilityTextMarkerRange range);
    DOMString attributedStringForTextMarkerRangeWithOptions(AccessibilityTextMarkerRange range, boolean includeSpellCheck);
    long textMarkerRangeLength(AccessibilityTextMarkerRange range);
    boolean attributedStringForTextMarkerRangeContainsAttribute(DOMString attr, AccessibilityTextMarkerRange range);
    long indexForTextMarker(AccessibilityTextMarker marker);
    boolean isTextMarkerValid(AccessibilityTextMarker marker);
    AccessibilityTextMarker textMarkerForIndex(long textIndex);
    readonly attribute AccessibilityTextMarker startTextMarker;
    readonly attribute AccessibilityTextMarker endTextMarker;
    boolean setSelectedTextMarkerRange(AccessibilityTextMarkerRange range);
    AccessibilityTextMarkerRange leftWordTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarkerRange rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarker previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarker nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarkerRange paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarker previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarker nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarkerRange sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarker previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarker nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
    AccessibilityTextMarkerRange textMarkerRangeMatchesTextNearMarkers(DOMString text, AccessibilityTextMarker startMarker, AccessibilityTextMarker endMarker);

    // Returns an ordered list of supported actions for an element.
    readonly attribute DOMString supportedActions;
    readonly attribute DOMString mathPostscriptsDescription;
    readonly attribute DOMString mathPrescriptsDescription;
    readonly attribute object mathRootRadicand;

    readonly attribute DOMString pathDescription;

    // iOS specific accessibility methods.
    readonly attribute DOMString identifier;
    readonly attribute DOMString traits;
    readonly attribute long elementTextPosition;
    readonly attribute long elementTextLength;
    readonly attribute DOMString stringForSelection;
    object elementsForRange(unsigned long location, unsigned long length);
    undefined increaseTextSelection();
    undefined decreaseTextSelection();
    AccessibilityUIElement linkedElement();
    AccessibilityUIElement headerElementAtIndex(unsigned long index);
    // This will simulate the accessibilityDidBecomeFocused API in UIKit.
    undefined assistiveTechnologySimulatedFocus();
    readonly attribute boolean isSearchField;
    readonly attribute boolean isTextArea;
    readonly attribute boolean isInDefinitionListDefinition;
    readonly attribute boolean isInDefinitionListTerm;

    // Fieldset
    readonly attribute boolean hasContainedByFieldsetTrait;
    AccessibilityUIElement fieldsetAncestorElement();

    // Notification support.
    boolean addNotificationListener(object callbackFunction);
    boolean removeNotificationListener();
};

