// Copyright 2017 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.modular;

using fuchsia.ui.views;

/// This interface is implemented by a story shell. Dependencies are passed to it
/// in Initialize() on startup. The story shell is also expected to implement
/// Lifecycle in order to receive a Terminate() call on teardown.
///
/// In one component instance there can only be one StoryShell service instance.
/// The view token is sent to the separate View service. This way, the story
/// shell may be implemented as a flutter component.
///
/// Teardown may occur via the session shell calling StoryController.Stop(), the
/// sessionmgr being terminated, or by the system shutting down.
@discoverable // Created by story shell applications.
protocol StoryShell {
    Initialize(resource struct {
        story_shell_context client_end:StoryShellContext;
    });

    /// Adds a new Surface and its corresponding view to be displayed by the
    /// StoryShell. More context that allows the story shell to decide how
    /// to layout will be added later. Also, interface to influence life cycle and
    /// focus is obviously missing.
    /// `view_connection` the new view and the associated Surface ID.
    /// `surface_info` metadata relating to the Surface.
    @transitional("Implement AddSurface3 instead")
    AddSurface(resource struct {
        view_connection ViewConnection;
        surface_info SurfaceInfo;
    });
    /// DEPRECATED.  For transition purposes only.
    @transitional("Implement AddSurface3 instead")
    AddSurface2(resource struct {
        view_connection ViewConnection2;
        surface_info SurfaceInfo;
    });
    /// For transition purposes only.
    @transitional("Only implement while AddSurface is transitional")
    AddSurface3(resource struct {
        view_connection ViewConnection;
        surface_info SurfaceInfo2;
    });

    /// Focuses the surface with surface_id, bringing it to the foreground.
    FocusSurface(struct {
        surface_id string:MAX;
    });

    /// Defocuses the surface with surface_id, dismissing it to the background.
    DefocusSurface(struct {
        surface_id string:MAX;
    }) -> ();

    /// Notify when a Surface is focused in the story. The focus could be from
    /// a user interaction or requested by the framework through
    /// StoryController#FocusModule.
    /// EXPERIMENTAL
    -> OnSurfaceFocused(struct {
        surface_id string:MAX;
    });

    /// Remove the Surface with surface_id from the StoryShell entirely. This is
    /// final. The Surface is removed from the graph. If necessary, the
    /// associated Surface is defocused. There is no expectation that
    /// DefocusSurface is called before this.
    RemoveSurface(struct {
        surface_id string:MAX;
    });

    /// Update the surface
    /// This is called when the intent is to update the surface metadata in the
    /// story graph in place. Any fields, except for the surface_id can be
    /// updated. If no value or null is passed for a field it remains unchanged.
    /// This includes the `view_holder_token` inside the connection.
    ///
    /// E.g called when an intent resolves to a module that is known by the
    /// caller to already be running, to update associated metadata.
    @transitional("Implement UpdateSurface3 instead")
    UpdateSurface(resource struct {
        view_connection ViewConnection;
        surface_info SurfaceInfo;
    });
    /// DEPRECATED.  For transition purposes only.
    @transitional("Implement UpdateSurface3 instead")
    UpdateSurface2(resource struct {
        view_connection ViewConnection2;
        surface_info SurfaceInfo;
    });
    /// For transition purposes only.
    @transitional("Only implement while UpdateSurface is transitional")
    UpdateSurface3(resource struct {
        view_connection ViewConnection;
        surface_info SurfaceInfo2;
    });
};

/// A pair mapping a surface ID to a view (via `view_holder_token`).
type ViewConnection = resource struct {
    /// The ID for the surface
    surface_id string:MAX;

    /// Token for embedding the new view corresponding to the surface.
    view_holder_token fuchsia.ui.views.ViewHolderToken;
};

/// DEPRECATED, for transition purposes only.
type ViewConnection2 = resource struct {
    /// The ID for the surface
    surface_id string:MAX;

    /// Token for embedding the new view corresponding to the surface.
    view_holder_token fuchsia.ui.views.ViewHolderToken;
};

/// Contains metadata for a Surface.
type SurfaceInfo = struct {
    /// ID of the view that is parent of this Surface.
    parent_id string:MAX;

    /// The relationship between the parent Surface and this new Surface. Used
    /// for layout optimization.
    surface_relation box<SurfaceRelation>;

    /// Information about the module populates the view.
    module_manifest box<ModuleManifest>;

    /// How the Surface was generated. By an action internal to the story or by
    /// an external action.
    module_source ModuleSource;
};

/// Contains metadata for a Surface.
type SurfaceInfo2 = resource table {
    /// ID of the view that is parent of this Surface.
    1: parent_id string:MAX;

    /// The relationship between the parent Surface and this new Surface. Used
    /// for layout optimization.
    2: surface_relation SurfaceRelation;

    /// Information about the module populates the view.
    3: module_manifest ModuleManifest;

    /// How the Surface was generated. By an action internal to the story or by
    /// an external action.
    4: module_source ModuleSource;

    /// Collection of user-defined key-value attributes that describe this surface (module).
    ///
    /// The `Annotation.value` field of each `Annotation` is always set.
    5: annotations vector<Annotation>:MAX_ANNOTATIONS_PER_MODULE;

    /// The view ref associated with the surface, if one is present.
    6: view_ref fuchsia.ui.views.ViewRef;
};

/// The story shell receives this protocol upon initialization.
protocol StoryShellContext {};

/// Defines the visual state of the Story shell.
type StoryVisualState = strict enum {
    MINIMIZED = 0;
    MAXIMIZED = 1;
    MAXIMIZED_OVERLAYED = 2;
};
