// 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 =
      const LayoutContext(size: const Size(1280, 800));

  /// Constructor
  CompositionDelegate({
    this.layoutContext = defaultContext,
  })  : _hiddenSurfaces = <String>{},
        _surfaceTree = new 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 = new 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;
  }
}
