@import '../ripple/ripple-theme';
@import '../ripple/ripple-component';

////
/// @group themes
/// @access public
/// @author <a href="https://github.com/simeonoff" target="_blank">Simeon Simeonoff</a>
/// @author <a href="https://github.com/desig9stein" target="_blank">Marin Popov</a>
////

/// @param {Map} $palette [$default-palette] - The palette used as basis for styling the component.
/// @param {Map} $schema [$light-schema] - The schema used as basis for styling the component.
/// @param {Map} $elevations [$elevations] - The elevations (shadows) map to be used.
///
/// @param {Color} $thumb-on-color [null] - The color of the thumb when the switch is on.
/// @param {Color} $track-on-color [null] - The color of the track when the switch is on.
/// @param {Color} $thumb-off-color [null] - The color of the thumb when the switch is off.
/// @param {Color} $track-off-color [null] - The color of the track when the switch is off.
/// @param {Color} $thumb-disabled-color [null] - The color of the thumb when the switch is disabled.
/// @param {Color} $track-disabled-color [null] - The color of the track when the switch is disabled.
/// @param {Color} $label-color [null] - The color of the switch label
/// @param {Color} $label-disabled-color [null] - The color of the switch label when the switch is disabled
/// @param {box-shadow} $resting-shadow [null] - The shadow used for the thumb in resting state of the switch.
/// @param {box-shadow} $hover-shadow [null] - The shadow used for the thumb in hover state of the switch.
/// @param {box-shadow} $disabled-shadow [null] - The shadow used for the thumb in disable state of the switch.
///
/// @param {border-radius} $border-radius-track [null] - The border radius used for switch track.
/// @param {border-radius} $border-radius-thumb [null] - The border radius used for switch thumb.
/// @param {border-radius} $border-radius-ripple [null] - The border radius used for switch ripple.
///
/// @requires $default-palette
/// @requires $light-schema
/// @requires apply-palette
/// @requires extend
/// @requires igx-elevation
/// @requires $elevations
///
/// @example scss Set custom track and thumb on colors
///   $my-switch-theme: igx-toast-theme($thumb-on-color: black, $track-on-color: yellow);
///   // Pass the theme to the igx-bottom-nav component mixin
///   @include igx-switch($my-switch-theme);
@function igx-switch-theme(
    $palette: $default-palette,
    $schema: $light-schema,

    $thumb-on-color: null,
    $track-on-color: null,

    $thumb-off-color: null,
    $track-off-color: null,

    $track-disabled-color: null,
    $thumb-disabled-color: null,

    $label-color: null,
    $label-disabled-color: null,

    $resting-shadow: null,
    $hover-shadow: null,
    $disabled-shadow: null,

    $border-radius-track: null,
    $border-radius-thumb: null,
    $border-radius-ripple: null,
    $border-color: null,
    $border-hover-color: null,
    $border-disabled-color: null,
    $border-on-color: null,
    $border-on-hover-color: null
) {
    $name: 'igx-switch';
    $switch-schema: ();

    @if map-has-key($schema, $name) {
        $switch-schema: map-get($schema, $name);
    } @else {
        $switch-schema: $schema;
    }

    $theme: apply-palette($switch-schema, $palette);

    $border-radius-track: round-borders(
        if($border-radius-track, $border-radius-track, map-get($switch-schema, 'border-radius-track')), 0, 7px
    );

    $border-radius-thumb: round-borders(
        if($border-radius-thumb, $border-radius-thumb, map-get($switch-schema, 'border-radius-thumb')), 0, 10px
    );

    $border-radius-ripple: round-borders(
        if($border-radius-ripple, $border-radius-ripple, map-get($switch-schema, 'border-radius-ripple')), 0, 24px
    );

    @if not($resting-shadow) {
        $resting-elevation: map-get($switch-schema, 'resting-elevation');
        $resting-shadow: igx-elevation($elevations, $resting-elevation);
    }

    @if not($hover-shadow) {
        $hover-elevation: map-get($switch-schema, 'hover-elevation');
        $hover-shadow: igx-elevation($elevations, $hover-elevation);
    }

    @if not($disabled-shadow) {
        $disabled-elevation: map-get($switch-schema, 'disabled-elevation');
        $disabled-shadow: igx-elevation($elevations, $disabled-elevation);
    }

    @return extend($theme, (
        name: $name,
        palette: $palette,

        thumb-on-color: $thumb-on-color,
        track-on-color: $track-on-color,

        thumb-off-color: $thumb-off-color,
        track-off-color: $track-off-color,

        track-disabled-color: $track-disabled-color,
        thumb-disabled-color: $thumb-disabled-color,

        label-color: $label-color,
        label-disabled-color: $label-disabled-color,

        resting-shadow: $resting-shadow,
        hover-shadow: $hover-shadow,
        disabled-shadow: $disabled-shadow,

        border-radius-track: $border-radius-track,
        border-radius-thumb: $border-radius-thumb,
        border-radius-ripple: $border-radius-ripple,
        border-color: $border-color,
        border-hover-color: $border-hover-color,
        border-disabled-color: $border-disabled-color,
        border-on-color: $border-on-color,
        border-on-hover-color: $border-on-hover-color,
    ));
}

/// @param {Map} $theme - The theme used to style the component.
/// @requires {mixin} igx-root-css-vars
/// @requires {mixin} igx-css-vars
/// @requires {mixin} scale-in-out
/// @requires {mixin} igx-ripple
/// @requires {mixin} hide-default
/// @requires igx-ripple-theme
/// @requires em
/// @requires {mixin} scale-in-out
/// @requires {mixin} animation
/// @requires --var
@mixin igx-switch($theme) {
    @include igx-root-css-vars($theme);
    @include scale-in-out($start-scale: .9);

    $switch-width: map-get((
        material: 36px,
        fluent: 40px,
    ), map-get($theme, variant));

    $switch-height: map-get((
        material: 14px,
        fluent: 20px
    ), map-get($theme, variant));

    $switch-thumb-width: map-get((
        material: 20px,
        fluent: 12px
    ), map-get($theme, variant));

    $switch-on-offset: map-get((
        material: 1px,
        fluent: $switch-thumb-width / 2
    ), map-get($theme, variant));

    $switch-off-offset: map-get((
        material: -1px,
        fluent: $switch-thumb-width / 3
    ), map-get($theme, variant));

    $ripple-display: map-get((
        material: block,
        fluent: none
    ), map-get($theme, variant));

    $thumb-resting-shadow: map-get((
        material: --var($theme, 'resting-shadow'),
        fluent: none
    ), map-get($theme, variant));

    $thumb-hover-shadow: map-get((
        material: --var($theme, 'hover-shadow'),
        fluent: none
    ), map-get($theme, variant));

    $thumb-disabled-shadow: map-get((
        material: --var($theme, 'disabled-shadow'),
        fluent: none
    ), map-get($theme, variant));

    $switch-thumb-height: $switch-thumb-width ;

    $ripple-size: em(48px);
    $ripple-radius: $ripple-size / 2;

    $label-margin: em(8px);

    $input-transition: all .2s $ease-in-out-quad;

    $ripple-theme: igx-ripple-theme(
        $color: --var($theme, 'thumb-on-color')
    );

    $left: if-ltr(left, right);
    $right: if-ltr(right, left);

    %switch-display {
        position: relative;
        display: inline-flex;
        flex-flow: row nowrap;
        align-items: center;
    }

    %switch-input {
        @include hide-default();
    }

    %switch-display--disabled {
        user-select: none;
        pointer-events: none;
        cursor: initial;
    }

    %switch-composite {
        display: flex;
        align-items: center;
        width: rem($switch-width);
        height: rem($switch-height);
        border: 1px solid --var($theme, 'border-color');
        border-radius: --var($theme, 'border-radius-track');
        background: --var($theme, 'track-off-color');
        cursor: pointer;
        user-select: none;
        transition: $input-transition;

        &:hover,
        &:focus {
            border-color: --var($theme, 'border-hover-color');
        }
    }

    %switch-composite--x {
        background: --var($theme, 'track-on-color');
        border-color: --var($theme, 'border-on-color');

        &:hover,
        &:focus {
            border-color: --var($theme, 'border-on-hover-color');
        }
    }

    %switch-composite--disabled {
        background: --var($theme, 'track-disabled-color');
        border-color: --var($theme, 'border-disabled-color');
    }

    %switch-composite-thumb {
        position: relative;
        display: block;
        width: rem($switch-thumb-width);
        height: $switch-thumb-height;
        min-width: rem($switch-thumb-width);
        border-radius: --var($theme, 'border-radius-thumb');
        background: --var($theme, 'thumb-off-color');
        box-shadow: $thumb-resting-shadow;
        transition: $input-transition;

        @include if-ltr() {
            transform: translateX(#{rem($switch-off-offset)});
        }

        @include if-rtl() {
            transform: translateX(#{rem(-1 * $switch-off-offset)});
        }

        &:hover {
            box-shadow: $thumb-hover-shadow;
        }
    }

    %switch-composite-thumb--x {
        background: --var($theme, 'thumb-on-color');

        @include if-ltr() {
            transform: translateX(#{rem($switch-width) - rem($switch-thumb-width) - rem($switch-on-offset)});
        }

        @include if-rtl() {
            transform: translateX(-#{rem($switch-width) - rem($switch-thumb-width) - rem($switch-on-offset)});
        }
    }

    %switch-composite-thumb--disabled {
        background: --var($theme, 'thumb-disabled-color');
        box-shadow: $thumb-disabled-shadow;
    }

    %switch-ripple {
        @include igx-ripple($ripple-theme);
        @include igx-css-vars($ripple-theme);
        display: $ripple-display;
        position: absolute;
        top: calc(50% - #{$ripple-radius});
        left: calc(50% - #{$ripple-radius});
        width: $ripple-size;
        height: $ripple-size;
        overflow: hidden;
        pointer-events: none;
        filter: opacity(1);
        border-radius: --var($theme, 'border-radius-ripple');
    }

    %switch-ripple--focused {
        @include animation('scale-in-out' 1s $ease-out-quad infinite);
        background: --var($theme, 'track-off-color');
        transition: background .2s $ease-out-quad;
        opacity: .12;
    }

    %switch-ripple--focused-checked {
        background: --var($theme, 'thumb-on-color');
    }

    %switch-label {
        display: inline-block;
        color: --var($theme, 'label-color');
        cursor: pointer;
        user-select: none;
        word-wrap: break-all;

        &:empty {
            margin: 0;
        }
    }

    %switch-label--before,
    %switch-label--after {
        &:empty {
            margin: 0;
        }
    }

    %switch-label--after {
        margin-#{$left}: $label-margin;
    }

    %switch-label--before {
        order: -1;
        margin-#{$right}: $label-margin;
    }

    %switch-label--disabled {
        color: --var($theme, 'label-disabled-color');
    }

    %switch-ripple--hover {
        &::after {
            position: absolute;
            content: '';
            opacity: .06;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
        }
    }

    %switch-ripple--hover-unchecked {
        &::after {
            background: --var($theme, 'track-off-color');
        }
    }

    %switch-ripple--hover-checked {
        &::after {
            background: --var($theme, 'thumb-on-color');
        }
    }

    %switch-ripple--pressed {
        &::after {
            opacity: .12;
        }
    }
}

/// Adds typography styles for the igx-checkbox component.
/// Uses the 'subtitle-1' category from the typographic scale.
/// @group typography
/// @param {Map} $type-scale - A typographic scale as produced by igx-type-scale.
/// @param {Map} $categories [(label: 'subtitle-1')] - The categories from the typographic scale used for type styles.
/// @requires {mixin} igx-type-style
@mixin igx-switch-typography(
    $type-scale,
    $categories: (label: 'subtitle-1')
) {
    $label: map-get($categories, 'label');

    %switch-label {
        @include igx-type-style($type-scale, $label) {
            margin-top: 0;
            margin-bottom: 0;
        }
    }
}
