// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.ui.text;

/// Current state of the `TextField`.
/// Lists current revision number for the content. Any time the revision number is
/// incremented, all these Positions become invalid, and a new `TextFieldState`
/// should be obtained using `TextField.WatchState`.
///
/// Assumptions:
/// - No cursor support
/// - No selection support
/// - No composition/dead key support
table TextFieldState {
    /// Revision is an opaque identifier of the state. It should not be a subject of assumptions
    /// or manipulations for the client. Client's responsibility is to ensure the revision is
    /// up to date using `ReadableTextField.WatchState()` prior to modifying text contents in
    /// the field.
    /// Revision is incremented any time anything about the state is changed.
    /// Examples:
    ///  - content in the text field is changed
    /// Required.
    1: uint64 revision;

    /// The start and end of the entire text field.
    /// Required.
    2: Range document;
};

/// Indicates errors that can occur with various TextField methods.
enum Error {
    /// Indicates the revision number used is no longer valid.
    BAD_REVISION = 1;

    /// Indicates the range is not valid.
    INVALID_RANGE = 2;
};

/// Editing capabilities of the `TextField`.
/// This protocol should not be used directly by clients, `TextField` should be used instead.
/// Assumptions:
/// - no support for conflict resolution
protocol EditableTextField {
    /// Replaces text in the range with `new_text`.
    /// Can be used to replace, insert, or delete text.
    /// It's the caller's responsibility to make sure `new_text` isn't too long for a FIDL
    /// message; if it is, the client should break up the string into separate `Replace` calls.
    /// As a result of calling this method text field content is updated as well as
    /// `TextFieldState.revision`, which in turn will notify listeners via response to
    /// `ReadableTextField.WatchState()`
    Replace(Range range, string:MAX new_text);
};

/// Text retrieving and state monitoring capabilities of the `TextField`.
/// This protocol should not be used directly by clients, `TextField` should be used instead.
protocol ReadableTextField {
    /// Returns a string of unicode code points between two positions.
    /// It's the caller's responsibility to make sure that text isn't too long for a FIDL
    /// message; if it is, the client should break up the string into separate `GetContents`
    /// calls.
    GetContents(uint64 revision, Range range) -> (string:MAX contents) error Error;

    /// Returns current state of the `TextField`. First call to this method will be
    /// responded immediately. Responses to subsequent requests are responded as `revision`
    /// number of `TextInputState` changes.
    WatchState() -> (TextFieldState state);
};

/// Represents a text field or other kind of editing interface that can receive and present
/// text input.
/// Clients should be only using `TextField`.
protocol TextField {
    compose EditableTextField;
    compose ReadableTextField;
};
