// Default variables
$spacing-sizes: (
  0: 0,
  1: 0.25rem,
  2: 0.5rem,
  3: 1rem,
  4: 2rem,
  5: 4rem,
  6: 8rem,
) !default;
$spacing-important: false !default;

// retrieve spacing from $spacing-sizes map ie. `spacing(3)`
@function spacing($size) {
  @return map-get($spacing-sizes, $size);
}

// Mixins
// Margin
@mixin ml($size: 1) {
  @if ($size == 'auto') {
    margin-left: auto #{if($spacing-important, '!important', '')};
  }

  @else {
    margin-left: spacing($size) #{if($spacing-important, '!important', '')};
  }
}

@mixin mt($size: 1) {
  margin-top: spacing($size) #{if($spacing-important, '!important', '')};
}

@mixin mr($size: 1) {
  @if ($size == 'auto') {
    margin-right: auto #{if($spacing-important, '!important', '')};
  }

  @else {
    margin-right: spacing($size) #{if($spacing-important, '!important', '')};
  }
}

@mixin mb($size: 1) {
  margin-bottom: spacing($size) #{if($spacing-important, '!important', '')};
}

@mixin mx($r: 1, $l: null) {
  @if ($r and $l) {
    @include mr($r);
    @include ml($l);
  }

  @else if ($r and not $l) {
    @include mr($r);
    @include ml($r);
  }

  @else {
    @error "mx(#{$r}, #{$l}): Invalid parameters. Expects mx($size) or mx($r, $l)";
  }
}

@mixin my($t: 1, $b: null) {
  @if ($t and $b) {
    @include mt($t);
    @include mb($b);
  }

  @else if ($t and not $b) {
    @include mt($t);
    @include mb($t);
  }

  @else {
    @error "my(#{$t}, #{$b}): Invalid parameters. Expects my($size) or my($t, $b)";
  }
}

@mixin m($t: 1, $r: null, $b: null, $l: null) {
  @if ($t and $r and $b and $l) {
    @include mt($t);
    @include mr($r);
    @include mb($b);
    @include ml($l);
  }

  @else if ($t and $r and $b and not $l) {
    @include mt($t);
    @include mx($r);
    @include mb($b);
  }

  @else if ($t and $r and not $b and not $l) {
    @include my($t);
    @include mx($r);
  }

  @else if ($t and not $r and not $b and not $l) {
    @if ($t == 'auto') {
      @include my(0); //be explicit about what the browser does
      @include mx(auto);
    }

    @else {
      @include my($t);
      @include mx($t);
    }
  }

  @else {
    @error "m(#{$t}, #{$r}, #{$b}, #{$l}): Invalid parameters. Expects m($size), m($y, $x), m($t, $x, $b) or m($t, $r, $b, $l)";
  }
}

// Padding
@mixin pl($size: 1) {
  padding-left: spacing($size) #{if($spacing-important, '!important', '')};
}

@mixin pt($size: 1) {
  padding-top: spacing($size) #{if($spacing-important, '!important', '')};
}

@mixin pr($size: 1) {
  padding-right: spacing($size) #{if($spacing-important, '!important', '')};
}

@mixin pb($size: 1) {
  padding-bottom: spacing($size) #{if($spacing-important, '!important', '')};
}

@mixin px($r: 1, $l: null) {
  @if ($r and $l) {
    @include pr($r);
    @include pl($l);
  }

  @else if ($r and not $l) {
    @include pr($r);
    @include pl($r);
  }

  @else {
    @error "px(#{$r}, #{$l}): Invalid parameters. Expects px($size) or px($r, $l)";
  }
}

@mixin py($t: 1, $b: null) {
  @if ($t and $b) {
    @include pt($t);
    @include pb($b);
  }

  @else if ($t and not $b) {
    @include pt($t);
    @include pb($t);
  }

  @else {
    @error "py(#{$t}, #{$b}): Invalid parameters. Expects py($size) or py($t, $b)";
  }
}

@mixin p($t: 1, $r: null, $b: null, $l: null) {
  @if ($t and $r and $b and $l) {
    @include pt($t);
    @include pr($r);
    @include pb($b);
    @include pl($l);
  }

  @else if ($t and $r and $b and not $l) {
    @include pt($t);
    @include px($r);
    @include pb($b);
  }

  @else if ($t and $r and not $b and not $l) {
    @include py($t);
    @include px($r);
  }

  @else if ($t and not $r and not $b and not $l) {
    @include py($t);
    @include px($t);
  }

  @else {
    @error "p(#{$t}, #{$r}, #{$b}, #{$l}): Invalid parameters. Expects p($size), p($y, $x), p($t, $x, $b) or p($t, $r, $b, $l)";
  }
}
