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

/// If only background color is specified, text/icon color
/// will be assigned automatically to a contrasting color.
/// Does ___not___ apply for disabled state colors.
/// @param {Map} $palette [$default-palette] - The palette used as basis for the component theme.
/// @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 {border-radius} $flat-border-radius [null] - The border radius used for flat button.
/// @param {border-radius} $raised-border-radius [null] - The border radius used for raised button.
/// @param {border-radius} $outlined-border-radius [null] - The border radius used for outlined button.
/// @param {border-radius} $fab-border-radius [null] - The border radius used for fab button.
/// @param {border-radius} $icon-border-radius [null] - The border radius used for icon button.
/// @param {Color} $flat-background [null] - The background color of a flat button.
/// @param {Color} $flat-text-color [null] - The idle text color of a flat button.
/// @param {Color} $flat-hover-background [null] - The hover background color of a flat button.
/// @param {Color} $flat-hover-text-color [null] - The hover text color of a flat button.
/// @param {Color} $flat-focus-background [null] - The focus background color of a flat button.
/// @param {Color} $flat-focus-text-color [null] - The focus text color of a flat button.
/// @param {Color} $flat-icon-color [null] - The color of a flat button icon.
/// @param {Color} $flat-hover-icon-color [null] - The hover color of a flat button icon.
/// @param {Color} $flat-focus-icon-color [null] - The focus color of a flat button icon.
///
/// @param {Color} $outlined-background [null] - The background color of an outlined button.
/// @param {Color} $outlined-text-color [null] - The idle text color of an outlined button.
/// @param {Color} $outlined-outline-color [null] - The outline color of an outlined button.
/// @param {Color} $outlined-disabled-outline-color [null] - The outline color of an outlined, disabled button.
/// @param {Color} $outlined-hover-background [null] - The hover background color of an outlined button.
/// @param {Color} $outlined-hover-text-color [null] - The hover text color of an outlined button.
/// @param {Color} $outlined-focus-background [null] - The focus background color of an outlined button.
/// @param {Color} $outlined-focus-text-color [null] - The focus text color of an outlined button.
/// @param {Color} $outlined-icon-color [null] - The color of a outlined button icon.
/// @param {Color} $outlined-hover-icon-color [null] - The hover color of a outlined button icon.
/// @param {Color} $outlined-focus-icon-color [null] - The focus color of a outlined button icon.
///
/// @param {Color} $raised-background [null] - The background color of a raised button.
/// @param {Color} $raised-text-color [null] - The idle text color of a raised button.
/// @param {Color} $raised-hover-background [null] - The hover background of a raised button.
/// @param {Color} $raised-hover-text-color [null] - The hover text color of a raised button.
/// @param {Color} $raised-focus-background [null] - The focus background color of a raised button.
/// @param {Color} $raised-focus-text-color [null] - The focus text color of a raised button.
/// @param {Color} $raised-icon-color [null] - The color of a raised button icon.
/// @param {Color} $raised-hover-icon-color [null] - The hover color of a raised button icon.
/// @param {Color} $raised-focus-icon-color [null] - The focus color of a raised button icon.
///
/// @param {box-shadow} $raised-resting-shadow [null] - The shadow color of the raised button in its resting state.
/// @param {box-shadow} $raised-hover-shadow [null] - The shadow color of the raised button in its hover state.
/// @param {box-shadow} $raised-focus-shadow [null] - The shadow color of the raised button in its focus state.
///
/// @param {Color} $fab-background [null] - The background color of a floating action button.
/// @param {Color} $fab-text-color [null] - The text color of a floating action button.
/// @param {Color} $fab-hover-background [null] - The hover background color of a floating action button.
/// @param {Color} $fab-hover-text-color [null] - The hover text color of a floating action button.
/// @param {Color} $fab-focus-background [null] - The focus background color of floating action button.
/// @param {Color} $fab-focus-text-color [null] - The focus text color of a floating action button.
///
/// @param {box-shadow} $fab-resting-shadow [null] - The shadow color of the floating action button in its resting state.
/// @param {box-shadow} $fab-hover-shadow [null] - The shadow color of the floating action button in its hover state.
/// @param {box-shadow} $fab-focus-shadow [null] - The shadow color of the floating action button in its focus state.
///
/// @param {Color} $icon-color [null] - The icon color of an icon button.
/// @param {Color} $icon-hover-color [null] - The hover icon color of an icon button.
/// @param {Color} $icon-background [null] - The background color of the an icon button.
/// @param {Color} $icon-hover-background [null] - The hover background color of an icon button.
/// @param {Color} $icon-focus-color [null] - The focus icon color of an icon button.
/// @param {Color} $icon-focus-background [null] - The focus background color an icon button.
///
/// @param {Color} $disabled-color [null] - The disabled text/icon color of a button.
/// @param {Color} $disabled-background [null] - The disabled background color of raised, fab, or icon buttons.
///
/// @requires $default-palette
/// @requires $light-schema
/// @requires apply-palette
/// @requires extend
/// @requires text-contrast
/// @requires igx-elevation
/// @requires $elevations
/// @requires round-borders
///
/// @example scss Change the background and text colors in raised buttons
///   $my-button-theme: igx-button-theme(
///     $raised-text-color: white,
///     $raised-background: black
///   );
///   // Pass the theme to the igx-button component mixin
///   @include igx-button($my-button-theme);
@function igx-button-theme(
    $palette: $default-palette,
    $schema: $light-schema,
    $elevations: $elevations,

    $flat-border-radius: null,
    $raised-border-radius: null,
    $fab-border-radius: null,
    $icon-border-radius: null,
    $outlined-border-radius: null,

    $flat-text-color: null,
    $flat-background: null,
    $flat-hover-background: null,
    $flat-hover-text-color: null,
    $flat-focus-background: null,
    $flat-focus-text-color: null,
    $flat-icon-color: null,
    $flat-hover-icon-color: null,
    $flat-focus-icon-color: null,

    $outlined-text-color: null,
    $outlined-outline-color: null,
    $outlined-disabled-outline-color: null,
    $outlined-background: null,
    $outlined-hover-background: null,
    $outlined-hover-text-color: null,
    $outlined-focus-background: null,
    $outlined-focus-text-color: null,
    $outlined-icon-color: null,
    $outlined-hover-icon-color: null,
    $outlined-focus-icon-color: null,

    $raised-text-color: null,
    $raised-background: null,
    $raised-hover-background: null,
    $raised-hover-text-color: null,
    $raised-focus-background: null,
    $raised-focus-text-color: null,
    $raised-icon-color: null,
    $raised-hover-icon-color: null,
    $raised-focus-icon-color: null,

    $raised-resting-shadow: null,
    $raised-hover-shadow: null,
    $raised-focus-shadow: null,

    $fab-text-color: null,
    $fab-background: null,
    $fab-hover-background: null,
    $fab-hover-text-color: null,
    $fab-focus-background: null,
    $fab-focus-text-color: null,

    $fab-resting-shadow: null,
    $fab-hover-shadow: null,
    $fab-focus-shadow: null,

    $icon-color: null,
    $icon-background: null,
    $icon-hover-background: null,
    $icon-hover-color: null,
    $icon-focus-background: null,
    $icon-focus-color: null,

    $disabled-color: null,
    $disabled-background: null
) {
    $name: 'igx-button';
    $button-schema: ();

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

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

    $flat-border-radius: round-borders(
        if($flat-border-radius, $flat-border-radius, map-get($button-schema, 'flat-border-radius')), 0, 20px
    );

    $raised-border-radius: round-borders(
        if($raised-border-radius, $raised-border-radius, map-get($button-schema, 'raised-border-radius')), 0, 20px
    );

    $fab-border-radius: round-borders(
        if($fab-border-radius, $fab-border-radius, map-get($button-schema, 'fab-border-radius')), 12, 28px
    );

    $icon-border-radius: round-borders(
        if($icon-border-radius, $icon-border-radius, map-get($button-schema, 'icon-border-radius')), 0, 20px
    );

    $outlined-border-radius: round-borders(
        if($outlined-border-radius, $outlined-border-radius, map-get($button-schema, 'outlined-border-radius')), 0, 20px
    );

    @if not($flat-text-color) and $flat-background {
        $flat-text-color: text-contrast($flat-background);
    }

    @if not($flat-hover-background) and $flat-background {
        $flat-hover-background: lighten-color($flat-background, 5%);
    }

    @if not($flat-focus-background) and $flat-background {
        $flat-focus-background: lighten-color($flat-background, 5%);
    }

    @if not($flat-hover-text-color) and $flat-hover-background {
        $flat-hover-text-color: text-contrast($flat-hover-background);
    }

    @if not($flat-focus-text-color) and $flat-focus-background {
        $flat-focus-text-color: text-contrast($flat-focus-background);
    }

    @if not($outlined-text-color) and $outlined-background {
        $outlined-text-color: text-contrast($outlined-background);
    }

    @if not($outlined-hover-background) and $outlined-background {
        $outlined-hover-background: lighten-color($outlined-background, 5%);
    }

    @if not($outlined-focus-background) and $outlined-background {
        $outlined-focus-background: lighten-color($outlined-background, 5%);
    }

    @if not($outlined-hover-text-color) and $outlined-hover-background {
        $outlined-hover-text-color: text-contrast($outlined-hover-background);
    }

    @if not($outlined-focus-text-color) and $outlined-focus-background {
        $outlined-focus-text-color: text-contrast($outlined-focus-background);
    }

    @if not($raised-text-color) and $raised-background {
        $raised-text-color: text-contrast($raised-background);
    }

    @if not($raised-hover-background) and $raised-background {
        $raised-hover-background: lighten-color($raised-background, 5%);
    }

    @if not($raised-focus-background) and $raised-background {
        $raised-focus-background: lighten-color($raised-background, 5%);
    }

    @if not($raised-hover-text-color) and $raised-hover-background {
        $raised-hover-text-color: text-contrast($raised-hover-background);
    }

    @if not($raised-focus-text-color) and $raised-focus-background {
        $raised-focus-text-color: text-contrast($raised-focus-background);
    }

    @if not($fab-text-color) and $fab-background {
        $fab-text-color: text-contrast($fab-background);
    }

    @if not($fab-hover-background) and $fab-background {
        $fab-hover-background: lighten-color($fab-background, 5%);
    }

    @if not($fab-focus-background) and $fab-background {
        $fab-focus-background: lighten-color($fab-background, 5%);
    }

    @if not($fab-hover-text-color) and $fab-hover-background {
        $fab-hover-text-color: text-contrast($fab-hover-background);
    }

    @if not($fab-focus-text-color) and $fab-focus-background {
        $fab-focus-text-color: text-contrast($fab-focus-background);
    }

    @if not($icon-color) and $icon-background {
        $icon-color: text-contrast($icon-background);
    }

    @if not($icon-hover-background) and $icon-background {
        $icon-hover-background: lighten-color($icon-background, 5%);
    }

    @if not($icon-focus-background) and $icon-background {
        $icon-focus-background: lighten-color($icon-background, 5%);
    }

    @if not($icon-focus-color) and $icon-focus-background {
        $icon-focus-color: text-contrast($icon-focus-background);
    }

    @if not($icon-hover-color) and $icon-hover-background {
        $icon-hover-color: text-contrast($icon-hover-background);
    }

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

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

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

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

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

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

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

        flat-border-radius: $flat-border-radius,
        raised-border-radius: $raised-border-radius,
        fab-border-radius: $fab-border-radius,
        icon-border-radius: $icon-border-radius,
        outlined-border-radius: $outlined-border-radius,

        flat-text-color: $flat-text-color,
        flat-background: $flat-background,
        flat-hover-background: $flat-hover-background,
        flat-hover-text-color: $flat-hover-text-color,
        flat-focus-background: $flat-focus-background,
        flat-focus-text-color: $flat-focus-text-color,
        flat-icon-color: $flat-icon-color,
        flat-hover-icon-color: $flat-hover-icon-color,
        flat-focus-icon-color: $flat-focus-icon-color,

        outlined-text-color: $outlined-text-color,
        outlined-outline-color: $outlined-outline-color,
        outlined-disabled-outline-color: $outlined-disabled-outline-color,
        outlined-background: $outlined-background,
        outlined-hover-background: $outlined-hover-background,
        outlined-hover-text-color: $outlined-hover-text-color,
        outlined-focus-background: $outlined-focus-background,
        outlined-focus-text-color: $outlined-focus-text-color,
        outlined-icon-color: $outlined-icon-color,
        outlined-hover-icon-color: $outlined-hover-icon-color,
        outlined-focus-icon-color: $outlined-focus-icon-color,

        raised-text-color: $raised-text-color,
        raised-background: $raised-background,
        raised-hover-background: $raised-hover-background,
        raised-hover-text-color: $raised-hover-text-color,
        raised-focus-background: $raised-focus-background,
        raised-focus-text-color: $raised-focus-text-color,
        raised-icon-color: $raised-icon-color,
        raised-hover-icon-color: $raised-hover-icon-color,
        raised-focus-icon-color: $raised-focus-icon-color,

        fab-text-color: $fab-text-color,
        fab-background: $fab-background,
        fab-hover-background: $fab-hover-background,
        fab-hover-text-color: $fab-hover-text-color,
        fab-focus-background: $fab-focus-background,
        fab-focus-text-color: $fab-focus-text-color,

        icon-color: $icon-color,
        icon-background: $icon-background,
        icon-hover-background: $icon-hover-background,
        icon-hover-color: $icon-hover-color,
        icon-focus-background: $icon-focus-background,
        icon-focus-color: $icon-focus-color,

        disabled-color: $disabled-color,
        disabled-background: $disabled-background,

        raised-resting-shadow: $raised-resting-shadow,
        raised-hover-shadow: $raised-hover-shadow,
        raised-focus-shadow: $raised-focus-shadow,

        fab-resting-shadow: $fab-resting-shadow,
        fab-hover-shadow: $fab-hover-shadow,
        fab-focus-shadow: $fab-focus-shadow,
    ));
}

/// @param {Map} $theme - The theme used to style the component.
/// @requires {mixin} igx-root-css-vars
/// @requires rem
/// @requires --var
@mixin igx-button($theme) {
    @include igx-root-css-vars($theme);

    $button-border: 1px solid transparent;
    $button-width: rem(88px);

    $button-transition: background .15s $ease-in-out-cubic,
        color .15s $ease-in-out-cubic,
        border .15s $ease-in-out-cubic;

    $button-disabled-shadow: none;

    $button-floating-width: rem(56px);
    $button-floating-height: $button-floating-width;

    $button-icon-width: rem(36px, 16px);
    $button-icon-height: $button-icon-width;
    $button-icon-font-size: rem(24px, 24px);
    $button-icon-padding: 0;

    $button-padding-material: (
        comfortable: rem(9px, 16px) rem(16px, 16px),
        cosy: rem(6px, 16px) rem(16px, 16px),
        compact: rem(3px, 16px) rem(16px, 16px)
    );

    $button-padding-fluent: (
        comfortable: 0 rem(16px, 16px),
        cosy: 0 rem(16px, 16px),
        compact: 0 rem(16px, 16px)
    );

    $button-padding: map-get((
        material: $button-padding-material,
        fluent: $button-padding-fluent
    ), map-get($theme, variant));

    $button--size-material: (
        comfortable: rem(36px),
        cosy: rem(30px),
        compact: rem(24px)
    );

    $button--size-fluent: (
        comfortable: rem(32px),
        cosy: rem(28px),
        compact: rem(24px)
    );

    $button-size: map-get((
        material: $button--size-material,
        fluent: $button--size-fluent
    ), map-get($theme, variant));


    $button-floating-padding: (
        comfortable: rem(15px),
        cosy: rem(11px),
        compact: rem(7px)
    );

    $button-floating-size: (
        comfortable: rem(56px),
        cosy: rem(48px),
        compact: rem(40px)
    );

    $icon-in-button-size: rem(18px);

    %igx-button-display {
        position: relative;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: $button-width;
        padding: map-get($button-padding, 'comfortable');
        min-height: map-get($button-size, 'comfortable');
        border: none;
        cursor: pointer;
        user-select: none;
        outline-style: none;
        -webkit-tap-highlight-color: transparent;
        overflow: hidden;
        white-space: nowrap;
        transition: $button-transition;
        font-family: inherit;
        margin: 0;

        %igx-icon-display {
            width: $icon-in-button-size;
            height: $icon-in-button-size;
            font-size: $icon-in-button-size;
        }
    }

    %igx-button-display--cosy {
        padding: map-get($button-padding, 'cosy');
        min-height: map-get($button-size, 'cosy');
    }

    %igx-button-display--compact {
        padding: map-get($button-padding, 'compact');
        min-height: map-get($button-size, 'compact');
    }

    %igx-button--flat {
        background: --var($theme, 'flat-background');
        color: --var($theme, 'flat-text-color');
        border-radius: --var($theme, 'flat-border-radius');

        %igx-icon-display {
            color: --var($theme, 'flat-icon-color')
        }

        &:hover {
            background: --var($theme, 'flat-hover-background');
            color: --var($theme, 'flat-hover-text-color');

            %igx-icon-display {
                color: --var($theme, 'flat-hover-icon-color')
            }
        }

        &:focus,
        &:active {
            background: --var($theme, 'flat-focus-background');
            color: --var($theme, 'flat-focus-text-color');

            %igx-icon-display {
                color: --var($theme, 'flat-focus-icon-color')
            }
        }
    }

    %igx-button--outlined {
        border: $button-border;
        border-color: --var($theme, 'outlined-outline-color');
        background: --var($theme, 'outlined-background');
        color: --var($theme, 'outlined-text-color');
        border-radius: --var($theme, 'outlined-border-radius');

        %igx-icon-display {
            color: --var($theme, 'outlined-icon-color')
        }

        &:hover {
            background: --var($theme, 'outlined-hover-background');
            color: --var($theme, 'outlined-hover-text-color');

            %igx-icon-display {
                color: --var($theme, 'outlined-hover-icon-color')
            }
        }

        &:focus,
        &:active {
            background: --var($theme, 'outlined-focus-background');
            color: --var($theme, 'outlined-focus-text-color');

            %igx-icon-display {
                color: --var($theme, 'outlined-focus-icon-color')
            }
        }
    }

    %igx-button--raised {
        color: --var($theme, 'raised-text-color');
        background: --var($theme, 'raised-background');
        box-shadow: --var($theme, 'raised-resting-shadow');
        border-radius: --var($theme, 'raised-border-radius');

        %igx-icon-display {
            color: --var($theme, 'raised-icon-color')
        }

        &:focus,
        &:hover {
            color: --var($theme, 'raised-hover-text-color');
            background: --var($theme, 'raised-hover-background');
            box-shadow: --var($theme, 'raised-hover-shadow');


            %igx-icon-display {
                color: --var($theme, 'raised-hover-icon-color')
            }
        }

        &:active {
            color: --var($theme, 'raised-focus-text-color');
            background: --var($theme, 'raised-focus-background');
            box-shadow: --var($theme, 'raised-focus-shadow');

            %igx-icon-display {
                color: --var($theme, 'raised-focus-icon-color')
            }
        }
    }

    %igx-button--round {
        display: inline-flex;
        position: relative;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        border: $button-border;
        border-radius: --var($theme, 'fab-border-radius');
        outline: none;
        cursor: pointer;
        transition: $button-transition;
        user-select: none;
        -webkit-tap-highlight-color: transparent;
        overflow: hidden;
        // hack to allow circular overflow in safari...
        filter: blur(0);
    }

    %igx-button--fab {
        padding: map-get($button-floating-padding, 'comfortable');
        min-width: map-get($button-floating-size, 'comfortable');
        min-height: map-get($button-floating-size, 'comfortable');
        line-height: unset;
        white-space: nowrap;
        color: --var($theme, 'fab-text-color');
        background: --var($theme, 'fab-background');
        box-shadow: --var($theme, 'fab-resting-shadow');
        border-radius: --var($theme, 'fab-border-radius');

        &:hover {
            color: --var($theme, 'fab-hover-text-color');
            background: --var($theme, 'fab-hover-background');
            box-shadow: --var($theme, 'fab-hover-shadow');
        }

        &:focus,
        &:active {
            color: --var($theme, 'fab-focus-text-color');
            background: --var($theme, 'fab-focus-background');
            box-shadow: --var($theme, 'fab-focus-shadow');
        }
    }

    %igx-button--fab-cosy {
        padding: map-get($button-floating-padding, 'cosy');
        min-width: map-get($button-floating-size, 'cosy');
        min-height: map-get($button-floating-size, 'cosy');
    }

    %igx-button--fab-compact {
        padding: map-get($button-floating-padding, 'compact');
        min-width: map-get($button-floating-size, 'compact');
        min-height: map-get($button-floating-size, 'compact');
    }

    %igx-button--icon {
        width: $button-icon-width;
        height: $button-icon-width;
        font-size: $button-icon-font-size;
        padding: $button-icon-padding;
        color: --var($theme, 'icon-color');
        background: --var($theme, 'icon-background');
        border-radius: --var($theme, 'icon-border-radius');

        &:hover {
            transition: $button-transition;
            color: --var($theme, 'icon-hover-color');
            background: --var($theme, 'icon-hover-background');
        }

        &:focus,
        &:active {
            color: --var($theme, 'icon-focus-color');
            background: --var($theme, 'icon-focus-background');
        }
    }

    %igx-button--disabled {
        pointer-events: none;
        box-shadow: none;

        &%igx-button--flat,
        &%igx-button--outlined,
        &%igx-button--raised,
        &%igx-button--fab,
        &%igx-button--icon {
            color: --var($theme, 'disabled-color');
        }

        &%igx-button--raised,
        &%igx-button--fab {
            background: --var($theme, 'disabled-background');
        }

        &%igx-button--flat,
        &%igx-button--outlined {
            background: transparent;
        }

        &%igx-button--outlined {
            border-color: --var($theme, 'outlined-disabled-outline-color');
        }

        &:focus {
            box-shadow: none;
        }
    }
}

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

    %igx-button-display {
        @include igx-type-style($type-scale, $text) {
            text-align: center;
        }
    }
}
