// =============================================================================
// TOOLS / #FUNCTIONS
// =============================================================================

// Rounding
// ==============================================

// Three functions to round numbers to a specified decimal place.
// @author Takeru Suzuki (gist.github.com/terkel/4373420)

// decimal-round()
// ------------------------------------

// Round a number to specified digits.
// See `docs/` for usage.
@function decimal-round ($number, $digits: 0, $mode: round) {
  $n: 1;
  // $number must be a number
  @if type-of($number) != number {
    @warn "#{ $number } is not a number.";
    @return $number;
  }
  // $digits must be a unitless number
  @if type-of($digits) != number {
    @warn "#{ $digits } is not a number.";
    @return $number;
  } @else if not unitless($digits) {
    @warn "#{ $digits } has a unit.";
    @return $number;
  }

  @for $i from 1 through $digits {
    $n: $n * 10;
  }

  @if $mode == round {
    @return round($number * $n) / $n;
  } @else if $mode == ceil {
    @return ceil($number * $n) / $n;
  } @else if $mode == floor {
    @return floor($number * $n) / $n;
  } @else {
    @warn "#{ $mode } is undefined keyword.";
    @return $number;
  }
}

// decimal-ceil()
// ------------------------------------

// Ceil a number to specified digits.
// See `docs/` for usage.
@function decimal-ceil ($number, $digits: 0) {
  @return decimal-round($number, $digits, ceil);
}

// decimal-floor()
// ------------------------------------

// Floor a number to specified digits.
// See `docs/` for usage.
@function decimal-floor ($number, $digits: 0) {
  @return decimal-round($number, $digits, floor);
}

// Maps
// ==============================================

// map-get-deep()
// ------------------------------------

// Access nested map values.
// @author Hugo Giraudel (with modifications)
// See `docs/` for usage.
@function map-get-deep($map, $keys...) {
  @if map-has-keys-deep($map, $keys...) {
    @each $key in $keys {
      $map: map-get($map, $key);
    }

    @return $map;
  }

  @warn "Unknown keys of `#{$keys}` in the defined map";
  @return null;
}

// map-has-keys-deep()
// ------------------------------------

// Check for keys in nested maps.
// @author Hugo Giraudel
// See `docs/` for usage.
@function map-has-keys-deep($map, $keys...) {
  @each $key in $keys {
    @if not map-has-key($map, $key) {
      @return false;
    }
    $map: map-get($map, $key);
  }

  @return true;
}

// multi-map-merge()
// ------------------------------------

// Merge mutiple maps together
@function multi-map-merge($maps...) {
  $group: ();

  @each $map in $maps {
    $group: map-merge($group, $map);
  }

  @return $group;
}

// Map Shortcuts
// ==============================================

// color()
// ------------------------------------

// Function to get color from `$colors` instead of using `map-get`.
// See `docs/` for usage.
@function color($key) {
  @return map-get-deep($colors, $key);
}

// z-index()
// ------------------------------------

// Function to get value from `$z-index` instead of using `map-get`.
// See `docs/` for usage.
@function z-index($key) {
  @return map-get-deep($z-index, $key);
}

// Conversion
// ==============================================

// convert-to-em()
// ------------------------------------

// Converts any `px` or `rem` value to `em`.
// See `docs/` for usage.
@function convert-to-em($value, $base-font-size: $global-font-size) {
  @if unit($value) == "px" {
    @return (strip-unit($value / $base-font-size)) * 1em;
  }

  @if unit($value) == "rem" {
    @return strip-unit($value) * 1em;
  } @else {
    @warn "Value must be em or px.";
  }
}

// reverse()
// ------------------------------------

// Function to reverse list of values.
// See `docs/` for usage.
@function reverse($list) {
  $reversed-list: ();

  @for $index from length($list)*-1 through -1 {
    $reversed-list: append($reversed-list, nth($list, abs($index)), comma);
  }

  @return $reversed-list;
}

// strip-unit()
// ------------------------------------

// Function to remove the unit from a value.
// See `docs/` for usage.
@function strip-unit($num) {
  @if type_of($num) == number {
    @return $num / ($num * 0 + 1);
  } @else {
    @warn "Value must be a number i.e. 12, 24px etc.";
  }
}

// Private / Framework Only
// ==============================================

// _important()
// ------------------------------------

// Function to conditionally return !important rule.
@function _important($important: true) {
  @if $important {
    @return " !important";
  } @else {
    @return null;
  }
}
