// 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.policy;
using fuchsia.ui.viewsv1token;

// 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 ViewOwner request is sent to the separate ViewProvider service. This way,
// the story shell may be implemented as a flutter component.
//
// Teardown may be initiated by the session shell calling StoryController.Stop(),
// by the sessionmgr being terminated, or by the system shutting down.
[Discoverable] // Created by story shell applications.
interface StoryShell {
    1: Initialize(StoryShellContext story_shell_context);

    // 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.
    2: AddSurface(ViewConnection view_connection, SurfaceInfo surface_info);

    // Focuses the surface with surface_id, bringing it to the foreground.
    3: FocusSurface(string surface_id);

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

    // Adds a container, with corresponding container layouts to the story.
    // Optionally provide a parent_id to connect to, if omitted adds the
    // Container node as the root of a new tree in the Story
    // DEPRECATED
    5: AddContainer(string containerName, string? parentId,
                    SurfaceRelation relation, // relation of container to parent
                    vector<ContainerLayout> layout,
                    vector<ContainerRelationEntry> relationships,
                    vector<ContainerView> views);

    // 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
    6: -> OnSurfaceFocused(string surface_id);

    // 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.
    7: RemoveSurface(string surface_id);

    // Reconnect the view in viewConnection.
    //
    // Called to reconnect views that have previously been added
    // to the StoryShell via addSurface, and then disconnected. a ViewOwner
    // connects to a child view and is notified if the view is available. If
    // it becomes unavailable it's disconnected. If a surface with a
    // disconnected view is to be shown again, ReconnectView is called.
    //
    // E.g. called in response to StoryShell calling RequestView().
    8: ReconnectView(ViewConnection view_connection);

    // 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 ViewOwner 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.
    9: UpdateSurface(ViewConnection view_connection, SurfaceInfo surface_info);
};

// A pair mapping the view owner to surface ID
struct ViewConnection {
    // The new view corresponding to the surface.
    fuchsia.ui.viewsv1token.ViewOwner owner;

    // The ID for the surface
    string surface_id;
};

// Contain metadata for a Surface
struct SurfaceInfo {
    // ID of the view that is parent of this Surface.
    string parent_id;

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

    // Information about the module populates the view.
    ModuleManifest? module_manifest;

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

// Maps the node_name to the specific mozart view resulting from resolving and
// launching the intent specified in a Container node
struct ContainerView {
    // Name by which this container node is referenced in container layout and
    // surface relationship specifications (cf. container.fidl)
    string node_name;

    // The new view resolved from the intent corresponding to node_name
    fuchsia.ui.viewsv1token.ViewOwner owner;
};

// This interface provides the StoryShell instance with everything it needs to
// know or be able to do about the Story. Not much right now, but we expect this
// to increase.
interface StoryShellContext {
    // Requests a Presentation connection from the SessionShell. See
    // SessionShellPresenationProvider in session_shell.fidl.
    1: GetPresentation(request<fuchsia.ui.policy.Presentation> request);

    // Starts watching Story shell's visual state.
    2: WatchVisualState(StoryVisualStateWatcher watcher);

    // Gets a Link instance that the story shell can use for persisting metadata.
    3: GetLink(request<Link> request);

    // Requests a view for a Surface.
    // Requests that a view for |surface_id| is provided through
    // StoryShell.ReconnectView().
    4: RequestView(string surface_id);

    // Notification that the Surface is no longer on screen.
    5: OnSurfaceOffScreen(string surface_id);
};

// Implemented by StoryShell to get notified about visual state changes.
interface StoryVisualStateWatcher {
    1: OnVisualStateChange(StoryVisualState visual_state);
};

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