/// Created by @Haoyi on 2021/7/7

part of "design.dart";

abstract class DesignRect extends DesignObject<Rect> {
  Rect get rect;

  double get width;

  double get height;

  Offset get topLeft;

  Offset get bottomLeft;

  Offset get topRight;

  Offset get bottomRight;

  Offset get center;

  double get top;

  double get bottom;

  double get right;

  double get left;

  DesignField get topField;

  DesignField get leftField;

  DesignField get rightField;

  DesignField get bottomField;
}

class _DesignFieldRect extends DesignRect {
  final DesignField leftField;
  final DesignField topField;
  final DesignField rightField;
  final DesignField bottomField;

  Rect? _rect;

  Rect get rect => _rect!;

  _DesignFieldRect.fromLTRB(this.leftField, this.topField, this.rightField, this.bottomField);

  @override
  double get width => rect.width;

  @override
  double get height => rect.height;

  @override
  Offset get topLeft => rect.topLeft;

  @override
  Offset get bottomLeft => rect.bottomLeft;

  @override
  Offset get topRight => rect.topRight;

  @override
  Offset get bottomRight => rect.bottomRight;

  @override
  Offset get center => rect.center;

  @override
  double get top => rect.top;

  @override
  double get bottom => rect.bottom;

  @override
  double get right => rect.right;

  @override
  double get left => rect.left;

  @override
  Rect measure(_DeviceMetrics metrics) {
    if (_rect == null) {
      final l = leftField.measure(metrics);
      final t = topField.measure(metrics);
      final r = rightField.measure(metrics);
      final b = bottomField.measure(metrics);
      _rect = Rect.fromLTRB(l, t, r, b);
    }
    return _rect!;
  }
}

class _DesignExplicitRect extends DesignRect {
  final double designLeft;
  final double designTop;
  final double designRight;
  final double designBottom;

  Rect? _rect;

  @override
  Rect get rect => _rect!;

  _DesignExplicitRect.fromLTRB(
      this.designLeft, this.designTop, this.designRight, this.designBottom);

  @override
  double get width => rect.width;

  @override
  double get height => rect.height;

  @override
  Offset get topLeft => rect.topLeft;

  @override
  Offset get bottomLeft => rect.bottomLeft;

  @override
  Offset get topRight => rect.topRight;

  @override
  Offset get bottomRight => rect.bottomRight;

  @override
  Offset get center => rect.center;

  @override
  DesignField get bottomField => DesignField._height(designBottom);

  @override
  DesignField get leftField => DesignField._width(designLeft);

  @override
  DesignField get rightField => DesignField._width(designRight);

  @override
  DesignField get topField => DesignField._height(designTop);

  @override
  double get top => rect.top;

  @override
  double get bottom => rect.bottom;

  @override
  double get right => rect.right;

  @override
  double get left => rect.left;

  @override
  Rect measure(_DeviceMetrics metrics) {
    if (_rect == null) {
      final l = DesignField._calculate(_DesignMethod.width, metrics, designLeft);
      final t = DesignField._calculate(_DesignMethod.height, metrics, designTop);
      final r = DesignField._calculate(_DesignMethod.width, metrics, designRight);
      final b = DesignField._calculate(_DesignMethod.height, metrics, designBottom);
      _rect = Rect.fromLTRB(l, t, r, b);
    }
    return _rect!;
  }
}
