// Copyright 2019 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.settings;

using fuchsia.ui.types;

/// Modify or watch accessibility settings that are persisted.
///
/// Supported SettingsEpitaph enums:
/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
@discoverable
protocol Accessibility {
    /// Gets the current value of all accessibility settings. Returns
    /// immediately on first call; subsequent calls return when any of the
    /// values change.
    ///
    /// - `settings` all current values of the accessibility settings.
    /// * see [`AccessibilitySettings`] for their meaning.
    ///
    /// If this call fails, it is considered a fatal error and the channel
    /// will be closed.
    Watch() -> (struct {
        settings AccessibilitySettings;
    });

    /// Sets [AccessibilitySettings] settings. Any field not explicitly set in the table performs a
    /// no-op, and will not make any changes.
    Set(struct {
        settings AccessibilitySettings;
    }) -> (struct {}) error Error;
};

/// Supported accessibility settings.
type AccessibilitySettings = table {
    /// For videos, use an alternative audio track (akin to changing languages)
    /// that explains what is happening visually while there is no dialogue.
    1: audio_description bool;

    /// Read aloud elements of the screen selected by the user.
    2: screen_reader bool;

    /// Invert colors on the screen.
    3: color_inversion bool;

    /// Interpret triple-tap on the touchscreen as a command to zoom in.
    4: enable_magnification bool;

    /// What type of color-blindness, if any, to correct for.
    5: color_correction ColorBlindnessType;

    /// What kind of sources get closed captions, and how they look.
    6: captions_settings CaptionsSettings;
};

type ColorBlindnessType = strict enum {
    /// No color blindness.
    NONE = 0;

    /// Red-green color blindness due to reduced sensitivity to red light.
    PROTANOMALY = 1;

    /// Red-green color blindness due to reduced sensitivity to green light.
    DEUTERANOMALY = 2;

    /// Blue-yellow color blindness. It is due to reduced sensitivity to blue
    /// light.
    TRITANOMALY = 3;
};

/// What kind of sources get closed captions, and how they look.
type CaptionsSettings = table {
    /// Closed captions enabled for media sources of audio.
    1: for_media bool;

    /// Closed captions enabled for Text-To-Speech sources of audio.
    2: for_tts bool;

    /// Font style and color used for the closed captions text.
    3: font_style CaptionFontStyle;

    /// Border color used around the closed captions window.
    ///
    /// Each color channel should be a finite number otherwise will cause
    /// SetAccessibilityInfo to fail with INVALID_VALUE.
    4: window_color fuchsia.ui.types.ColorRgba;

    /// Background color of the closed captions window.
    ///
    /// Each color channel should be a finite number otherwise will cause
    /// SetAccessibilityInfo to fail with INVALID_VALUE.
    5: background_color fuchsia.ui.types.ColorRgba;
};

/// Font, size, and color of closed captions text.
type CaptionFontStyle = table {
    1: family CaptionFontFamily;
    /// 47 CFR §79.103(c)(2) requires at least 3-bit RGB for user override of
    /// closed-captions color.
    ///
    /// Each color channel should be a finite number otherwise will cause
    /// SetAccessibilityInfo to fail with INVALID_VALUE.
    2: color fuchsia.ui.types.ColorRgba;
    /// Size of closed captions text relative to the default captions size. A
    /// range of [0.5, 2] is guaranteed to be supported (as 47 CFR §79.103(c)(4)
    /// establishes). Size should be a finite number.
    3: relative_size float32;
    4: char_edge_style EdgeStyle;
};

/// Font family groups for closed captions, specified by 47 CFR §79.102(k).
type CaptionFontFamily = strict enum {
    UNKNOWN = 0;
    MONOSPACED_SERIF = 1;
    PROPORTIONAL_SERIF = 2;
    MONOSPACED_SANS_SERIF = 3;
    PROPORTIONAL_SANS_SERIF = 4;
    CASUAL = 5;
    CURSIVE = 6;
    SMALL_CAPITALS = 7;
};

/// Edge style for fonts as specified in 47 CFR §79.103(c)(7)
type EdgeStyle = strict enum {
    /// No border around fonts.
    NONE = 0;

    /// A shadow "behind" and slightly offset from each edge.
    DROP_SHADOW = 1;

    /// A bevel that mimics a 3D raised effect.
    RAISED = 2;

    /// A bevel that mimics a 3D depressed effect.
    DEPRESSED = 3;

    /// A plain border around each shapes.
    OUTLINE = 4;
};
