/* Sass Functions go here */

/// Remove the unit of a length
/// @param {Number} $number - Number to remove unit from
/// @return {Number} - Unitless number
@function strip-unit($number) {
	@if type-of($number) == 'number' and not unitless($number) {
		@return $number / ($number * 0 + 1);
	}

	@return $number;
}

// ----
// Sass (v3.3.14)
// Compass (v1.0.0.rc.1)
// ----

@function pow($x, $y) {
  $ret: 1;

  @if $y > 0 {
    @for $i from 1 through $y {
        $ret: $ret * $x;
    }
  }

  @else {
    @for $i from $y to 0 {
        $ret: $ret / $x;
    }
  }

  @return $ret;
}

/**
 * Map deep get
 * @author Hugo Giraudel
 * @access public
 * @param {Map} $map - Map
 * @param {Arglist} $keys - Key chain
 * @return {*} - Desired value
 *
 * Example:
 * $m-breakpoint: map-deep-get($__prefix-default-config, "layouts", "M");
 */
@function map-deep-get($map, $keys...) {
    @each $key in $keys {
        $map: map-get($map, $key);
    }
    @return $map;
}

/**
 * Deep set function to set a value in nested maps
 * @author Hugo Giraudel
 * @access public
 * @param {Map} $map - Map
 * @param {List} $keys -  Key chaine
 * @param {*} $value - Value to assign
 * @return {Map}
 *
 * Example:
 * $__prefix-default-config: map-deep-set($__prefix-default-config, "layouts" "M", 650px);
 */
@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}` doesn'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;
}

/**
 * jQuery-style extend function
 * - Child themes can use this function to `reset` the values in
 *   config maps without editing the `master` Sass files.
 * - src: https://www.sitepoint.com/extra-map-functions-sass/
 * - About `map-merge()`:
 * - - only takes 2 arguments
 * - - is not recursive
 * @param {Map} $map - first map
 * @param {ArgList} $maps - other maps
 * @param {Bool} $deep - recursive mode
 * @return {Map}
 *
 * Examples:

$grid-configuration-default: (
	'columns': 12,
	'layouts': (
		'small': 800px,
		'medium': 1000px,
		'large': 1200px,
	),
);

$grid-configuration-custom: (
	'layouts': (
		'large': 1300px,
		'huge': 1500px
	),
);

$grid-configuration-user: (
	'direction': 'ltr',
	'columns': 16,
	'layouts': (
		'large': 1300px,
		'huge': 1500px
	),
);

// $deep: false
$grid-configuration: map-extend($grid-configuration-default, $grid-configuration-custom, $grid-configuration-user);
// --> ("columns": 16, "layouts": (("large": 1300px, "huge": 1500px)), "direction": "ltr")

// $deep: true
$grid-configuration: map-extend($grid-configuration-default, $grid-configuration-custom, $grid-configuration-user, true);
// --> ("columns": 16, "layouts": (("small": 800px, "medium": 1000px, "large": 1300px, "huge": 1500px)), "direction": "ltr")

 */
@function map-extend($map, $maps.../*, $deep */) {
	$last: nth($maps, -1);
	$deep: $last == true;
	$max: if($deep, length($maps) - 1, length($maps));

	// Loop through all maps in $maps...
	@for $i from 1 through $max {
		// Store current map
		$current: nth($maps, $i);

		// If not in deep mode, simply merge current map with map
		@if not $deep {
			$map: map-merge($map, $current);
		} @else {
			// If in deep mode, loop through all tuples in current map
			@each $key, $value in $current {

				// If value is a nested map and same key from map is a nested map as well
				@if type-of($value) == "map" and type-of(map-get($map, $key)) == "map" {
					// Recursive extend
					$value: map-extend(map-get($map, $key), $value, true);
				}

				// Merge current tuple with map
				$map: map-merge($map, ($key: $value));
			}
		}
	}

	@return $map;
}
