////
/// @group tile-grid
/// Creates a CSS grid with items that have matching aspect ratios. Reflows to fit as many items as can be fit withing current grid's width by default. Allows passing static styles to create fixed number of columns per row. Static styles are set adaptively and can adjust the number of columns at different breakpoints.
////

@use "sass:map";
@use "sass:list";

@use "../selector";
@use "../breakpoint";
@use "../utils";


/// Module Settings
/// @type Map
/// @prop {CssValue} aspect-ratio [list.slash(4, 3)]
/// @prop {Number} gap [1rem] The gap for the tile grid.
/// @prop {Number} width [10em]

$config: (
  "aspect-ratio" : list.slash(4, 3),
  "gap" : 1rem,
  "width" : 10em,
) !default;

/// Alternate Sizes for reflowable grid
/// - Map of preferred width for columns and optional aspect-ratio for item
/// @type Map

$sizes: (
  "large" : (
    "width" : 20em,
  )
) !default;

/// Static grid width styles
/// @type Map

$static-sizes: (
  "static" : (
    "default" : (
      "columns" : 1,
      "gap" : null,
      "aspect-ratio" : list.slash(4, 3)
    ),
    "small" : (
      "direction" : "min",
      "columns" : 2,
      "gap" : null,
    ),
    "medium" : (
      "direction" : "min",
      "columns" : 3,
      "gap" : null,
    ),
  ),
  "static-wide" : (
    "default" : (
      "columns" : 1,
      "gap" : null,
      "aspect-ratio" : list.slash(4, 3)
    ),
    "small" : (
      "direction" : "min",
      "columns" : 2,
      "gap" : null,
    ),
  )
) !default;

/// Change modules $config
/// @param {Map} $changes Map of changes
/// @example scss
///   @include ulu.component-tile-grid-set(( "property" : value ));

@mixin set($changes) {
  $config: map.merge($config, $changes) !global;
}

/// Set fixed sizes map
/// @param {Map} $changes Map of changes
/// @param {String} $merge-mode Merge mode see utils.map-merge() [null|"deep"|"overwrite"]

@mixin set-static($changes, $merge-mode: null) {
  $static-sizes: utils.map-merge($static-sizes, $changes, $merge-mode) !global;
}

/// Set sizes map
/// @param {Map} $changes Map of changes
/// @param {String} $merge-mode Merge mode see utils.map-merge() [null|"deep"|"overwrite"]

@mixin set-sizes($changes, $merge-mode: null) {
  $sizes: utils.map-merge($sizes, $changes, $merge-mode) !global;
}

/// Get a config option
/// @param {Map} $name Name of property
/// @example scss
///   @include ulu.component-tile-grid-get("property");

@function get($name) {
  @return utils.require-map-get($config, $name, "component-tile-grid [config]");
}

/// Output component stylesheet
/// @example scss
///  @include ulu.component-tile-grid-styles();

@mixin styles {
  $prefix: selector.class("tile-grid");

  #{ $prefix } {
    display: grid;
    gap: get("gap");
    grid-template-columns: repeat(auto-fit, minmax(get("width"), 1fr));
    grid-auto-rows: 1fr;
  }
  #{ $prefix }__item {
    aspect-ratio: get("aspect-ratio");
  }
  // Use with fill-context, creates the space for images/etc
  #{ $prefix }--expanded {
    #{ $prefix }__item {
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
  }

  // Print out reflowable sizes modifiers
  @each $modifier, $props in $sizes {
    $width: map.get($props, "width");
    $gap: map.get($props, "gap");
    $aspect-ratio: map.get($props, "aspect-ratio");
    
    @if ($width or $gap) {
      #{ $prefix }--#{ $modifier } {
        @if utils.map-has($props, "width") {
          grid-template-columns: repeat(auto-fit, minmax($width, 1fr));
        }
        gap: $gap;
      }
    }
    @if $aspect-ratio {
      #{ $prefix }--#{ $modifier } #{ $prefix }__item {
        aspect-ratio: $aspect-ratio;
      }
    }
  }

  // Print out the static column styles
  // - Adaptive column count per breakpoint, equal widths
  @each $modifier, $breakpoints in $static-sizes {
    @include breakpoint.from-each($breakpoints) using ($props) {
      #{ $prefix }--#{ $modifier } {
        grid-template-columns: repeat(map.get($props, "columns"), 1fr);
        gap: map.get($props, "gap");
      }
      @if utils.map-contains-any($props, ("aspect-ratio",)) {
        #{ $prefix }__item {
          aspect-ratio: map.get($props, "aspect-ratio");
        }
      }
    }
  }

  // Modifier to force no gap on grid
  #{ $prefix }--no-gap {
    gap: 0 !important;
  }
}

