// 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.

import 'dart:collection';
import 'package:meta/meta.dart';

import '../internal/tree/_surface_tree.dart';
import '../layout/layout_context.dart';
import '../layout/layout_types.dart';
import '../surface/surface.dart';

/// The CompositionDelegate maintains the model of surfaces participating in an
/// experience and their relationships. Using context such as viewport area,
/// surface metadata, etc., it determines a layout given a 'focused' surface.
class CompositionDelegate {
  /// The set of surfaces that are currently marked as 'hidden' in the
  /// experience - they are still present in the experience, but they will not
  /// be laid out until they have focusSurface() called on them.
  final Set<String> _hiddenSurfaces;

  /// The focus order of surfaces being laid out in the experience. Hiding
  /// removes a surface from the _focusedSurfaces Set and adds it to the
  /// _hiddenSurfaces Set.
  final LinkedHashSet<String> _focusedSurfaces = LinkedHashSet<String>();

  /// The context of the layout
  LayoutContext layoutContext;

  /// The tree recording the relationships between Surfaces in the experience.
  /// All Surfaces are represented here (by surfaceId) including Surfaces with
  /// no current relationships and Surfaces that are currently hidden.
  final SurfaceTree _surfaceTree;

  /// The default LayoutContext
  static const LayoutContext defaultContext =
      LayoutContext(size: Size(1280, 800));

  /// Constructor
  CompositionDelegate({
    this.layoutContext = defaultContext,
  })  : _hiddenSurfaces = <String>{},
        _surfaceTree = SurfaceTree();

  /// Add a Surface to the tree. [parentId] is an optional paramater used when
  /// this surface has a parent-child relationship with a [Surface] that is
  /// already in the experience - for example if this Surface was launched by
  /// that Surface.
  void addSurface({@required Surface surface, String parentId}) {
    _surfaceTree.add(surface: surface, parentId: parentId);
  }

  /// Destructively remove a Surface from the tree and the focused and hidden
  /// Surface sets: deletes the Surface from the experience. Any children of
  /// the removed Surface are preserved, relationships between those children
  /// and further descendents are also preserved, but any relationship between
  /// those children and ancestors is severed.
  void removeSurface({String surfaceId}) {
    _surfaceTree.remove(surfaceId: surfaceId);
    _focusedSurfaces.remove(surfaceId);
    _hiddenSurfaces.remove(surfaceId);
  }

  /// Brings the Surface with surfaceId into 'focus' - calls to getLayout will
  /// determine a layout starting from this Surface in the tree. The focused
  /// Surface is guaranteed to be shown. The Surface being focused is assumed
  /// to have already been added to the experience.
  void focusSurface({String surfaceId}) {
    // focus is the opposite of hide
    _hiddenSurfaces.remove(surfaceId);
    // bubble the surface to the top of the focus stack
    _focusedSurfaces
      ..remove(surfaceId)
      ..add(surfaceId);
  }

  /// Hides a Surface from the experience. Does not modify the topology of the
  /// tree, just marks one of the nodes as hidden, and does not use it in layout
  void hideSurface({String surfaceId}) {
    _focusedSurfaces.remove(surfaceId);
    _hiddenSurfaces.add(surfaceId);

    // TODO (djmurphy): handle "canHideSurface - dependency considerations"
  }

  /// Update the relationships or metadata for a Surface already in the tree.
  /// If the Surface is not yet in the tree this is a no-op.
  void update({Surface surface, String parentId}) {
    _surfaceTree.update(surface: surface, parentId: parentId);
  }

  /// Determines a layout given the current LayoutContext and focusedSurface, and
  /// returns a list of [Layer]s.
  ///
  /// Each [Layer] in the presentation holds a list of [LayoutElement]s that
  /// make up that Layer.
  ///
  /// The List is ordered from bottom up (as per Flutter Stack convention), so
  /// the upper-most layer of the presentation is the last element in the
  /// returned list.
  ///
  /// If the previousLayout is provided as an argument, it can be taken into
  /// consideration during layout determination. For example, a Presenter
  /// implementation may allow resizing of split points, which might be factored
  /// into subsequent layouts. (Currently unimplemented)
  ///
  /// For a scenario where layout is two layers, with a Single Surface 'C'
  /// occupying the entire back layer, and two Surfaces 'A' and 'B' occupying
  /// the foreground layer, split evenly:
  ///
  ///           XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX
  ///          XX                  XX XX                  XX
  ///         XX      XXX         XX XX     XXXXX        XX
  ///        XX     XX  XX       XX XX     XX  XX       XX
  ///       XX    XXXXXXXX      XX XX     XXXXX        XX
  ///      XX    XX    XX      XX XX     XX  XX       XX
  ///     XX    XX    XX      XX XX     XXXXXX       XX
  ///    XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX  XXX
  ///        XX                                         XX
  ///       XX                XXXX                     XX
  ///      XX               XX                        XX
  ///     XX               XX                        XX
  ///    XX               XX                        XX
  ///   XX                XXXXX                    XX
  ///  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  ///
  /// Then the returned layout would be (bottom up):
  /// '[
  ///   [
  ///     {"x":0,"y":0,"w":1280,"h":800,"surfaceId":"C"} // SurfaceLayout
  ///   ], // Layer
  ///   [
  ///     {"x":0,"y":0,"w":640,"h":800,"surfaceId":"A"},   // SurfaceLayout
  ///     {"x":640","y":0,"w":640,"h":800,"surfaceId":"B"} // SurfaceLayout
  ///   ] // Layer
  /// ] // List<Layer>'
  List<Layer> getLayout({List<Layer> previousLayout}) {
    // TODO(djmurphy): complete logic - this is placeholder to unblock work
    if (_surfaceTree.isEmpty) {
      return <Layer>[];
    }
    List<Layer> layout = <Layer>[];
    SurfaceTree spanningTree = _surfaceTree.spanningTree(
      startNodeId: _focusedSurfaces.last,
      condition: (node) => true,
    );
    int spanningTreeSize = spanningTree.length;
    if (spanningTreeSize > 1) {
      _splitEvenly(layout, spanningTree, spanningTreeSize);
    } else {
      // Relies purely on the focused surfaces rather than what's in the graph.
      // TODO(jphsiao/djmurphy) expand this to take into account the surface graph.
      for (String id in _focusedSurfaces.toList()) {
        layout.add(
          Layer(
            element: SurfaceLayout(
              x: 0.0,
              y: 0.0,
              w: layoutContext.size.width,
              h: layoutContext.size.height,
              surfaceId: id,
            ),
          ),
        );
      }
    }
    return layout;
  }

  List<Layer> _splitEvenly(
      List<Layer> layout, SurfaceTree spanningTree, int spanningTreeSize) {
    Layer layer = Layer();
    int surfaceIndex = 0;
    double splitSize = layoutContext.size.width / spanningTreeSize;
    for (Surface surface in spanningTree) {
      layer.add(SurfaceLayout(
        x: surfaceIndex * splitSize,
        y: 0.0,
        w: splitSize,
        h: layoutContext.size.height,
        surfaceId: surface.surfaceId,
      ));
      surfaceIndex += 1;
    }
    layout.add(layer);
    return layout;
  }
}
