@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>
////

/// Checkbox Theme
/// @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 {Color} $label-color [null]- The text color used for the label text.
/// @param {Color} $empty-color [null] - The unchecked border color.
/// @param {Color} $fill-color [null] - The checked border and fill colors.
/// @param {Color} $tick-color [null] - The checked mark color.
/// @param {Color} $disabled-color [null] - The disabled border and fill colors.
/// @param {border-radius} $border-radius [null] - The border radius used for checkbox component.
/// @param {border-radius} $border-radius-ripple [null] - The border radius used for checkbox ripple.
/// Set to light when the surrounding area is dark.
///
/// @requires $default-palette
/// @requires $light-schema
/// @requires apply-palette
/// @requires extend
///
/// @example scss Change the checked fill color
///   $my-checkbox-theme: igx-checkbox-theme($fill-color: magenta);
///   // Pass the theme to the igx-checkbox component mixin
///   @include igx-checkbox($my-checkbox-theme);
@function igx-checkbox-theme(
    $palette: $default-palette,
    $schema: $light-schema,

    $border-radius: null,
    $label-color: null,
    $empty-color: null,
    $fill-color: null,
    $tick-color: null,
    $disabled-color: null,
    $disabled-color-label: null,
    $border-radius-ripple: null
) {
    $name: 'igx-checkbox';
    $checkbox-schema: ();

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

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

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

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

    @return extend($theme, (
        name: $name,
        palette: $palette,
        label-color: $label-color,
        empty-color: $empty-color,
        fill-color: $fill-color,
        tick-color: $tick-color,
        disabled-color: $disabled-color,
        disabled-color-label: $disabled-color-label,
        border-radius: $border-radius,
        border-radius-ripple: $border-radius-ripple
    ));
}

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

    @include scale-in-out($start-scale: .9);

    // If updating the WIDTH of the checkbox here, please update it in the grid theme as well.
    // It is under the name of $cbx-size
    $size: em(20px);
    $checkbox-radius: $size / 2;

    $border-width: map-get((
        material: 2px,
        fluent: 1px
    ), map-get($theme, variant));

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

    $label-margin: em(8px);
    $radius: 2px;

    $mark-stroke: map-get((
        material: 3,
        fluent: 1
    ), map-get($theme, variant));

    $mark-offset: map-get((
        material: 0,
        fluent: -1px
    ), map-get($theme, variant));

    $mark-length: 24;
    $mark-x-factor: $mark-stroke / $mark-length;

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

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

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

    @include scale-in-center();

    %cbx-display {
        position: relative;
        display: inline-flex;
        flex-flow: row nowrap;
        align-items: center;
        outline-style: none;
    }

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

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

    %cbx-composite-wrapper {
        position: relative;
        width: $size;
        height: $size;
    }

    %cbx-composite {
        position: relative;
        display: inline-block;
        cursor: pointer;
        width: $size;
        height: $size;
        min-width: $size;
        border-width: rem($border-width);
        border-style: solid;
        border-color: --var($theme, 'empty-color');
        border-radius: --var($theme, 'border-radius');
        -webkit-tap-highlight-color: transparent;
        transition: border-color .2s $ease-out-quad;
        overflow: hidden;

        &::after {
            position: absolute;
            content: '';
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            transition: background .2s $ease-out-quad;
        }
    }

    %cbx-composite--x {
        border-color: --var($theme, 'fill-color');
        background: --var($theme, 'fill-color');

        &::after {
            background: --var($theme, 'fill-color');
        }
    }

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

    %cbx-composite--x--disabled {
        background: --var($theme, 'disabled-color');

        &::after {
            background: --var($theme, 'disabled-color');
        }
    }

    %cbx-composite-mark {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        stroke: --var($theme, 'tick-color');
        stroke-linecap: square;
        stroke-width: $mark-stroke;
        stroke-dasharray: $mark-length;
        stroke-dashoffset: $mark-length;
        fill: none;
        opacity: 0;
        z-index: 1;
        transition: opacity .1s $ease-out-quad;
    }

    %igx-checkbox--indeterminate {
        %cbx-composite-mark {
            top: $mark-offset;
            left: $mark-offset;
        }
    }

    %cbx-composite-mark--x {
        stroke-dashoffset: 0;
        opacity: 1;
        transition: all .2s $ease-out-quad, opacity .2s $ease-out-quad;
    }

    %cbx-composite-mark--in {
        stroke-dashoffset: 41; /* length of path - adjacent line length */
        opacity: 1;
        transform: rotate(45deg) translateX(-#{$mark-x-factor}em);
    }

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

        &:empty {
            margin: 0;
        }
    }

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

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

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

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

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

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

    %cbx-ripple--focused-checked {
        background: --var($theme, 'fill-color');
    }

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

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

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

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

    %cbx-display--plain {
        %cbx-composite,
        %cbx-composite::after,
        %cbx-composite-mark,
        %cbx-composite-mark--x {
            transition: none;
        }
    }
}

/// 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-checkbox-typography(
    $type-scale,
    $categories: (label: 'subtitle-1')
) {
    $label: map-get($categories, 'label');

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