// @TODO : documentation
@mixin s-loader-grid(
  $shape: rect,
  $color: s-color(primary),
  $cols: 5,
  $rows: 5,
  $size: 10px,
  $gap: 5px,
  $offset: 200px,
  $rotate: 0deg,
  $a-shape: null,
  $a-steps: 5,
  $a-spread: null,
  $a-rotate: null,
  $a-scale: null,
  $a-opacity: null,
  $a-duration: 1s,
  $a-delay: 0s,
  $a-ease: ease-in-out
) {
  @if $_sugar-test-arguments {
    $shape: s-test-argument("s-loader-grid", "shape", (rect, circle), $shape);
    $color: s-test-argument(
      "s-loader-grid",
      "color",
      "color|list-color",
      $color
    );
    $cols: s-test-argument("s-loader-grid", "cols", integer, $cols);
    $rows: s-test-argument("s-loader-grid", "rows", integer, $rows);
    $size: s-test-argument("s-loader-grid", "size", number, $size);
    $gap: s-test-argument("s-loader-grid", "gap", number, $gap);
    $offset: s-test-argument("s-loader-grid", "offset", number, $offset);
    $rotate: s-test-argument("s-loader-grid", "rotate", degree, $rotate);
    $a-shape: s-test-argument(
      "s-loader-grid",
      "a-shape",
      (rect, circle),
      $a-shape
    );
    $a-steps: s-test-argument("s-loader-grid", "a-steps", integer, $a-steps);
    $a-spread: s-test-argument("s-loader-grid", "a-spread", number, $a-spread);
    $a-rotate: s-test-argument("s-loader-grid", "a-rotate", degree, $a-rotate);
    $a-scale: s-test-argument("s-loader-grid", "a-scale", number, $a-scale);
    $a-opacity: s-test-argument(
      "s-loader-grid",
      "a-opacity",
      number,
      $a-opacity
    );
    $a-duration: s-test-argument(
      "s-loader-grid",
      "a-duration",
      second,
      $a-duration
    );
    $a-delay: s-test-argument("s-loader-grid", "a-delay", second, $a-delay);
    $a-ease: s-test-argument("s-loader-grid", "a-ease", string, $a-ease);
  }

  // handle colors
  $colors: null;
  @if s-is($color, list-color) and length($color) > 1 {
    $colors: $color;
  }

  // manage duration :
  $a-duration: $a-duration + $a-delay;

  width: $size;
  height: $size;
  @if $shape == circle {
    border-radius: 50%;
  }

  // position grid
  $width: $size * $cols + $gap * ($cols - 1);
  $height: $size * $rows + $gap * ($rows - 1);

  // @include s-translate((-$width / 2 - $size - $gap - $offset) (-$height / 2 - $size - $gap - $offset));
  transform: translateX(-$width / 2 - $size - $gap - $offset)
    translateY(-$height / 2 - $size - $gap - $offset) rotate($rotate);
  transform-origin: ($offset + $width / 2 + $gap + $size)
    ($offset + $height / 2 + $gap + $size);

  $a-name: unquote("grid-#{unique-id()}");

  // calculate box shadows
  $shadows: ();
  $color-idx: 1;
  @for $i from 0 through $cols - 1 {
    @for $j from 0 through $rows - 1 {
      $x: ($size * $i + $gap * $i) + $size + $gap + $offset;
      $y: ($size * $j + $gap * $j) + $size + $gap + $offset;
      $c: $color;
      @if $colors and length($colors) == $cols * $rows {
        $c: nth($colors, $color-idx);
        $color-idx: $color-idx + 1;
      } @else if length($colors) == 2 {
        @if $j % 2 == 0 {
          $color-idx: $color-idx - 1;
        }
        $c: nth($colors, $color-idx % 2 + 1);
      }
      $shadows: append($shadows, $c $x $y 0 0, comma);
    }
  }

  &:before {
    @if $shape == circle {
      border-radius: 50%;
    }
    position: relative;
    z-index: 1;
    content: "";
    display: block;
    width: $size;
    height: $size;
    animation: $a-name $a-duration $a-ease 0s infinite;
    box-shadow: $shadows;
    transform-origin: ($offset + $width / 2 + $gap + $size)
      ($offset + $height / 2 + $gap + $size);
  }

  // calculate percentage of delay
  $p-delay: 1 / $a-duration * $a-delay;
  // animation
  @keyframes #{$a-name} {
    @for $i from 1 through $a-steps {
      $percentage: percentage((1 - $p-delay) / $a-steps * $i);
      #{$percentage} {
        // loop on each box shadows
        $shadows: ();
        $color-idx: 1;
        @for $j from 0 through $cols - 1 {
          @for $k from 0 through $rows - 1 {
            $x: ($size * $j + $gap * $j) + $size + $gap + $offset;
            $y: ($size * $k + $gap * $k) + $size + $gap + $offset;
            $s-spread: 0;
            $blur: 0;
            $c: $color;
            @if $colors and length($colors) == $cols * $rows {
              $c: nth($colors, $color-idx);
              $color-idx: $color-idx + 1;
            } @else if length($colors) == 2 {
              @if $j % 2 != 0 {
                $color-idx: $color-idx - 1;
              }
              $c: nth($colors, $color-idx % 2 + 1);
            }
            $transparentize: 0;
            @if $a-opacity and $i < $a-steps {
              $transparentize: 1 - $a-opacity;
              $transparentize: $transparentize * 10;
              $t-rand: random($transparentize);
              $transparentize: $t-rand / 10;
              $c: transparentize($c, $transparentize);
            }
            @if $a-scale {
              @if $i >= $a-steps {
                $s-spread: 0;
              } @else {
                $s-spread: random($a-scale - $size) + 0px;
              }
            }
            @if $a-spread and $i < $a-steps {
              $randX: random($a-spread / 2);
              $randY: random($a-spread / 2);
              @if random(10) < 5 {
                $randX: $randX * -1;
              }
              @if random(10) < 5 {
                $randY: $randY * -1;
              }
              $x: $x + $randX;
              $y: $y + $randY;
            }
            @if $i >= $a-steps {
              $shadows: append($shadows, $c $x $y 0 0, comma);
            } @else {
              $shadows: append($shadows, $c $x $y $blur $s-spread, comma);
            }
          }
        }
        @if $a-rotate and $i < $a-steps {
          $randX: random($a-rotate / 2);
          @if random(10) < 5 {
            $randX: $randX * -1;
          }
          transform: rotateZ($randX + 0deg);
        } @else {
          transform: rotateZ(0);
        }
        @if $i < $a-steps - 1 {
          @if $a-shape == circle {
            @include s-corner(50%);
          } @else if $a-shape == rect {
            @include s-corner(0);
          }
        }
        // apply shadows
        box-shadow: $shadows;
      }
    }
  }
}
