
@use 'sass:color';
@use 'sass:meta';
@use '../../functions/bottom-shadow' as *;
@use '../../functions/top-shadow' as *;
@use '../../functions/conv-color' as *;
@use '../../functions/is-integer' as *;
@use '../../functions/is-number' as *;

/// Uses box-shadow to give an element a depth effect based on Google's
/// Material Design principles.
///
/// @link https://material.io/design/environment/light-shadows.html
/// @link https://material.io/design/environment/elevation.html
///
/// @param {Number} $level - Depth level (Must be between 0 and 5, inclusive).
/// This value will change the strength of the shadow effect, with 0 being off,
/// 1 being the lowest effective level, and 5 being the strongest. The higher
/// the value, the deeper the shadow, the more the effect makes the element
/// look like it is lifted off the screen.
/// @param {Color} $color [#000] - The color of the box-shadow effect.
/// @param {Number} $intensity [1] - An optional value that is multiplied with
/// the default color opacity to increase or decrease the intensity of the
/// effect.
///
/// @group Utilities
/// @require {function} bottom-shadow
/// @require {function} top-shadow
/// @require {function} conv-color
/// @require {function} is-integer
/// @require {function} is-number
///
/// @throw Invalid $level value error.
/// @throw Invalid $intensity value error.
/// @throw Unaccepted $color type error.
/// @throw Passed $color value had it's alpha value disregarded warning.
@mixin depth-level($level, $color: #000, $intensity: 1) {
  @if not is-integer($level) or $level < 0 or $level > 5 {
    @error 'Invalid $level of [ #{meta.inspect($level)} ] used in the ' +
      '[ depth-level ] mixin. Value must be an integer between 0 and 5 inclusive.';
  }

  @if not is-number($intensity) {
    @error 'Invalid $intensity of [ #{meta.inspect($intensity)} ] used in the ' +
      '[ depth-level ] mixin. Value must be an number.';
  }

  @if meta.type-of($color) != 'color' {
    @error 'Invalid $color of [ #{meta.inspect($color)} ] used in the ' +
     '[ depth-level ] mixin. Value must be an accepted color type.';
  }

  @if color.alpha($color) != 1 {
    @warn 'Color passed to the [ depth-level() ] mixin has an alpha value. ' +
        'This value was disregarded as the alpha value of the color is set ' +
        'by the mixin.';
  }

  // Convert the color into a hex string or CSS color name value.
  // This value will be converted into an rgba color by the
  // bottom-shadow and top-shadow functions called below.
  $color: conv-color($color, 'name');

  @if $level == 0 {
    box-shadow: none;
  } @else {
    box-shadow:
      bottom-shadow($level, $color, $intensity),
      top-shadow($level, $color, $intensity);
  }
}

/// Uses box-shadow to give an element a depth effect based on Google's
/// Material Design principles.
///
/// @link https://material.io/design/environment/light-shadows.html
/// @link https://material.io/design/environment/elevation.html
///
/// @param {Number} $level - Depth level (Must be between 0 and 5, inclusive).
/// This value will change the strength of the shadow effect, with 0 being off,
/// 1 being the lowest effective level, and 5 being the strongest. The higher
/// the value, the deeper the shadow, the more the effect makes the element
/// look like it is lifted off the screen.
/// @param {Color} $color [#000] - The color of the box-shadow effect.
/// @param {Number} $intensity [1] - An optional value that is multiplied with
/// the default color opacity to increase or decrease the intensity of the
/// effect.
///
/// @group Utilities
/// @require {function} bottom-shadow
/// @require {function} top-shadow
/// @require {function} conv-color
/// @require {function} is-integer
/// @require {function} is-number
///
/// @throw Invalid $level value error.
/// @throw Invalid $intensity value error.
/// @throw Unaccepted $color type error.
/// @throw Passed $color value had it's alpha value disregarded warning.
///
/// @alias depth-level
@mixin card-depth($level, $color: #000, $intensity: 1) {
  @include depth-level($level, $color);
}

/// Uses box-shadow to give an element a depth effect based on Google's
/// Material Design principles.
///
/// @link https://material.io/design/environment/light-shadows.html
/// @link https://material.io/design/environment/elevation.html
///
/// @param {Number} $level - Depth level (Must be between 0 and 5, inclusive).
/// This value will change the strength of the shadow effect, with 0 being off,
/// 1 being the lowest effective level, and 5 being the strongest. The higher
/// the value, the deeper the shadow, the more the effect makes the element
/// look like it is lifted off the screen.
/// @param {Color} $color [#000] - The color of the box-shadow effect.
/// @param {Number} $intensity [1] - An optional value that is multiplied with
/// the default color opacity to increase or decrease the intensity of the
/// effect.
///
/// @group Utilities
/// @require {function} bottom-shadow
/// @require {function} top-shadow
/// @require {function} conv-color
/// @require {function} is-integer
/// @require {function} is-number
///
/// @throw Invalid $level value error.
/// @throw Invalid $intensity value error.
/// @throw Unaccepted $color type error.
/// @throw Passed $color value had it's alpha value disregarded warning.
///
/// @alias depth-level
@mixin card($level, $color: #000, $intensity: 1) {
  @include depth-level($level, $color);
}

/// Uses box-shadow to give an element a depth effect based on Google's
/// Material Design principles.
///
/// @link https://material.io/design/environment/light-shadows.html
/// @link https://material.io/design/environment/elevation.html
///
/// @param {Number} $level - Depth level (Must be between 0 and 5, inclusive).
/// This value will change the strength of the shadow effect, with 0 being off,
/// 1 being the lowest effective level, and 5 being the strongest. The higher
/// the value, the deeper the shadow, the more the effect makes the element
/// look like it is lifted off the screen.
/// @param {Color} $color [#000] - The color of the box-shadow effect.
/// @param {Number} $intensity [1] - An optional value that is multiplied with
/// the default color opacity to increase or decrease the intensity of the
/// effect.
///
/// @group Utilities
/// @require {function} bottom-shadow
/// @require {function} top-shadow
/// @require {function} conv-color
/// @require {function} is-integer
/// @require {function} is-number
///
/// @throw Invalid $level value error.
/// @throw Invalid $intensity value error.
/// @throw Unaccepted $color type error.
/// @throw Passed $color value had it's alpha value disregarded warning.
///
/// @alias depth-level
@mixin shadow-depth($level, $color: #000, $intensity: 1) {
  @include depth-level($level, $color);
}

/// Uses box-shadow to give an element a depth effect based on Google's
/// Material Design principles.
///
/// @link https://material.io/design/environment/light-shadows.html
/// @link https://material.io/design/environment/elevation.html
///
/// @param {Number} $level - Depth level (Must be between 0 and 5, inclusive).
/// This value will change the strength of the shadow effect, with 0 being off,
/// 1 being the lowest effective level, and 5 being the strongest. The higher
/// the value, the deeper the shadow, the more the effect makes the element
/// look like it is lifted off the screen.
/// @param {Color} $color [#000] - The color of the box-shadow effect.
/// @param {Number} $intensity [1] - An optional value that is multiplied with
/// the default color opacity to increase or decrease the intensity of the
/// effect.
///
/// @group Utilities
/// @require {function} bottom-shadow
/// @require {function} top-shadow
/// @require {function} conv-color
/// @require {function} is-integer
/// @require {function} is-number
///
/// @throw Invalid $level value error.
/// @throw Invalid $intensity value error.
/// @throw Unaccepted $color type error.
/// @throw Passed $color value had it's alpha value disregarded warning.
///
/// @alias depth-level
@mixin depth($level, $color: #000, $intensity: 1) {
  @include depth-level($level, $color);
}

/// Uses box-shadow to give an element a depth effect based on Google's
/// Material Design principles.
///
/// @link https://material.io/design/environment/light-shadows.html
/// @link https://material.io/design/environment/elevation.html
///
/// @param {Number} $level - Depth level (Must be between 0 and 5, inclusive).
/// This value will change the strength of the shadow effect, with 0 being off,
/// 1 being the lowest effective level, and 5 being the strongest. The higher
/// the value, the deeper the shadow, the more the effect makes the element
/// look like it is lifted off the screen.
/// @param {Color} $color [#000] - The color of the box-shadow effect.
/// @param {Number} $intensity [1] - An optional value that is multiplied with
/// the default color opacity to increase or decrease the intensity of the
/// effect.
///
/// @group Utilities
/// @require {function} bottom-shadow
/// @require {function} top-shadow
/// @require {function} conv-color
/// @require {function} is-integer
/// @require {function} is-number
///
/// @throw Invalid $level value error.
/// @throw Invalid $intensity value error.
/// @throw Unaccepted $color type error.
/// @throw Passed $color value had it's alpha value disregarded warning.
///
/// @alias depth-level
@mixin shadow-level($level, $color: #000, $intensity: 1) {
  @include depth-level($level, $color);
}

/// Uses box-shadow to give an element a depth effect based on Google's
/// Material Design principles.
///
/// @link https://material.io/design/environment/light-shadows.html
/// @link https://material.io/design/environment/elevation.html
///
/// @param {Number} $level - Depth level (Must be between 0 and 5, inclusive).
/// This value will change the strength of the shadow effect, with 0 being off,
/// 1 being the lowest effective level, and 5 being the strongest. The higher
/// the value, the deeper the shadow, the more the effect makes the element
/// look like it is lifted off the screen.
/// @param {Color} $color [#000] - The color of the box-shadow effect.
/// @param {Number} $intensity [1] - An optional value that is multiplied with
/// the default color opacity to increase or decrease the intensity of the
/// effect.
///
/// @group Utilities
/// @require {function} bottom-shadow
/// @require {function} top-shadow
/// @require {function} conv-color
/// @require {function} is-integer
/// @require {function} is-number
///
/// @throw Invalid $level value error.
/// @throw Invalid $intensity value error.
/// @throw Unaccepted $color type error.
/// @throw Passed $color value had it's alpha value disregarded warning.
///
/// @alias depth-level
@mixin add-shadow($level, $color: #000, $intensity: 1) {
  @include depth-level($level, $color);
}

/// Uses box-shadow to give an element a depth effect based on Google's
/// Material Design principles.
///
/// @link https://material.io/design/environment/light-shadows.html
/// @link https://material.io/design/environment/elevation.html
///
/// @param {Number} $level - Depth level (Must be between 0 and 5, inclusive).
/// This value will change the strength of the shadow effect, with 0 being off,
/// 1 being the lowest effective level, and 5 being the strongest. The higher
/// the value, the deeper the shadow, the more the effect makes the element
/// look like it is lifted off the screen.
/// @param {Color} $color [#000] - The color of the box-shadow effect.
/// @param {Number} $intensity [1] - An optional value that is multiplied with
/// the default color opacity to increase or decrease the intensity of the
/// effect.
///
/// @group Utilities
/// @require {function} bottom-shadow
/// @require {function} top-shadow
/// @require {function} conv-color
/// @require {function} is-integer
/// @require {function} is-number
///
/// @throw Invalid $level value error.
/// @throw Invalid $intensity value error.
/// @throw Unaccepted $color type error.
/// @throw Passed $color value had it's alpha value disregarded warning.
///
/// @alias depth-level
@mixin material-shadow($level, $color) {
  @include depth-level($level, $color);
}
