$breakpoints: $grid-breakpoints;
// -----------------------
// ---- Config variables
$util-class-prefix: "u-";

// -- Margin
// default [example: (15px, 1em, 2rem) ]
$margin-top: ();
$margin-bottom: (2rem, 1rem);
$margin-left: ();
$margin-right: ();
// mirrored [example: (50: 50px, 60-50: (60px, 50px)]
$margin-vertical: ();
$margin-horizontal: ();

// -- Padding
// default [example: (15px, 1em, 2rem, (10: 10px) ]
$padding-top: ();
$padding-bottom: ();
$padding-left: ();
$padding-right: ();
// mirrored [example: (50: 50px, 60-50: (60px, 50px)]
$padding-vertical: ();
$padding-horizontal: ();

// -- Font size [example: (12px, 1em, 2rem) ]
$font-sizes: ();

// -- Font weight [example: ((weight-1-name: 300), (weight-2-name: 600), 300, 600) ]
$font-weights: ();

// -- Color [example: (color-1-name: #dadada, color-2-name: #fafafa) ]
$colors: ();

// -- Text transform [example: (uppercase, capitalize) ]
$text-transforms: ();

// -- Text align [example: (left, right, center) ]
$text-aligns: (center, right, left);

// -- Line height [example: (1em, 1, 25px, (1\.5: 1.5)) ]
$line-heights: ();

// -- Icon [example: (name: (50px, 40px), name: 60px, name: 2em, name: (1em, 1.2em), name: (50px, 50px) ]
$icons: ();

// -- Max-width [example: (50px, (100\%: 100%), 2em) ]
$max-widths: ();

// -- Height [example: (50px, (100\%: 100%), 2em) ]
$heights: ();

// -- Font families [example: (font-default: $font, font-headers: $font-headers)]
$font-families: ();

// ----------------------------------
// ---- Mixins for generate classess
// -- Universal mixins
@mixin generate-for-one-prop($name, $css-attr, $config, $generateBP: false) {
  @if (type-of($config)==map) {
    @each $config-name,
    $config-value in $config {
      .#{$util-class-prefix}#{$name}-#{$config-name} {
        #{$css-attr}: $config-value;
      }
    }
  }
  @else {
    @each $config-value in $config {
      @if (type-of($config-value)==map) {
        @each $cnf-name,
        $cnf-value in $config-value {
          .#{$util-class-prefix}#{$name}-#{$cnf-name} {
            #{$css-attr}: $cnf-value;
          }
        }
      }
      @else {
        .#{$util-class-prefix}#{$name}-#{$config-value} {
          #{$css-attr}: $config-value;
        }
      }
    }
  }

  @if $generateBP {
    @each $breakpoint,
    $value in $breakpoints {
      @media (min-width: $value) {
        @if (type-of($config)==map) {
          @each $config-name,
          $config-value in $config {
            .#{$util-class-prefix}#{$name}-#{$config-name}\@#{$breakpoint} {
              #{$css-attr}: $config-value;
            }
          }
        }
        @else {
          @each $config-value in $config {
            @if (type-of($config-value)==map) {
              @each $cnf-name,
              $cnf-value in $config-value {
                .#{$util-class-prefix}#{$name}-#{$cnf-name}\@#{$breakpoint} {
                  #{$css-attr}: $cnf-value;
                }
              }
            }
            @else {
              .#{$util-class-prefix}#{$name}-#{$config-value}\@#{$breakpoint} {
                #{$css-attr}: $config-value;
              }
            }
          }
        }
      }
    }
  }
}

@mixin generate-for-many-props($name, $props, $config, $generateBP: false) {
  @each $config-name,
  $config-value in $config {
    @if (type-of($config-value)==list) {
      .#{$util-class-prefix}#{$name}-#{$config-name} {
        @for $i from 1 to length($props)+1 {
          $cnf-name: nth($props, $i);
          $cnf-value: nth($config-value, $i);

          #{$cnf-name}: $cnf-value;
        }
      }
    }
    @else {
      .#{$util-class-prefix}#{$name}-#{$config-name} {
        $val: $config-value;
        @if ($val==null) {
          $val: $config-name;
        }
        @each $prop in $props {
          #{$prop}: $val;
        }
      }
    }
  }

  @if $generateBP {
    @each $breakpoint,
    $value in $breakpoints {
      @media (min-width: $value) {
        @each $config-name,
        $config-value in $config {
          @if (type-of($config-value)==list) {
            .#{$util-class-prefix}#{$name}-#{$config-name}\@#{$breakpoint} {
              @for $i from 1 to length($props)+1 {
                $cnf-name: nth($props, $i);
                $cnf-value: nth($config-value, $i);

                #{$cnf-name}: $cnf-value;
              }
            }
          }
          @else {
            .#{$util-class-prefix}#{$name}-#{$config-name}\@#{$breakpoint} {
              $val: $config-value;
              @if ($val==null) {
                $val: $config-name;
              }
              @each $prop in $props {
                #{$prop}: $val;
              }
            }
          }
        }
      }
    }
  }
}

// -- Margins
// --------------------------
// ---- Generation
// -- Margin
@include generate-for-one-prop(mt, margin-top, $margin-top);
@include generate-for-one-prop(mb, margin-bottom, $margin-bottom);
@include generate-for-one-prop(ml, margin-left, $margin-left);
@include generate-for-one-prop(mr, margin-right, $margin-right);

@include generate-for-many-props(mv, (margin-top, margin-bottom), $margin-vertical);
@include generate-for-many-props(mh, (margin-left, margin-right), $margin-horizontal);

// -- Padding
@include generate-for-one-prop(pt, padding-top, $padding-top);
@include generate-for-one-prop(pb, padding-bottom, $padding-bottom);
@include generate-for-one-prop(pl, padding-left, $padding-left);
@include generate-for-one-prop(pr, padding-right, $padding-right);

@include generate-for-many-props(pv, (padding-top, padding-bottom), $padding-vertical);
@include generate-for-many-props(ph, (padding-left, padding-right), $padding-horizontal);

// -- Font size
@include generate-for-one-prop(fs, font-size, $font-sizes);

// -- Font weight
@include generate-for-one-prop(fw, font-weight, $font-weights);

// -- Color
@include generate-for-one-prop(color, color, $colors);

// -- Text transform
@include generate-for-one-prop(tt, text-transform, $text-transforms, true);

// -- Text align
@include generate-for-one-prop(ta, text-align, $text-aligns, true);

// -- Line height
@include generate-for-one-prop(lh, line-height, $line-heights);

// -- Icon
@include generate-for-many-props(icon, (min-width, max-width, height), $icons);

// -- Width
@include generate-for-one-prop(mw, max-width, $max-widths);

// -- Height
@include generate-for-one-prop(h, height, $heights);

// -- Font-families
@include generate-for-one-prop(ff, font-family, $font-families);
