// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of layout;

/// The interface that the layout algorithms use to talk to the view. */
abstract class Positionable {
  ViewLayout get layout;

  /// Gets our custom CSS properties, as provided by the CSS preprocessor. */
  Map<String, String> get customStyle;

  /// Gets the root DOM used for layout. */
  Element get node;

  /// Gets the collection of child views. */
  Iterable<Positionable> get childViews;

  /// Causes a view to layout its children. */
  void doLayout();
}

/// Caches the layout parameters that were specified in CSS during a layout
/// computation. These values are immutable during a layout.
class LayoutParams {
  // TODO(jmesserly): should be const, but there's a bug in DartC preventing us
  // from calling "window." in an initializer. See b/5332777
  CssStyleDeclaration? style;

  int? get layer => 0;

  LayoutParams(Element node) {
    style = node.getComputedStyle();
  }
}

// TODO(jmesserly): enums would really help here
class Dimension {
  // TODO(jmesserly): perhaps this should be X and Y
  static const WIDTH = Dimension._internal('width');
  static const HEIGHT = Dimension._internal('height');

  final String name; // for debugging
  const Dimension._internal(this.name);
}

class ContentSizeMode {
  /// Minimum content size, e.g. min-width and min-height in CSS. */
  static const MIN = ContentSizeMode._internal('min');

  /// Maximum content size, e.g. min-width and min-height in CSS. */
  static const MAX = ContentSizeMode._internal('max');

  // TODO(jmesserly): we probably want some sort of "auto" or "best fit" mode
  // Don't need it yet though.

  final String name; // for debugging
  const ContentSizeMode._internal(this.name);
}

/// Abstract base class for View layout. Tracks relevant layout state.
/// This code was inspired by code in Android's View.java; it's needed for the
/// rest of the layout system.
class ViewLayout {
  /// The layout parameters associated with this view and used by the parent
  /// to determine how this view should be laid out.
  LayoutParams? layoutParams;
  int? _offsetWidth;
  int? _offsetHeight;

  /// The view that this layout belongs to. */
  final Positionable view;

  /// To get a perforant positioning model on top of the DOM, we read all
  /// properties in the first pass while computing positions. Then we have a
  /// second pass that actually moves everything.
  int? _measuredLeft, _measuredTop, _measuredWidth, _measuredHeight;

  ViewLayout(this.view);

  /// Creates the appropriate view layout, depending on the properties.
  // TODO(jmesserly): we should support user defined layouts somehow. Perhaps
  // registered with a LayoutProvider.
  factory ViewLayout.fromView(Positionable view) {
    if (hasCustomLayout(view)) {
      return GridLayout(view);
    } else {
      return ViewLayout(view);
    }
  }

  static bool hasCustomLayout(Positionable view) {
    return view.customStyle['display'] == "-dart-grid";
  }

  CssStyleDeclaration? get _style => layoutParams!.style;

  void cacheExistingBrowserLayout() {
    _offsetWidth = view.node.offset.width as int?;
    _offsetHeight = view.node.offset.height as int?;
  }

  int? get currentWidth {
    return _offsetWidth;
  }

  int? get currentHeight {
    return _offsetHeight;
  }

  int get borderLeftWidth => _toPixels(_style!.borderLeftWidth);
  int get borderTopWidth => _toPixels(_style!.borderTopWidth);
  int get borderRightWidth => _toPixels(_style!.borderRightWidth);
  int get borderBottomWidth => _toPixels(_style!.borderBottomWidth);
  int get borderWidth => borderLeftWidth + borderRightWidth;
  int get borderHeight => borderTopWidth + borderBottomWidth;

  /// Implements the custom layout computation. */
  void measureLayout(Future<Size> size, Completer<bool>? changed) {}

  /// Positions the view within its parent container.
  /// Also performs a layout of its children.
  void setBounds(int? left, int? top, int width, int height) {
    assert(width >= 0 && height >= 0);

    _measuredLeft = left;
    _measuredTop = top;

    // Note: we need to save the client height
    _measuredWidth = width - borderWidth;
    _measuredHeight = height - borderHeight;
    final completer = Completer<Size>();
    completer.complete(Size(_measuredWidth!, _measuredHeight!));
    measureLayout(completer.future, null);
  }

  /// Applies the layout to the node. */
  void applyLayout() {
    if (_measuredLeft != null) {
      // TODO(jmesserly): benchmark the performance of this DOM interaction
      final style = view.node.style;
      style.position = 'absolute';
      style.left = '${_measuredLeft}px';
      style.top = '${_measuredTop}px';
      style.width = '${_measuredWidth}px';
      style.height = '${_measuredHeight}px';
      style.zIndex = '${layoutParams!.layer}';

      _measuredLeft = null;
      _measuredTop = null;
      _measuredWidth = null;
      _measuredHeight = null;

      // Ensure we can handle our custom layout when it is a child of a
      // DOM-positioned node. For example, say we have a View tree like this:
      //
      //   ViewWithLayout   <-- uses our layout engine
      //     childView1     <-- is positioned by our layout engine, but uses
      //                        HTML layout internally
      //       childOfChild <-- uses our layout engine for its own children
      if (!hasCustomLayout(view)) {
        for (final child in view.childViews) {
          child.doLayout();
        }
      }
    }
  }

  int? measureContent(ViewLayout parent, Dimension? dimension,
      [ContentSizeMode? mode]) {
    if (dimension == Dimension.WIDTH) {
      return measureWidth(parent, mode);
    } else if (dimension == Dimension.HEIGHT) {
      return measureHeight(parent, mode);
    }
    return null;
  }

  int? measureWidth(ViewLayout parent, ContentSizeMode? mode) {
    final style = layoutParams!.style;
    if (mode == ContentSizeMode.MIN) {
      return _styleToPixels(style!.minWidth, currentWidth, parent.currentWidth);
    } else if (mode == ContentSizeMode.MAX) {
      return _styleToPixels(style!.maxWidth, currentWidth, parent.currentWidth);
    }
    return null;
  }

  int? measureHeight(ViewLayout parent, ContentSizeMode? mode) {
    final style = layoutParams!.style;
    if (mode == ContentSizeMode.MIN) {
      return _styleToPixels(
          style!.minHeight, currentHeight, parent.currentHeight);
    } else if (mode == ContentSizeMode.MAX) {
      return _styleToPixels(
          style!.maxHeight, currentHeight, parent.currentHeight);
    }
    return null;
  }

  static int _toPixels(String style) {
    if (style.endsWith('px')) {
      return int.parse(style.substring(0, style.length - 2));
    } else {
      // TODO(jmesserly): other size units
      throw UnsupportedError('Unknown min/max content size format: "$style"');
    }
  }

  static int? _styleToPixels(String style, num? size, num? parentSize) {
    if (style == 'none') {
      // For an unset max-content size, use the actual size
      return size as int?;
    }
    if (style.endsWith('%')) {
      num percent = double.parse(style.substring(0, style.length - 1));
      return ((percent / 100) * parentSize!).toInt();
    }
    return _toPixels(style);
  }
}
