//------------------------------------
//      $WIDTHS
//------------------------------------

/// Second words used to represent numbers in a fraction; Corresponds to grid interval names (whole, half, third, etc.).
$_human-readable-numerators: one, two, three, four, five, six, seven, eight,
    nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen,
    eighteen, nineteen, twenty;

/// First words used to represent numbers in a fraction; Corresponds to grid interval names (one, two, three, etc.).
$_human-readable-denominators: whole, half, third, quarter, fifth, sixth,
    seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth,
    fifteenth, sixteenth, seventeenth, eighteenth, nineteenth, twentieth,
    twentyfirst, twentysecond, twentythird, twentyfourth, twentyfifth,
    twentysixth, twentyseventh, twentyeigth, twentyninth;

/// Creates a percentage based on the `$size / $context` while allowing for a contextual calculations (`($total/$context) * ($columns/$total)`).
///
/// For instance, if you have a grid of 12 columns and you've created an item that is 7 columns wide, its children would then be in a 7/12 context. In order to maintain the grid and calculate the width of a child that spans 4 columns, it would have to be 1 quarter of 7/12.
/// @example
///    .parent {
///       width: grid-size(7, 12);
///    }
///    .child {
///       width: grid-size(4, 7, 12);
///    }
/// @group grid
/// @param {number} $columns - Column span
/// @param {number} $context [$grid-columns] - Out of how many columns?
/// @param {number} $total-columns [$grid-columns] -
/// @returns {number} percentage
///
@function grid-size(
    $columns,
    $context: $grid-columns,
    $total-columns: $grid-columns
) {
    //Correct for nested columns() calls
    @if (unit($context) == '%') {
        $context: ($context / ($context * 0 + 1)) / 100;
        $context: $total-columns * $context;
    }
    $context: ($total-columns / $context);
    $columns: ($columns / $total-columns);

    @return percentage($context * $columns);
}

/// @alias grid-size
/// @group grid
///
@function columns($args...) {
    @return grid-size($args...);
}

/// Creates a width property with a percentage based on the `$columns / $total`. Also includes flex-based properties if `$grid-flex` is enabled.
/// @group grid
/// @param {number} $columns - Column span.
/// @param {number} $total [$grid-columns]
///
@mixin grid-width($columns, $total: $grid-columns) {
    width: #{grid-size($columns, $total)};
    @if $grid-flex {
        flex-basis: #{grid-size($columns, $grid-columns)};
        max-width: #{grid-size($columns, $grid-columns)};
    }
}

/// @alias grid-width
/// @group grid
///
@mixin width($args...) {
    @include grid-width($args...);
}

/// Uses `$_human-readable-numerators` and `$_human-readable-denominators` to create percentages based on `$grid-columns`. `$property` accepts any property, as well as lists of properties.
///
/// @group grid
///
/// @param {boolean} $silent [$grid-silent-classes] - Use silent classes?
/// @param {string} $property ["width"] - What property should these widths applied to?
/// @param {boolean} $important [false] - Should `!important` be applied to properties?
/// @param {string} $property ["width"] - What property should these widths applied to?
///
@mixin width-setup(
    $silent: $grid-silent-classes,
    $property: 'width',
    $important: false,
    $columns: $grid-columns,
    $format: '{%numerator%}-{%denominator%}'
) {
    $class-type: if($silent, '%', '.');
    $_: $class-type;
    $divisor: $columns;
    $class-name-list: ();
    $important: if($important, '!important', '');
    $space: '_';

    //To prevent stuff like 12/12 (five-fifths, etc.),
    // we need to declare 1/1 here
    #{$_}#{_class($format, (numerator: 'one', denominator: 'whole'))} {
        @each $type in $property {
            #{$type}: 100% #{$important};
        }
    }

    @for $i from 1 through $columns {
        @while $divisor > 0 {
            @for $dividen from 1 to $divisor {
                // Assign the numerator and denominator of our fraction to human-readable versions (e.g. three, four, third, quarter, etc.)
                $numerator: nth($_human-readable-numerators, $dividen);
                $denominator: nth($_human-readable-denominators, $divisor);

                // Divide first number(numerator) by second number(denominator).
                $size: grid-size($dividen, $divisor);

                // Pluralize anything other than ratios with a numerator of 1
                @if ($numerator != 'one') {
                    $denominator: '#{$denominator}s';
                }

                $class-name: _class(
                    $format,
                    (
                        class: '#{$numerator}-#{$denominator}',
                        numerator: $numerator,
                        denominator: $denominator,
                    )
                );

                #{$_}#{$class-name} {
                    @each $type in $property {
                        @if index('top' 'right' 'bottom' 'left', $type) != null
                        {
                            position: relative;
                        }
                        #{$type}: $size #{$important};
                    }
                }

                @if $grid-silent-classes and $debug-silent-classes {
                    $class-name-list: map-merge(
                        $class-name-list,
                        (
                            $class-name: $size,
                        )
                    );
                }
            }

            $divisor: $divisor - 1;
        }
    }

    // Add to silent class registry if asked for
    @if $silent and $debug-silent-classes {
        $class-name-list: map-merge(
            $class-name-list,
            (
                #{_class(
                        $format,
                        (
                            numerator: 'one',
                            denominator: 'whole',
                        )
                    )}:
                    100%
            )
        );
        $_silent-class-registry: silents-register(
            $class-name-list,
            $property
        ) !global;
    }
}
