@import './animations.scss';
@import './colors.scss';

// A collection of mixins and CSS classes that can be used to apply elevation to
// elements
// Examples:
//
//
// .pg-foo {
//   @include $pg-elevation(2);
//
//   &:active {
//     @include $pg-elevation(8);
//   }
// }
//
// <div id="external-card" class="pg-elevation-2"><p>Some content</p></div>

@function _get-umbra-map($color, $opacity) {
  @return (
    0: '0px 0px 0px 0px #{rgba($color, $opacity * 0.16)}',
    1: '0px 0px 1px 0px #{rgba($color, $opacity * 0.16)}',
    2: '0px 0px 1px 0px #{rgba($color, $opacity * 0.16)}',
    3: '0px 0px 1px 0px #{rgba($color, $opacity * 0.08)}',
    4: '0px 0px 1px 0px #{rgba($color, $opacity * 0.10)}',
    5: '0px 0px 1px 0px #{rgba($color, $opacity * 0.10)}'
  );
}

@function _get-penumbra-map($color, $opacity) {
  @return (
    0: '0px 0px 0px 0px #{rgba($color, $opacity * 0.16)}',
    1: '0px 1px 1px 0px #{rgba($color, $opacity * 0.16)}',
    2: '0px 3px 4px 0px #{rgba($color, $opacity * 0.10)}',
    3: '0px 8px 10px 0px #{rgba($color, $opacity * 0.20)}',
    4: '0px 16px 16px 0px #{rgba($color, $opacity * 0.12)}',
    5: '0px 24px 24px 0px #{rgba($color, $opacity * 0.12)}'
  );
}

// Not currently used
@function _get-ambient-map($color, $opacity) {
  @return (
    0: '0px 0px 0px 0px #{rgba($color, $opacity * 0)}',
    1: '0px 1px 3px 0px #{rgba($color, $opacity * 0)}',
    2: '0px 1px 5px 0px #{rgba($color, $opacity * 0)}',
    3: '0px 1px 8px 0px #{rgba($color, $opacity * 0)}',
    4: '0px 1px 10px 0px #{rgba($color, $opacity * 0)}',
    5: '0px 1px 14px 0px #{rgba($color, $opacity * 0)}'
  );
}

// The default duration value for elevation transitions.
$pg-elevation-transition-duration: 280ms !default;

// The default easing value for elevation transitions.
$pg-elevation-transition-timing-function: $transition-curve-standard;

// The default color for elevation shadows.
$pg-elevation-color: $neutral1000 !default;

// The default opacity scaling value for elevation shadows.
$pg-elevation-opacity: 1 !default;

// Prefix for elevation-related selectors.
$_pg-elevation-prefix: 'pg-elevation-';
$_grit-elevation-prefix: 'grit-elevation-';

// Applies the correct css rules to an element to give it the elevation specified by $zValue.
// The $zValue must be between 0 and 24.
@mixin pg-elevation(
  $zValue,
  $color: $pg-elevation-color,
  $opacity: $pg-elevation-opacity
) {
  @if type-of($zValue) != number or not unitless($zValue) {
    @error '$zValue must be a unitless number';
  }
  @if $zValue < 0 or $zValue > 5 {
    @error '$zValue must be between 0 and 5';
  }

  box-shadow: #{map-get(_get-umbra-map($color, $opacity), $zValue)},
    #{map-get(_get-penumbra-map($color, $opacity), $zValue)};
  z-index: $zValue;
}

// Applies the elevation to an element in a manner that allows
// consumers to override it via the pgerial elevation classes.
@mixin pg-overridable-elevation(
  $zValue,
  $color: $pg-elevation-color,
  $opacity: $pg-elevation-opacity
) {
  &:not([class*='#{$_pg-elevation-prefix}']) {
    @include pg-elevation($zValue, $color, $opacity);
  }
}

// Returns a string that can be used as the value for a transition property for elevation.
// Calling this function directly is useful in situations where a component needs to transition
// more than one property.
//
// .foo {
//   transition: pg-elevation-transition-property-value(), opacity 100ms ease;
// }
@function pg-elevation-transition-property-value(
  $duration: $pg-elevation-transition-duration,
  $easing: $pg-elevation-transition-timing-function
) {
  @return box-shadow #{$duration} #{$easing};
}

// Applies the correct css rules needed to have an element transition between elevations.
// This mixin should be applied to elements whose elevation values will change depending on their
// context (e.g. when active or disabled).

@mixin pg-elevation-transition(
  $duration: $pg-elevation-transition-duration,
  $easing: $pg-elevation-transition-timing-function
) {
  transition: pg-elevation-transition-property-value($duration, $easing);
}
