// 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.hardware.light;

const uint8 LIGHT_NAME_LEN = 32;

enum Capability {
    /// This capability indicates that the light supports setting brightness to a uint8_t value.
    /// If this capability is not supported, the light only supports off and on state.
    BRIGHTNESS = 1;
    /// This capability indicates that the light supports setting an RGB value.
    RGB = 2;
    /// No capabilities
    SIMPLE = 3;
};

struct Rgb {
    float64 red;
    float64 green;
    float64 blue;
};

struct Info {
    string:LIGHT_NAME_LEN name;
    Capability capability;
};

struct GroupInfo {
    string:LIGHT_NAME_LEN name;
    uint32 count;
    Capability capability;
};

enum LightError {
    OK = 0;
    NOT_SUPPORTED = 1;
    INVALID_INDEX = 2;
    FAILED = 3;
};

[Discoverable]
protocol Light {
    /// Returns the total number of physical lights.
    /// This will typically be 1 for a simple LED light, but may be greater than one for an array of
    /// lights or a more complicated lighting device.
    /// The multiple lights are addressed using "index" parameter in the calls below.
    GetNumLights() -> (uint32 count);

    /// Returns the total number of light groups (does not count single lights).
    /// The light groups are addressed using "group_id" parameter in the calls below.
    GetNumLightGroups() -> (uint32 count);

    /// Returns info for the single light.
    /// index: Index of the light defined by board. Must be less than value returned by GetNumLights.
    GetInfo(uint32 index) -> (Info info) error LightError;

    /// Returns the current value. If the light is ON, the value is True. If the light is OFF,
    /// the value is False.
    /// If the capability 'SIMPLE' is not supported by this light, returns NOT_SUPPORTED.
    /// Use GetInfo to check if light supports this operation.
    /// index: a number between 0 inclusive and the count received from GetNumLights.
    GetCurrentSimpleValue(uint32 index) -> (bool value) error LightError;

    /// Sets the current value. Value should be set to 'TRUE' to turn on the light. Value should be
    /// set to 'FALSE' to turn off the light.
    /// If the capability 'SIMPLE' is not supported by this light, returns NOT_SUPPORTED.
    /// Use GetInfo to check if light supports this operation.
    /// index: a number between 0 inclusive and the count received from GetNumLights.
    SetSimpleValue(uint32 index, bool value) -> () error LightError;

    /// Returns the current brightness value (0.0 - 1.0) of the light indicated by index, where 0.0
    /// is minimum brightness and 1.0 is maximum.
    /// If the capability 'BRIGHTNESS' is not supported by this light, returns NOT_SUPPORTED.
    /// Use GetInfo to check if light supports this operation.
    /// index: a number between 0 inclusive and the count received from GetNumLights.
    GetCurrentBrightnessValue(uint32 index) -> (float64 value) error LightError;

    /// Sets the current brightness value (0.0 - 1.0), where 0.0 is minimum brightness and 1.0 is
    /// maximum.
    /// If the capability 'BRIGHTNESS' is not supported by this light, returns NOT_SUPPORTED.
    /// Use GetInfo to check if light supports this operation.
    /// index: a number between 0 inclusive and the count received from GetNumLights.
    SetBrightnessValue(uint32 index, float64 value) -> () error LightError;

    /// Returns the current RGB value for the single light.
    /// If the capability 'RGB' is not supported by this light, returns NOT_SUPPORTED.
    /// Use GetInfo to check if light supports this operation.
    /// index: a number between 0 inclusive and the count received from GetNumLights.
    GetCurrentRgbValue(uint32 index) -> (Rgb value) error LightError;

    /// Sets the current RGB value.
    /// If the capability 'RGB' is not supported by this light, returns NOT_SUPPORTED.
    /// Use GetInfo to check if light supports this operation.
    /// index: a number between 0 inclusive and the count received from GetNumLights.
    SetRgbValue(uint32 index, Rgb value) -> () error LightError;

    /// Returns group info for the light group.
    /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
    GetGroupInfo(uint32 group_id) -> (GroupInfo info) error LightError;

    /// Returns an array of the current values.If the light is ON, the value is True. If the light
    /// is OFF, the value is False.
    /// If group_id is invalid, INVALID_INDEX will be returned.
    /// If the capability 'SIMPLE' is not supported by this group, returns NOT_SUPPORTED.
    /// Use GetGroupInfo to check if group supports this operation.
    /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
    GetGroupCurrentSimpleValue(uint32 group_id) -> (vector<bool>:MAX? values) error LightError;

    /// Sets the current values through the values array. Value should be set to 'TRUE' to turn on
    /// the light. Value should be set to 'FALSE' to turn off the light.
    /// If group_id is invalid, INVALID_INDEX will be returned.
    /// If the capability 'SIMPLE' is not supported by this group, returns NOT_SUPPORTED.
    /// Use GetGroupInfo to check if group supports this operation.
    /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
    SetGroupSimpleValue(uint32 group_id, vector<bool>:MAX values) -> () error LightError;

    /// Returns an array of the current brightness values (0.0 - 1.0) for the light group, where 0.0
    /// is minimum brightness and 1.0 is maximum.
    /// If group_id is invalid, INVALID_INDEX will be returned.
    /// If the capability 'BRIGHTNESS' is not supported by this group, returns NOT_SUPPORTED.
    /// Use GetGroupInfo to check if group supports this operation.
    /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
    GetGroupCurrentBrightnessValue(uint32 group_id) -> (vector<float64>:MAX? values) error LightError;

    /// Sets the current brightness values (0.0 - 1.0) for the light group through the values array,
    /// where 0.0 is minimum brightness and 1.0 is maximum.
    /// If group_id is invalid, INVALID_INDEX will be returned.
    /// If the capability 'BRIGHTNESS' is not supported by this group, returns NOT_SUPPORTED.
    /// Use GetGroupInfo to check if group supports this operation.
    /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
    SetGroupBrightnessValue(uint32 group_id, vector<float64>:MAX values) -> () error LightError;

    /// Returns an array of the current RGB values for the light group.
    /// If group_id is invalid, INVALID_INDEX will be returned.
    /// If the capability 'RGB' is not supported by this group, returns NOT_SUPPORTED.
    /// Use GetGroupInfo to check if group supports this operation.
    /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
    GetGroupCurrentRgbValue(uint32 group_id) -> (vector<Rgb>:MAX? values) error LightError;

    /// Sets the current RGB value for the light group.
    /// If group_id is invalid, INVALID_INDEX will be returned.
    /// If the capability 'RGB' is not supported by this group, returns NOT_SUPPORTED.
    /// Use GetGroupInfo to check if group supports this operation.
    /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
    SetGroupRgbValue(uint32 group_id, vector<Rgb>:MAX values) -> () error LightError;

    // TODO: Ideas for future expansion
    // - Hardware blinking configuration, for lights that have hardware or MCU support for blinking.
};
