// /*------------------------------------*\
//     #FONT-SIZE
// \*------------------------------------*/

@use "sass:math";
@use "sass:map";
@use "../settings/settings.config" as *;
@use "../tools/tools.ms" as *;
@use "../tools/tools.line-height" as *;

/// Generates a font-size declaration and (optionally) an equivalent
/// line-height.
///
/// @param {number | length } $font-size [0] - Determine the font-size by using a value
///   of the modular scale.
/// @param {number | string} $line-height [auto] - By default, the line-height
///   will be automatically calculated, so it sits in the vertical grid. You
///   can override that with a custom value. Allowed keywords are `"normal"`,
///   `"inherit"`, `"none"` and `"false"`.
/// @param {number} $line-height-modifier [false] - Increase and decrease the
///   generated line-height in increments.
/// @param {boolean} $important [false] - Output the generated declarations with
///   an `!important`.
///
/// @example scss - Default mixin usage with Modular Scale entity value via the `ms()` function
///     .foo {
///         @include fluidms-font-size(
///             $font-size: ms(4)
///         );
///     }
///
/// @example scss - Assign a custom line-height
///     .foo {
///         @include fluidms-font-size(
///             $line-height: 50px
///         );
///     }
///
/// @example scss - No line-height output
///     .foo {
///         @include fluidms-font-size(
///             $line-height: false
///         );
///     }
///
/// @example scss - Adjust the line-height in increments (integers)
///     .foo {
///         @include fluidms-font-size(
///             $line-height-modifier: 2
///         );
///     }
///
/// @example scss - Add `!important` to generated declarations
///     .foo {
///         @include fluidms-font-size(
///             $important: true
///         );
///     }
///
/// @output The mixin outputs a `font-size` with a CSS `calc` function using CSS
///   custom properties and an optional `line-height` declaration.
@mixin fluidms-font-size(
    $font-size: ms(0),
    $line-height: auto,
    $line-height-modifier: false,
    $important: false
) {

    // Enable/disable `!important` output.
    @if ($important == true) {
        $important: !important;
    } @else if ($important == false) {
        $important: null;
    } @else {
        @error "`$important` needs to be `true` or `false`.";
    }

    // Only execute when `$font-size` is a unitless number.
    @if (type-of($font-size) == number and unitless($font-size)) {
        // Calculate the font-size.
        font-size: 1rem * (math.pow(map.get($CONFIG, ratio), $font-size)) $important;

        // If multiple ratios are defined for different breakpoints.
        @each $key, $value in $CONFIG {
            @if (type-of($key) == number) {
                @if (unit($key) == "px") {
                    @media screen and (min-width: $key) {
                        // Exclude all the scales that are smaller than the
                        // base font-size, so that small type will not get
                        // smaller on larger viewports.
                        @if not (str-index(#{$font-size}, "-")) {
                            font-size: 1rem * (math.pow(map.get($value, ratio), $font-size)) $important;
                        }
                    }
                }
            }
        }

        @if ($line-height == auto) {
            @if $GLOBAL-BASELINE {
                // Calculate the line-height at runtime by using the generated
                // `--ms<n>-line-height` CSS custom properties.
                $_line-height: fluidms-line-height($font-size, map.get($CONFIG, ratio));
                // If the line-height is modified, add/subtract that from the
                // calculated line-height.
                @if $line-height-modifier {
                    $_line-height: calc((#{fluidms-line-height($font-size, map.get($CONFIG, ratio))}) + #{$line-height-modifier * $GLOBAL-BASELINE});
                }
                line-height: $_line-height $important;

                // If multiple ratios are defined for different breakpoints.
                @each $key, $value in $CONFIG {
                    @if (type-of($key) == number) {
                        @if (unit($key) == "px") {
                            @media screen and (min-width: $key) {
                                // Exclude all the scales that are smaller than the
                                // base font-size, so that small type will not get
                                // smaller on larger viewports.
                                @if not (str-index(#{$font-size}, "-")) {
                                    // Calculate the line-height at runtime by using the generated
                                    // `--ms<n>-line-height` CSS custom properties.
                                    $_line-height: fluidms-line-height($font-size, map.get($value, ratio));
                                    // If the line-height is modified, add/subtract that from the
                                    // calculated line-height.
                                    @if $line-height-modifier {
                                        $_line-height: calc((#{fluidms-line-height($font-size, map.get($value, ratio))}) + #{$line-height-modifier * $GLOBAL-BASELINE});
                                    }
                                    line-height: $_line-height $important;
                                }
                            }
                        }
                    }
                }

            } @else {
                @if $line-height-modifier {
                    @warn _lineHeightModifierHasNoEffect();
                }
            }
        } @else {
            line-height: _validateLineHeight($line-height) $important;
        }
    }
    // If `$font-size` is anything but a unitless number.
    @else {
        // Just output the passed in font-size value.
        font-size: $font-size $important;
        @if ($line-height == auto) {
            @if $GLOBAL-BASELINE {
                // If the font-size is custom, just output the
                // `$GLOBAL-LINE-HEIGHT` as `em` value, so we can use `calc`
                // with it when a line-height modifier is used.
                $_line-height: $GLOBAL-LINE-HEIGHT * 1em;
                // If the line-height is modified, add/subtract that from the
                // calculated line-height.
                @if $line-height-modifier {
                    $_line-height: calc(#{$_line-height} + #{$line-height-modifier * $GLOBAL-BASELINE});
                }
                line-height: $_line-height $important;
            } @else {
                @if $line-height-modifier {
                    @warn _lineHeightModifierHasNoEffect();
                }
            }
        } @else {
            line-height: _validateLineHeight($line-height) $important;
        }
    }

}

@function _lineHeightModifierHasNoEffect() {
    @return "`$line-height-modifier` has no effect when `$GLOBAL-BASELINE` is set to `false`.";
}

@function _validateLineHeight($value) {
    @if ($value == "none" or $value == false) {
        // Avoid CSS output (conditional declaration).
        @return null;
    } @else if (type-of($value) == number or $value == "inherit" or $value == "normal") {
        @return $value;
    } @else {
        @error "`#{$value}` is not a valid value for `$line-height`.";
    }
}
