// Internal counter for creating unique keyframe names
$-mui-custom: 0;

/// Creates a keyframe from one or more effect functions. Use this function instead of `mui-animation` if you want to create a keyframe animation *without* automatically assigning it to the element.
/// @param {String} $name - Name of the keyframe.
/// @param {Function} $effects... - One or more effect functions to build the keyframe with.
@mixin mui-keyframes($name, $effects...) {
  $obj: -mui-process-args($effects...);
  $obj: map-remove($obj, name);

  @keyframes #{$name} {
    // Now iterate through each keyframe percentage
    @each $pct, $props in $obj {
      #{-mui-keyframe-pct($pct)} {
        // Lastly, iterate through each CSS property within a percentage and print it out
        @each $prop, $value in $props {
          #{$prop}: #{$value};
        }
      }
    }
  }
}

/// Creates a string for a CSS keyframe, by converting a list of numbers to a comma-separated list of percentage values.
/// @param {Number|List} $input - List of numbers to use.
/// @return {String} A set of comma-separated percentage values.
/// @access private
@function -mui-keyframe-pct($input) {
  $output: ();

  @if type-of($input) == 'number' {
    $output: ($input * 1%);
  } @else if type-of($input) == 'list' {
    @each $i in $input {
      $output: append($output, ($i * 1%), comma);
    }
  }

  @return $output;
}

/// Prints the CSS properties from a specific key in a keyframes map. Used to borrow CSS from keyframe functions for use in transitions.
/// @param {Map} $kf - Keyframe map to extract from.
/// @param {Number} $key - Key in the map to print the CSS of.
/// @access private
@mixin -mui-keyframe-get($kf, $key) {
  $map: map-get($kf, $key);

  @each $prop, $value in $map or () {
    // Some keyframe maps store transforms as quoted strings
    @if type-of($value) == 'string' {
      $value: unquote($value);
    }
    #{$prop}: $value;
  }
}

/// Reformats a map containing keys with a list of values, so that each key is a single value.
/// @param {Map} $map - Map to split up.
/// @return {Map} A reformatted map.
/// @access private
@function -mui-keyframe-split($map) {
  $new-map: ();

  // Split keys with multiple values into individual keys
  @each $key, $item in $map {
    $key-type: type-of($key);

    @if $key-type == 'number' {
      $new-map: map-merge($new-map, ($key: $item));
    } @else if $key-type == 'list' {
      @each $k in $key {
        $new-map: map-merge($new-map, ($k: $item));
      }
    }
  }

  @return $new-map;
}

/// Combines a series of keyframe objects into one.
/// @param {Map} $maps... - A series of maps to merge, as individual parameters.
/// @return {Map} A combined keyframe object.
/// @access private
@function -mui-keyframe-combine($maps...) {
  $new-map: ();

  // Iterate through each map passed in
  @each $map in $maps {
    @if type-of($map == 'string') {
      $map: call($map);
    }

    $map: -mui-keyframe-split($map);

    // Iterate through each keyframe in the map
    // $key is the keyframe percentage
    // $value is a map of CSS properties
    @each $key, $value in $map {
      $new-value: ();

      @if map-has-key($new-map, $key) {
        // If the map already has the keyframe %, append the new property
        $new-value: -mui-merge-properties(map-get($new-map, $key), $value);
      } @else {
        // Otherwise, create a new map with the new property
        $new-value: $value;
      }

      // Finally, merge the modified keyframe value into the output map
      $new-map: map-merge($new-map, ($key: $new-value));
    }
  }

  // Make a name for the keyframes
  $-mui-custom: $-mui-custom + 1 !global;
  $map-name: (name: 'custom-#{$-mui-custom}');
  $new-map: map-merge($new-map, $map-name);

  @return $new-map;
}

/// Combines two maps of CSS properties into one map. If both maps have a transform property, the values from each will be combined into one property.
/// @param {Map} $one - First map to merge.
/// @param {Map} $two - Second map to merge.
/// @return {Map} A combined map.
/// @access private
@function -mui-merge-properties($one, $two) {
  @if map-has-key($one, transform) and map-has-key($two, transform) {
    $transform: join(map-get($one, transform), map-get($two, transform));
    $one: map-merge($one, (transform: $transform));
    $two: map-remove($two, transform);
  }

  @return map-merge($one, $two);
}
