
// The browser usage threshold for features that gracefully degrade
// Defaults to 1 user in 1,000.
$graceful-usage-threshold: 0.1 !default;

$debug-browser-support: false !default;

// @private
$default-capability-options: (
        (full-support: 1),
        (partial-support: 1)
);

// Yields to the mixin content once for each prefix required.
// The current prefix is set to the $current-prefix global for use by the included content.
// Also yields to the content once with $current-prefix set to null for the official version
// as long as there's not already a prefix in scope.
@mixin with-each-prefix($capability, $threshold) {
  @each $prefix, $should-use-prefix in prefixes-for-capability($capability, $threshold) {
    @if $should-use-prefix {
      @if $debug-browser-support and type-of($should-use-prefix) == list {
        /* Capability #{$capability} is prefixed with #{$prefix} because #{$should-use-prefix} is required. */
      } @else if $debug-browser-support and type-of($should-use-prefix) == number {
        /* Capability #{$capability} is prefixed with #{$prefix} because #{$should-use-prefix}% of users need it which is more than the threshold of #{$threshold}%. */
      }
      @include with-prefix($prefix) {
        @include with-browser-ranges($capability) {
          @content;
        }
      }
    } @else if $debug-browser-support {
      /* Capability #{$capability} is not prefixed with #{$prefix} because #{prefix-usage($prefix, $capability, $capability-options)}% of users are affected which is less than the threshold of #{$threshold}. */
    }
  }
  @include with-prefix(null) {
    @include with-browser-ranges($capability) {
      @content;
    }
  }
}

// If there's a prefix context in scope, this will only output the content if the prefix matches.
// Otherwise, sets the current prefix scope and outputs the content.
@mixin with-prefix($prefix) {
  @if $current-prefix or $prefix-context {
    @if $current-prefix == $prefix or $prefix-context == $prefix {
      @if $debug-browser-support {
        @if $prefix {
          /* content for #{$prefix} because #{$current-prefix or $prefix-context} is already in scope. */
        } @else {
          /* unprefixed content. #{$current-prefix or $prefix-context} is already in scope. */
        }
      }
      $old-prefix-context: $prefix-context;
      $old-prefix: $current-prefix;
      $prefix-context: $prefix-context or $current-prefix !global;
      $current-prefix: $prefix !global;
      @content;
      $prefix-context: $old-prefix-context !global;
      $current-prefix: $old-prefix !global;
    } @else if $prefix == null {
      $old-prefix-context: $prefix-context;
      $prefix-context: $prefix-context or $current-prefix !global;
      $current-prefix: null !global;
      @if $debug-browser-support {
        /* Content for official syntax. Prefix context is still #{$prefix-context}. */
      }
      @content;
      $current-prefix: $prefix-context !global;
      $prefix-context: $old-prefix-context !global;
    } @else if $debug-browser-support {
      /* Omitting content for #{$prefix} because #{$current-prefix} is already in scope. */
    }
  } @else {
    @if $debug-browser-support and $prefix {
      /* Creating new #{$prefix} context. */
    }
    $prefix-context: $prefix !global;
    $current-prefix: $prefix !global;
    @content;
    $current-prefix: null !global;
    $prefix-context: null !global;
  }
}

// If passed a map, that will be the new browser ranges.
// Otherwise a range map will be created based on the given capability and prefix
// using the `browser-ranges($capability, $prefix)` function.
//
// If there are current ranges in scope and the new ranges have some overlap
// with the current,
//
// If there is no overlap, then the content will not be rendered.
@mixin with-browser-ranges($capability, $prefix: $current-prefix) {
  $new-ranges: null;
  @if type-of($capability) == map {
    $new-ranges: $capability;
  } @else {
    $new-ranges: browser-ranges($capability, $prefix);
  }

  @if has-browser-subset($current-browser-versions, $new-ranges) {
    $old-ranges: $current-browser-versions;
    $current-browser-versions: intersect-browser-ranges($old-ranges, $new-ranges) !global;
    @content;
    $current-browser-versions: $old-ranges !global;
  } @else if $debug-browser-support {
    /* Excluding content because #{inspect($new-ranges)} is not included within
       #{inspect($current-browser-versions)} */
  }
}

// Output a property and value using the current prefix.
// It will be unprefixed if $current-prefix is null.
@mixin prefix-prop($property, $value, $prefix: $current-prefix) {
  #{prefix-identifier($property, $prefix)}: $value;
}

