@use '@angular/cdk';
@use './m3-progress-bar';
@use '../core/tokens/token-utils';

$fallbacks: m3-progress-bar.get-tokens();

.mat-mdc-progress-bar {
  --mat-progress-bar-animation-multiplier: 1;

  // Explicitly set to `block` since the browser defaults custom elements to `inline`.
  display: block;

  // Explicitly set a `text-align` so that the content isn't affected by the parent (see #27613).
  text-align: start;

  // Inverts the progress bar horizontally in `query` mode.
  &[mode='query'] {
    transform: scaleX(-1);
  }

  &._mat-animation-noopable {
    .mdc-linear-progress__buffer-dots,
    .mdc-linear-progress__primary-bar,
    .mdc-linear-progress__secondary-bar,
    .mdc-linear-progress__bar-inner.mdc-linear-progress__bar-inner {
      // Disable the loading animations.
      animation: none;
    }

    .mdc-linear-progress__primary-bar,
    .mdc-linear-progress__buffer-bar {
      // There's a `transitionend` event that depends on this element. Add a very short
      // transition when animations are disabled so that the event can still fire.
      transition: transform 1ms;
    }
  }
}

// Slow down the animation by 100% when the user configured their OS to reduce
// motion since some animations like the indeterminate one can be quite dynamic.
.mat-progress-bar-reduced-motion {
  --mat-progress-bar-animation-multiplier: 2;
}

.mdc-linear-progress {
  position: relative;
  width: 100%;
  transform: translateZ(0);
  outline: 1px solid transparent;
  overflow-x: hidden;
  transition: opacity 250ms 0ms cubic-bezier(0.4, 0, 0.6, 1);

  $track-variable: token-utils.slot(progress-bar-track-height, $fallbacks);
  $indicator-height-variable: token-utils.slot(progress-bar-active-indicator-height, $fallbacks);
  height: max(#{$track-variable}, #{$indicator-height-variable});

  @include cdk.high-contrast {
    outline-color: CanvasText;
  }
}

.mdc-linear-progress__bar {
  position: absolute;
  top: 0;
  bottom: 0;
  margin: auto 0;
  width: 100%;
  animation: none;
  transform-origin: top left;
  transition: transform 250ms 0ms cubic-bezier(0.4, 0, 0.6, 1);
  height: token-utils.slot(progress-bar-active-indicator-height, $fallbacks);

  .mdc-linear-progress--indeterminate & {
    transition: none;
  }

  [dir='rtl'] & {
    right: 0;
    transform-origin: center right;
  }
}

.mdc-linear-progress__bar-inner {
  display: inline-block;
  position: absolute;
  width: 100%;
  animation: none;
  border-top-style: solid;
  border-color: token-utils.slot(progress-bar-active-indicator-color, $fallbacks);
  border-top-width: token-utils.slot(progress-bar-active-indicator-height, $fallbacks);
}

.mdc-linear-progress__buffer {
  display: flex;
  position: absolute;
  top: 0;
  bottom: 0;
  margin: auto 0;
  width: 100%;
  overflow: hidden;
  height: token-utils.slot(progress-bar-track-height, $fallbacks);
  border-radius: token-utils.slot(progress-bar-track-shape, $fallbacks);
}

.mdc-linear-progress__buffer-dots {
  $circle-color: token-utils.slot(progress-bar-track-color, $fallbacks);
  $circle-size: calc(#{token-utils.slot(progress-bar-track-height, $fallbacks)} / 2);
  background-image: radial-gradient(circle, #{$circle-color} #{$circle-size}, transparent 0);
  background-repeat: repeat-x;
  background-size: calc(#{$circle-size} * 5);
  // The `background-position` prevents the animation from jumping around when the progress
  // changes. Note that we shouldn't invert it in RTL, because the animation direction is reversed.
  background-position: left;
  flex: auto;
  transform: rotate(180deg);
  animation: mdc-linear-progress-buffering
    calc(250ms * var(--mat-progress-bar-animation-multiplier)) infinite linear;

  @include cdk.high-contrast {
    background-color: ButtonBorder;
  }

  [dir='rtl'] & {
    animation: mdc-linear-progress-buffering-reverse
      calc(250ms * var(--mat-progress-bar-animation-multiplier)) infinite linear;
    transform: rotate(0);
  }
}

.mdc-linear-progress__buffer-bar {
  flex: 0 1 100%;
  transition: flex-basis 250ms 0ms cubic-bezier(0.4, 0, 0.6, 1);
  background-color: token-utils.slot(progress-bar-track-color, $fallbacks);
}

.mdc-linear-progress__primary-bar {
  transform: scaleX(0);

  .mdc-linear-progress--indeterminate & {
    left: -145.166611%;
  }

  .mdc-linear-progress--indeterminate.mdc-linear-progress--animation-ready & {
    animation: mdc-linear-progress-primary-indeterminate-translate
      calc(2s * var(--mat-progress-bar-animation-multiplier)) infinite linear;
  }

  .mdc-linear-progress--indeterminate.mdc-linear-progress--animation-ready & {
    > .mdc-linear-progress__bar-inner {
      animation: mdc-linear-progress-primary-indeterminate-scale
        calc(2s * var(--mat-progress-bar-animation-multiplier)) infinite linear;
    }
  }

  [dir='rtl'] .mdc-linear-progress.mdc-linear-progress--animation-ready & {
    animation-name: mdc-linear-progress-primary-indeterminate-translate-reverse;
  }

  [dir='rtl'] .mdc-linear-progress.mdc-linear-progress--indeterminate & {
    right: -145.166611%;
    left: auto;
  }
}

.mdc-linear-progress__secondary-bar {
  display: none;

  .mdc-linear-progress--indeterminate & {
    left: -54.888891%;
    display: block;
  }

  .mdc-linear-progress--indeterminate.mdc-linear-progress--animation-ready & {
    animation: mdc-linear-progress-secondary-indeterminate-translate
      calc(2s * var(--mat-progress-bar-animation-multiplier)) infinite linear;
  }

  .mdc-linear-progress--indeterminate.mdc-linear-progress--animation-ready & {
    > .mdc-linear-progress__bar-inner {
      animation: mdc-linear-progress-secondary-indeterminate-scale
        calc(2s * var(--mat-progress-bar-animation-multiplier)) infinite linear;
    }
  }

  [dir='rtl'] .mdc-linear-progress.mdc-linear-progress--animation-ready & {
    animation-name: mdc-linear-progress-secondary-indeterminate-translate-reverse;
  }

  [dir='rtl'] .mdc-linear-progress.mdc-linear-progress--indeterminate & {
    right: -54.888891%;
    left: auto;
  }
}

@keyframes mdc-linear-progress-buffering {
  from {
    $track-variable: token-utils.slot(progress-bar-track-height, $fallbacks);
    transform: rotate(180deg) translateX(calc(#{$track-variable} * -2.5));
  }
}

@keyframes mdc-linear-progress-primary-indeterminate-translate {
  0% {
    transform: translateX(0);
  }
  20% {
    animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
    transform: translateX(0);
  }
  59.15% {
    animation-timing-function: cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);
    transform: translateX(83.67142%);
  }
  100% {
    transform: translateX(200.611057%);
  }
}

@keyframes mdc-linear-progress-primary-indeterminate-scale {
  0% {
    transform: scaleX(0.08);
  }
  36.65% {
    animation-timing-function: cubic-bezier(0.334731, 0.12482, 0.785844, 1);
    transform: scaleX(0.08);
  }
  69.15% {
    animation-timing-function: cubic-bezier(0.06, 0.11, 0.6, 1);
    transform: scaleX(0.661479);
  }
  100% {
    transform: scaleX(0.08);
  }
}

@keyframes mdc-linear-progress-secondary-indeterminate-translate {
  0% {
    animation-timing-function: cubic-bezier(0.15, 0, 0.515058, 0.409685);
    transform: translateX(0);
  }
  25% {
    animation-timing-function: cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);
    transform: translateX(37.651913%);
  }
  48.35% {
    animation-timing-function: cubic-bezier(0.4, 0.627035, 0.6, 0.902026);
    transform: translateX(84.386165%);
  }
  100% {
    transform: translateX(160.277782%);
  }
}

@keyframes mdc-linear-progress-secondary-indeterminate-scale {
  0% {
    animation-timing-function: cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);
    transform: scaleX(0.08);
  }
  19.15% {
    animation-timing-function: cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);
    transform: scaleX(0.457104);
  }
  44.15% {
    animation-timing-function: cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);
    transform: scaleX(0.72796);
  }
  100% {
    transform: scaleX(0.08);
  }
}

@keyframes mdc-linear-progress-primary-indeterminate-translate-reverse {
  0% {
    transform: translateX(0);
  }
  20% {
    animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
    transform: translateX(0);
  }
  59.15% {
    animation-timing-function: cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);
    transform: translateX(-83.67142%);
  }
  100% {
    transform: translateX(-200.611057%);
  }
}

@keyframes mdc-linear-progress-secondary-indeterminate-translate-reverse {
  0% {
    animation-timing-function: cubic-bezier(0.15, 0, 0.515058, 0.409685);
    transform: translateX(0);
  }
  25% {
    animation-timing-function: cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);
    transform: translateX(-37.651913%);
  }
  48.35% {
    animation-timing-function: cubic-bezier(0.4, 0.627035, 0.6, 0.902026);
    transform: translateX(-84.386165%);
  }
  100% {
    transform: translateX(-160.277782%);
  }
}

@keyframes mdc-linear-progress-buffering-reverse {
  from {
    transform: translateX(-10px);
  }
}
