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

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

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

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

  // Prevents the spinning of the inner element from affecting layout outside of the spinner.
  overflow: hidden;

  // Spinners with a diameter less than half the existing line-height will become distorted.
  // Explicitly set the line-height to 0px to avoid this issue.
  line-height: 0;
  position: relative;
  direction: ltr;
  transition: opacity 250ms cubic-bezier(0.4, 0, 0.6, 1);

  circle {
    stroke-width: token-utils.slot(progress-spinner-active-indicator-width, $fallbacks);
  }

  &._mat-animation-noopable {
    &, .mdc-circular-progress__determinate-circle {
      // The spinner itself has a transition on `opacity`.
      transition: none !important;
    }

    .mdc-circular-progress__indeterminate-circle-graphic,
    .mdc-circular-progress__spinner-layer,
    .mdc-circular-progress__indeterminate-container {
      // Disables the rotation animations.
      animation: none !important;
    }

    .mdc-circular-progress__indeterminate-container circle {
      // Render the indeterminate spinner as a complete circle when animations are off
      stroke-dasharray: 0 !important;
    }
  }

  @include cdk.high-contrast {
    .mdc-circular-progress__indeterminate-circle-graphic,
    .mdc-circular-progress__determinate-circle {
      // SVG colors aren't inverted automatically in high contrast mode. Set the
      // stroke to currentColor in order to respect the user's color settings.
      stroke: currentColor;
      // currentColor blends in with the background in Chromium-based browsers
      // so we have to fall back to `CanvasText` which isn't supported on IE.
      stroke: CanvasText;
    }
  }
}

// Slow down the animation by 25% when the user configured their OS to reduce motion.
.mat-progress-spinner-reduced-motion {
  --mat-progress-spinner-animation-multiplier: 1.25;
}

.mdc-circular-progress__determinate-container,
.mdc-circular-progress__indeterminate-circle-graphic,
.mdc-circular-progress__indeterminate-container,
.mdc-circular-progress__spinner-layer {
  position: absolute;
  width: 100%;
  height: 100%;
}

.mdc-circular-progress__determinate-container {
  transform: rotate(-90deg);

  .mdc-circular-progress--indeterminate & {
    opacity: 0;
  }
}

.mdc-circular-progress__indeterminate-container {
  font-size: 0;
  letter-spacing: 0;
  white-space: nowrap;
  opacity: 0;

  .mdc-circular-progress--indeterminate & {
    opacity: 1;
    animation: mdc-circular-progress-container-rotate
      calc(1568.2352941176ms * var(--mat-progress-spinner-animation-multiplier)) linear infinite;
  }
}

.mdc-circular-progress__determinate-circle-graphic,
.mdc-circular-progress__indeterminate-circle-graphic {
  fill: transparent;
}

.mat-mdc-progress-spinner .mdc-circular-progress__determinate-circle,
.mat-mdc-progress-spinner .mdc-circular-progress__indeterminate-circle-graphic {
  stroke: token-utils.slot(progress-spinner-active-indicator-color, $fallbacks);

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

.mdc-circular-progress__determinate-circle {
  transition: stroke-dashoffset 500ms cubic-bezier(0, 0, 0.2, 1);
}

.mdc-circular-progress__gap-patch {
  position: absolute;
  top: 0;
  left: 47.5%;
  box-sizing: border-box;
  width: 5%;
  height: 100%;
  overflow: hidden;
}

.mdc-circular-progress__indeterminate-circle-graphic {
  .mdc-circular-progress__gap-patch & {
    left: -900%;
    width: 2000%;
    transform: rotate(180deg);
  }

  .mdc-circular-progress__circle-clipper & {
    width: 200%;
  }

  .mdc-circular-progress__circle-right & {
    left: -100%;
  }

  .mdc-circular-progress--indeterminate .mdc-circular-progress__circle-left & {
    animation: mdc-circular-progress-left-spin
      calc(1333ms * var(--mat-progress-spinner-animation-multiplier))
      cubic-bezier(0.4, 0, 0.2, 1) infinite both;
  }

  .mdc-circular-progress--indeterminate .mdc-circular-progress__circle-right & {
    animation: mdc-circular-progress-right-spin
      calc(1333ms * var(--mat-progress-spinner-animation-multiplier))
      cubic-bezier(0.4, 0, 0.2, 1) infinite both;
  }
}

.mdc-circular-progress__circle-clipper {
  display: inline-flex;
  position: relative;
  width: 50%;
  height: 100%;
  overflow: hidden;
}

.mdc-circular-progress__spinner-layer {
  .mdc-circular-progress--indeterminate & {
    animation: mdc-circular-progress-spinner-layer-rotate
      calc(5332ms * var(--mat-progress-spinner-animation-multiplier)) cubic-bezier(0.4, 0, 0.2, 1)
      infinite both;
  }
}

@keyframes mdc-circular-progress-container-rotate {
  to {
    transform: rotate(360deg);
  }
}

@keyframes mdc-circular-progress-spinner-layer-rotate {
  12.5% {
    transform: rotate(135deg);
  }

  25% {
    transform: rotate(270deg);
  }

  37.5% {
    transform: rotate(405deg);
  }

  50% {
    transform: rotate(540deg);
  }

  62.5% {
    transform: rotate(675deg);
  }

  75% {
    transform: rotate(810deg);
  }

  87.5% {
    transform: rotate(945deg);
  }

  100% {
    transform: rotate(1080deg);
  }
}

@keyframes mdc-circular-progress-left-spin {
  from {
    transform: rotate(265deg);
  }

  50% {
    transform: rotate(130deg);
  }

  to {
    transform: rotate(265deg);
  }
}

@keyframes mdc-circular-progress-right-spin {
  from {
    transform: rotate(-265deg);
  }

  50% {
    transform: rotate(-130deg);
  }

  to {
    transform: rotate(-265deg);
  }
}
