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

// @dart = 2.9

part of layout;

// This file has classes representing the grid sizing functions

/**
 * Represents the sizing function used for the min or max of a row or column.
 */
// TODO(jmesserly): rename to GridSizing, or make internal
class SizingFunction {
  const SizingFunction();

  bool get isContentSized => isMinContentSized || isMaxContentSized;
  bool get isMinContentSized => false;
  bool get isMaxContentSized => false;
  bool get isFraction => false;

  num resolveLength(num gridSize) => 0;

  num get fractionValue => 0;

  // TODO(jmesserly): this is only needed because FixedSizing is mutable
  SizingFunction clone() => this;
}

/**
 * Fixed size reprensents a length as defined by CSS3 Values spec.
 * Can also be a percentage of the Grid element's logical width (for columns)
 * or logical height (for rows). When the width or height of the Grid element
 * is undefined, the percentage is ignored and the Grid Track will be
 * auto-sized.
 */
class FixedSizing extends SizingFunction {
  final String units;
  final num length;

  // TODO(jmesserly): kind of ugly to have this mutable property here, but
  // we need to correctly track whether we're content sized during a layout
  bool _contentSized;

  FixedSizing(this.length, [this.units = 'px']) : _contentSized = false {
    if (units != 'px' && units != '%') {
      // TODO(jmesserly): support other unit types
      throw new UnsupportedError('Units other than px and %');
    }
  }

  // TODO(jmesserly): this is only needed because of our mutable property
  FixedSizing clone() => new FixedSizing(length, units);

  bool get isMinContentSized => _contentSized;

  num resolveLength(num gridSize) {
    if (units == '%') {
      if (gridSize == null) {
        // Use content size when the grid doesn't have an absolute size in this
        // dimension
        _contentSized = true;
        return 0;
      }
      _contentSized = false;
      return (length / 100) * gridSize;
    } else {
      return length;
    }
  }

  String toString() => 'FixedSizing: ${length}${units} $_contentSized';
}

/**
 * Fraction is a non-negative floating-point number followed by 'fr'. Each
 * fraction value takes a share of the remaining space proportional to its
 * number.
 */
class FractionSizing extends SizingFunction {
  final num fractionValue;
  FractionSizing(this.fractionValue);

  bool get isFraction => true;

  String toString() => 'FixedSizing: ${fractionValue}fr';
}

class MinContentSizing extends SizingFunction {
  const MinContentSizing();

  bool get isMinContentSized => true;

  String toString() => 'MinContentSizing';
}

class MaxContentSizing extends SizingFunction {
  const MaxContentSizing();

  bool get isMaxContentSized {
    return true;
  }

  String toString() => 'MaxContentSizing';
}

/** The min and max sizing functions for a track. */
class TrackSizing {
  /** The min sizing function for the track. */
  final SizingFunction min;

  /** The min sizing function for the track. */
  final SizingFunction max;

  const TrackSizing.auto()
      : min = const MinContentSizing(),
        max = const MaxContentSizing();

  TrackSizing(this.min, this.max) {}

  // TODO(jmesserly): this is only needed because FixedSizing is mutable
  TrackSizing clone() => new TrackSizing(min.clone(), max.clone());
}

/** Represents a GridTrack breadth property. */
// TODO(jmesserly): these classes could be replaced with reflection/mirrors
abstract class _BreadthAccumulator {
  void setSize(GridTrack t, num value);
  num getSize(GridTrack t);

  SizingFunction getSizingFunction(GridTrack t);
}

class _UsedBreadthAccumulator implements _BreadthAccumulator {
  const _UsedBreadthAccumulator();

  void setSize(GridTrack t, num value) {
    t.usedBreadth = value;
  }

  num getSize(GridTrack t) => t.usedBreadth;

  SizingFunction getSizingFunction(GridTrack t) => t.minSizing;
}

class _MaxBreadthAccumulator implements _BreadthAccumulator {
  const _MaxBreadthAccumulator();

  void setSize(GridTrack t, num value) {
    t.maxBreadth = value;
  }

  num getSize(GridTrack t) => t.maxBreadth;

  SizingFunction getSizingFunction(GridTrack t) => t.maxSizing;
}
