
/* MAP */

@function map-previous ( $map, $key ) {

  $all: map-keys( $map );
  $index: index( $all, $key );

  @return if( $index > 1, nth( $all, $index - 1 ), null );

}

@function map-next ( $map, $key ) {

  $all: map-keys( $map );
  $index: index( $all, $key );

  @return if( $index < length( $all ), nth( $all, $index + 1 ), null );

}

@function map-set ( $map, $key, $value ) {

  $new: ( $key: $value );

  @return map-merge( $map, $new );

}

/* DEEP */

//SOURCE: https://css-tricks.com/snippets/sass/deep-getset-maps

@function map-deep-get ( $map, $keys... ) {

  @each $key in $keys {
    $map: map-get( $map, $key );
  }

  @return $map;

}

//SOURCE: https://css-tricks.com/snippets/sass/deep-getset-maps

@function map-deep-set ( $map, $keys, $value ) {

  $maps: ($map,);
  $result: null;

  // If the last key is a map already warn the user we will be overriding it with $value

  @if type-of( nth( $keys, -1 ) ) == 'map' {
    @warn 'The last key you specified is a map; it will be overrided with `#{$value}`';
  }

  // If `$keys` is a single key just merge and return

  @if length( $keys ) == 1 {
    @return map-merge( $map, ( $keys: $value ) );
  }

  // Loop from the first to the second to last key from `$keys` store the associated map to this key in the $maps list if the key doesn't exist, throw an error

  @for $i from 1 through length( $keys ) - 1 {

    $current-key: nth( $keys, $i );
    $current-map: nth( $maps, -1 );
    $current-get: map-get( $current-map, $current-key );

    @if $current-get == null {
      @error 'Key `#{$key}` does\'t exist at current level in map';
    }

    $maps: append( $maps, $current-get );

  }

  // Loop from the last map to the first one merge it with the previous one

  @for $i from length( $maps ) through 1 {
    $current-map: nth( $maps, $i );
    $current-key: nth( $keys, $i );
    $current-val: if( $i == length( $maps ), $value, $result );
    $result: map-merge ( $current-map, ( $current-key: $current-val ) );
  }

  // Return result

  @return $result;

}
