////
/// @group form-slider
/// @since 2.5.0
////

@import '@react-md/states/dist/scss/mixins';
@import '@react-md/transition/dist/scss/mixins';
@import '@react-md/utils/dist/scss/mixins';

@import './functions';
@import './variables';

/// Creates the styles for one of the slider's theme values. This is mostly
/// going to be an internal helper mixin util.
///
/// @param {String} property - The property to set a `rmd-slider-theme-values`
/// value to.
/// @param {String} theme-style - One of the keys of `rmd-slider-theme-values`
/// to extract a value from.
/// @param {Color|String|Number} fallback [null] - A fallback value to use if
/// the css variable isn't set somehow. This will default to automatically
/// retrieving the default value from the `rmd-slider-theme-values` map when
/// `null`.
@mixin rmd-slider-theme($property, $theme-style: $property, $fallback: null) {
  @include rmd-theme-apply-rmd-var(
    $property,
    $theme-style,
    $rmd-slider-theme-values,
    slider
  );
}

/// Updates one of the slider's theme variables with the new value for the
/// section of your app.
///
/// @param {String} theme-style - The slider theme style type to update. This
/// should be one of the `$rmd-slider-theme-values` keys.
/// @param {Color|String|Number} value - The new value to use.
@mixin rmd-slider-theme-update-var($theme-style, $value) {
  @include rmd-theme-update-rmd-var(
    $value,
    $theme-style,
    $rmd-slider-theme-values,
    slider
  );
}

/// This is used internally just to help with the `--offset1` and `--offset2`
/// custom properties to help position/style the thumbs and tracks in the
/// Slider.
///
/// @access private
/// @param {Number} thumb-index - This should be either 1 or 2
/// @return {String} the css variable for the slider thumb offset
@function rmd-slider-offset($thumb-index) {
  @return var(--offset#{$thumb-index}, 0);
}

/// Creates the styles for the slider container that allows for additional
/// addons to be placed inline with the slider.
///
/// @access private
@mixin rmd-slider-container {
  $directions: (right, left);

  @if $rmd-slider-container-addon-spacing != $rmd-icon-spacing-with-text {
    @include rmd-icon-theme-update-var(
      text-spacing,
      $rmd-slider-container-addon-spacing
    );
  }

  align-items: center;

  &--h {
    display: flex;
  }

  @if $rmd-slider-include-vertical {
    $directions: (top, right, bottom, left);

    &--v {
      display: inline-flex;
      flex-direction: column-reverse;
    }
  }

  @each $dir in directions {
    &--pad-#{$dir} {
      $property: padding-#{$dir};

      #{$property}: $rmd-slider-container-padding;
    }
  }
}

/// The track for the slider is made up of a container `<span>` element that
/// holds the one or two thumbs and displays the min/max distance the slider can
/// be dragged. To keep the DOM minimal, the track's "progress" is created by
/// using the `::before` and `::after` pseudo-selectors to create the progress
/// "blocks". The `::before` tag is used for the inactive state while the
/// `::after` tag shows the active state.
///
/// @access private
@mixin rmd-slider-track {
  @include rmd-slider-track-horizontal;
  @if $rmd-slider-include-vertical {
    @include rmd-slider-track-vertical;
  }

  position: relative;

  &::before,
  &::after {
    @if $rmd-slider-is-same-track-color {
      @include rmd-slider-theme(background-color, color);
    }

    content: '';
    pointer-events: none;
    position: absolute;
  }

  &::before {
    @if not $rmd-slider-is-same-track-color {
      @include rmd-slider-theme(background-color, inactive-color);
    }

    opacity: $rmd-slider-inactive-track-opacity;
    z-index: $rmd-slider-inactive-track-z-index;
  }

  &::after {
    @if not $rmd-slider-is-same-track-color {
      @include rmd-slider-theme(background-color, active-color);
    }

    opacity: $rmd-slider-active-track-opacity;
    z-index: $rmd-slider-active-track-z-index;
  }

  &--hoverable:hover {
    cursor: pointer;
  }

  &--animate::after {
    @include rmd-transition(standard);

    transition-duration: $rmd-transition-standard-time;
  }

  &--disabled {
    @if $rmd-slider-is-same-track-color {
      @include rmd-slider-theme-update-var(
        color,
        $rmd-slider-disabled-track-color
      );

      &::after {
        @include rmd-slider-theme-update-var(active-size, 0px);
      }

      @if $rmd-slider-inactive-track-opacity != null {
        &::before {
          opacity: 1;
        }
      }

      @if $rmd-slider-active-track-opacity != null {
        &::after {
          opacity: 1;
        }
      }
    }
  }
}

/// Creates the styles for horizontal tracks by attaching the following
/// modifiers to the parent class:
///
/// - `--h` - base styles that should be used along side one of the following
///   classes
/// - `--h1` - additional styles when there is only one thumb
/// - `--h2` - additional styles when there are two thumbs. Should not be used
///   with any of the `--h1*` classes
///
/// @access private
@mixin rmd-slider-track-horizontal {
  &--h {
    @include rmd-slider-theme(height, size);

    align-items: center;
    display: flex;
    width: 100%;

    &::before {
      @include rmd-slider-theme(height, inactive-size);

      width: 100%;
    }

    &::after {
      @include rmd-slider-theme(height, active-size);
    }
  }

  // one thumb track horizontal styles
  &--h1::after {
    @include rmd-utils-rtl-auto(left, 0);

    max-width: rmd-slider-offset(1);
    transition-property: max-width;
    width: 100%;
  }

  // two thumb track horizontal styles
  &--h2::after {
    @include rmd-utils-rtl {
      left: calc(100% - #{rmd-slider-offset(2)});
      right: rmd-slider-offset(1);
    }

    left: rmd-slider-offset(1);
    right: calc(100% - #{rmd-slider-offset(2)});
    transition-property: left, right;
    will-change: left, right;
  }
}

/// Creates the styles for horizontal tracks by attaching the following
/// modifiers to the parent class:
///
/// - `--v` - base styles that should be used along side one of the following
///   classes
/// - `--v1` - additional styles when there is only one thumb
/// - `--v2` - additional styles when there are two thumbs. Should not be used
///   with any of the `--v1*` classes
///
/// @access private
@mixin rmd-slider-track-vertical {
  &--v {
    @include rmd-slider-theme(height, vertical-size);
    @include rmd-slider-theme(width, size);

    display: inline-flex;
    justify-content: center;

    &::before {
      @include rmd-slider-theme(width, inactive-size);

      height: 100%;
    }

    &::after {
      @include rmd-slider-theme(width, active-size);

      bottom: 0;
    }
  }

  // one thumb track horizontal styles
  &--v1::after {
    height: 100%;
    max-height: rmd-slider-offset(1);
    transition-property: max-height;
  }

  // two thumb track horizontal styles
  &--v2::after {
    bottom: rmd-slider-offset(1);
    top: calc(100% - #{rmd-slider-offset(2)});
    transition-property: bottom, top;
    will-change: bottom, top;
  }
}

/// Creates the styles for the slider's thumb. This should be used within a
/// class since it adds additional class modifiers based on the parent class.
///
/// @access private
@mixin rmd-slider-thumb {
  @include rmd-utils-hide-focus-outline;
  @include rmd-slider-theme(
    background-color,
    if($rmd-slider-is-same-track-color, color, active-color)
  );
  @include rmd-slider-theme(height, thumb-size);
  @include rmd-slider-theme(width, thumb-size);
  @include rmd-slider-thumb-horizontal;
  @include rmd-utils-mouse-only {
    &:hover::after {
      transform: scale($rmd-slider-thumb-focus-scale);
    }

    &--active::after,
    &--active:hover::after {
      transform: scale($rmd-slider-thumb-active-scale);
    }
  }
  @include rmd-utils-keyboard-only {
    &:focus::after {
      transform: scale($rmd-slider-thumb-focus-scale);
    }

    &--active::after {
      transform: scale($rmd-slider-thumb-active-scale);
    }
  }

  @if $rmd-slider-include-vertical {
    @include rmd-slider-thumb-vertical;
  }

  border-radius: $rmd-slider-thumb-radius;
  position: absolute;
  z-index: $rmd-slider-thumb-z-index;

  &::after {
    @include rmd-transition(standard);
    @include rmd-utils-pseudo-element(null);

    background-color: inherit;
    opacity: $rmd-slider-thumb-bubble-opacity;
    transition: transform $rmd-transition-standard-time;
  }

  &--animate {
    @include rmd-transition(standard);

    transition-duration: $rmd-transition-standard-time;
  }

  &--disabled {
    background-color: $rmd-slider-disabled-thumb-color;

    // prevent hover effects like the "bubble"
    pointer-events: none;
  }

  &--mask {
    @include rmd-theme(background-color, background);

    border-radius: 0;
  }
}

/// Creates the styles for horizontal thumbs by attaching the following
/// modifiers to the parent class:
///
/// - `--h` - base styles that should be used along side the following classes
/// - `--h1` - styles specifically for the first thumb
/// - `--h2` - styles specifically for the second thumb
/// - `--disabled-h` - disabled styles since the thumb uses a `translateX` +
///   `scale` transform when disabled. Should not be applied to the "mask" thumb
///   that is used to add spacing on the track
/// - `--mask-h` - styles that should be used for the masked thumb to create
///   spacing on the track.
///
/// @access private
@mixin rmd-slider-thumb-horizontal {
  &--h {
    @include rmd-utils-rtl {
      transform: translateX(50%);
      transition-property: right;
    }

    // want the thumb to be aligned so that the center is at the current value.
    // without this transformation, the thumb's left side would be aligned with
    // the current value
    transform: translateX(-50%);
    transition-property: left;
  }

  // first thumb
  &--h1 {
    @include rmd-utils-rtl-auto(left, rmd-slider-offset(1));
  }

  // second thumb
  &--h2 {
    @include rmd-utils-rtl-auto(left, rmd-slider-offset(2));
  }

  &--disabled-h {
    @include rmd-utils-rtl {
      transform: translateX(50%) scale($rmd-slider-thumb-disabled-scale);
    }

    transform: translateX(-50%) scale($rmd-slider-thumb-disabled-scale);
  }

  &--mask-h {
    @include rmd-utils-rtl {
      transform: translateX(50%) scale($rmd-slider-thumb-disabled-mask-scale);
    }

    transform: translateX(-50%) scale($rmd-slider-thumb-disabled-mask-scale);
  }
}

/// Creates the styles for vertical thumbs by attaching the following modifiers
/// to the parent class:
///
/// - `--v` - base styles that should be used along side the following classes
/// - `--v1` - styles specifically for the first thumb
/// - `--v2` - styles specifically for the second thumb
/// - `--disabled-v` - disabled styles since the thumb uses a `translateY` +
///   `scale` transform when disabled. Should not be applied to the "mask" thumb
///   that is used to add spacing on the track
/// - `--mask-v` - styles that should be used for the masked thumb to create
///   spacing on the track.
///
/// @access private
@mixin rmd-slider-thumb-vertical {
  &--v {
    // want the thumb to be aligned so that the center is at the current value.
    // without this transformation, the thumb's bottom side would be aligned
    // with the current value
    transform: translateY(50%);
    transition-property: bottom;
  }

  &--v1 {
    bottom: rmd-slider-offset(1);
  }

  &--v2 {
    bottom: rmd-slider-offset(2);
  }

  &--disabled-v {
    transform: translateY(50%) scale($rmd-slider-thumb-disabled-scale);
  }

  &--mask-v {
    transform: translateY(50%) scale($rmd-slider-thumb-disabled-mask-scale);
  }
}

/// Generates the styles for the discrete slider's value tooltip
/// @access private
@mixin rmd-slider-value {
  opacity: 1;
  position: absolute;

  // this is used to generate the triangle
  &::after {
    border: $rmd-slider-thumb-value-caret-size solid transparent;
    content: '';
    position: absolute;
  }

  &--animate {
    transition: transform $rmd-transition-standard-time;
  }

  &--h {
    @include rmd-utils-rtl {
      transform: translateX(50%) scale(1);
    }

    top: $rmd-slider-thumb-value-offset;
    transform: translateX(-50%) scale(1);

    &::after {
      @include rmd-utils-rtl {
        transform: translateX(50%);
      }

      border-top-color: rmd-tooltip-theme-var(background-color);
      left: 50%;
      top: 100%;
      transform: translateX(-50%);
    }
  }

  &--h-off {
    transform: translateX(-50%) scale(0);
  }

  // have to "duplicate" these styles since the `--h-off` would override the
  // `--h` styles due to css order.
  &--h-on {
    transform: translateX(-50%) scale(1);
  }

  @if $rmd-slider-include-vertical {
    &--v {
      // going to force rendering always to the left even in RTL languages
      left: $rmd-slider-thumb-value-offset;
      transform: translateY(50%) scale(1);

      &::after {
        border-left-color: rmd-tooltip-theme-var(background-color);
        left: 100%;
        top: 50%;
        transform: translateY(-50%);
      }
    }

    &--v-off {
      transform: translateY(50%) scale(0);
    }

    // have to "duplicate" these styles since the `--v-off` would override the
    // `--v` styles due to css order.
    &--v-on {
      transform: translateY(50%) scale(1);
    }
  }
}

/// Creates all the styles for this package as well as defining all the theme
/// CSS variables.
@mixin react-md-slider {
  @include rmd-theme-create-root-theme($rmd-slider-theme-values, slider);

  .rmd-slider-container {
    @include rmd-slider-container;
  }

  .rmd-slider-track {
    @include rmd-slider-track;
  }

  .rmd-slider-thumb {
    @include rmd-slider-thumb;
  }

  .rmd-slider-value {
    @include rmd-slider-value;
  }
}
