//------------------------------------
//    $DISPLAY UTILITIES
//------------------------------------

$_default-display-classes: (
    'show': 'block',
    'bl': 'block',
    'ilbl': 'inline-block',
    'tbl': 'table',
    'tblcl': 'table-cell',
    'hide': 'none',
    'flex': 'flex',
    'block': 'block',
    'inline_block': 'inline-block',
    'table_cell': 'table-cell',
    'table': 'table',
);

/// A description of class names and their associated `display` value. Used for generating utility classes via `display-classes` mixin.
/// @group config
/// @type map
///
$display-classes: $_default-display-classes !default;

/// Formatting for utility display classes.
/// @see format-class-name
///
$display-class-format: 'display-{%display%}' '{\\@}{%breakpoint%}' !default;

/// Generates classes with display properties defined in `$class-list`. Intelligently extends duplicated display properties.
/// @param {Boolean} $silent [false]
/// @param {Boolean} $important [true]
/// @param {List} $class-list [$display-classes]
/// @param {List | String} $format [$display-class-format]
///
@mixin _output-display-classes(
    $silent: false,
    $important: true,
    $class-list: $display-classes,
    $format: $display-class-format
) {
    $class-type: if($silent, unquote('%'), unquote('.'));
    $important_str: if($important, ' !important', '');
    $display-lookup: null;
    $display-registry: ();
    $class-name-list: ();

    @each $name, $display in $class-list {
        $class-name: #{class-type}#{format-class-name(
                $format,
                (
                    'display': $display,
                )
            )};
        // Check for existence of a previous class using the same display
        $display-lookup: index($display-registry, $display);
        // If it exists, look it up in the map and extend that value.
        @if $display-lookup != null {
            $extender: nth(nth($class-list, $display-lookup), 1);

            #{$class-name} {
                @extend #{$class-type}#{$namespace}#{$extender};
            }
        } @else {
            #{$class-name} {
                display: #{$display}#{$important_str};
            }
        }

        // Keep track of display values so we can extend if necessary
        @if index($display-registry, '#{$display}') != null {
            @if $silent and $debug-silent-classes {
                $class-name-list: map-merge(
                    $class-name-list,
                    (
                        $class-name: $display,
                    )
                );
            }

            //Make sure duplicate values get a uniqueID so it's not extended
            $display: $display + '' + length($display-registry);
        }
        $display-registry: append($display-registry, '#{$display}', comma);
    }

    //Register silent class names for debugging
    @if $silent and $debug-silent-classes {
        $_silent-class-registry: silents-register(
            $class-name-list,
            'display'
        ) !global;
    }
}

/// The responsive component to `_output-display-classes`. Invokes `_output-display-classes`
/// while looping through a set of media-queries defined in `$breakpoints`.
/// This is most useful for creating responsive display classes.
///
/// @group core
///
/// @param {list} $breakpoints [$_all-breakpoints] - list of breakpoint names to loop over
/// @param {string} $namespace [''] - String to prepend to classes.
/// @param {boolean} $silent [false] - Generate silent classes?
/// @param {boolean} $important [false] - Add `!important` to declarations?
///
@mixin display-classes(
    $breakpoints: map-keys($breakpoints),
    $namespace: '',
    $silent: false,
    $important: false,
    $format: $display-class-format
) {
    $classes: $display-classes;

    @if $silent {
        //Merge user-defined classes with defaults
        // (so we have a wide-array of silent classes)
        $classes: map-extend($_default-display-classes, $display-classes, true);
    }

    @include _output-display-classes(
        $silent,
        $important,
        $classes,
        $format:
            format-class-list(
                $format,
                (
                    breakpoint: '',
                )
            )
    );

    @each $name in $breakpoints {
        @include media-query($name) {
            $name: $name;

            @include _output-display-classes(
                $silent,
                $important,
                $classes,
                $format:
                    format-class-list(
                        $format,
                        (
                            breakpoint: $name,
                        )
                    )
            );
        }
    }
}

/// @alias display-classes
///
@mixin display-utilities-init($args...) {
    @include display-classes($args...);
}
