/*!
 * Copyright (c) 2017 Edelweiss72 GmbH - All Rights Reserved
 * Unauthorized usage or distribution of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 *
 * @author Wladimir Eberts <w.eberts@edelweiss72.de>
 */

@function form-spinner-size($size, $parent) {
    @if unit($size) == '%' {
        @return round($parent * ($size / 100%));
    }

    @return $size;
}

@function form-spinner-step($time, $step, $limit) {
    $result: $time % ($limit + $step);

    @if $result > $limit {
        $result: 0s;
    }

    @return $result;
}

@mixin form-spinner-element($number) {
    $child: ceil($number / 2);

    @if $number % 2 == 0 {
        > :nth-child(#{$child})::after {
            @content;
        }
    }
    @else {
        > :nth-child(#{$child})::before {
            @content;
        }
    }
}

$form-spinner: 2 !default;
$form-spinner-delay: 1s !default;
$form-spinner-filter: grayscale(1) blur(5px) !default;
$form-spinner-width: 150px !default;
$form-spinner-height: 150px !default;
//$form-spinner-color: blue !default;
$form-spinner-color: red, yellow, lime, cyan, blue, magenta, red !default;
//$form-spinner-color: darken(crimson, 20%), crimson !default;

$form-spinner-elements: 32 !default;

$form-spinner-element-width: 10%;
$form-spinner-element-height: 5%;
$form-spinner-element-time: 1s / 20 !default;

$form-spinner-time: 1/2 * $form-spinner-elements * $form-spinner-element-time !default;
//$form-spinner-time: 4s !default;

$form-spinner-elements-max: 32;

.mod-form {
    > fieldset {
        @include if-parent('.mod-form.is-spinner') {
            opacity: 0.25;
            user-select: none;
            pointer-events: none;
            filter: $form-spinner-filter;
            transition: 0.5s ease-in $form-spinner-delay;
            transition-property: opacity, filter;
        }
    }

    .m-spinner {
        @include autoalpha(0);

        @include if-parent('.mod-form.is-spinner') {
            margin: auto;
            font-size: 0;
            pointer-events: none;
            @include autoalpha(1);
            width: $form-spinner-width;
            height: $form-spinner-height;
            @include absolute(0, 0, 0, 0);
            transition: opacity 0.5s ease-in $form-spinner-delay;

            @if $form-spinner == 1 {
                // convert percentage to absolute
                $form-spinner-element-width: form-spinner-size($form-spinner-element-width, $form-spinner-width) !global;

                width: auto;
                text-align: center;

                > ::before,
                > ::after {
                    content: '';
                    height: 100%;
                    margin: 0 1px;
                    display: inline-block;
                    width: $form-spinner-element-width;
                    animation: form-spinner $form-spinner-time infinite ease-in-out;

                    // set single color
                    @if length($form-spinner-color) == 1 {
                        background: nth($form-spinner-color, 1);
                    }
                }

                @for $i from 1 through $form-spinner-elements-max {
                    @include form-spinner-element($i) {
                        @if $i <= $form-spinner-elements {
                            $percent: ($i - 1) / $form-spinner-elements;

                            animation-delay: ($i - 1) * $form-spinner-element-time - 2 * $form-spinner-time;

                            // only coloroize on multiple colors
                            @if length($form-spinner-color) > 1 {
                                background: color-mix($percent, $form-spinner-color...);
                            }
                        }
                        @else {
                            @extend %form-spinner-element-hidden;
                        }
                    }
                }

                @keyframes form-spinner {
                    0%,
                    40%,
                    100% {
                        transform: scaleY(0.5);
                    }

                    20% {
                        transform: scaleY(1);
                    }
                }
            }

            @if $form-spinner == 2 {
                > ::before,
                > ::after {
                    content: '';
                    display: block;
                    border-radius: 0;
                    width: $form-spinner-element-width;
                    height: $form-spinner-element-height;
                    transform-origin: 50% ($form-spinner-height / 2);
                    @include absolute(0, 50% - $form-spinner-element-width / 2);
                    animation: form-spinner $form-spinner-time infinite ease-in-out both;

                    @if length($form-spinner-color) == 1 {
                        background: nth($form-spinner-color, 1);
                    }
                }

                @for $i from 1 through $form-spinner-elements-max {
                    @include form-spinner-element($i) {
                        @if $i <= $form-spinner-elements {
                            $percent: ($i - 1) / $form-spinner-elements;
                            //$y: (1 - cos($percent * 360deg)) / 2;
                            //$x: (1 + sin($percent * 360deg)) / 2;
                            //top: $y * (100% - $dot);
                            //left: $x * (100% - $dot);

                            @if $percent > 0 {
                                transform: rotate($percent * 360deg);
                            }

                            animation-delay: ($i - 1) * $form-spinner-element-time - 4 * $form-spinner-time;

                            @if length($form-spinner-color) > 1 {
                                background: color-mix($percent, $form-spinner-color...);
                            }
                        }
                        @else {
                            @extend %form-spinner-element-hidden;
                        }
                    }
                }

                @keyframes form-spinner {
                    0%,
                    39%,
                    100% {
                        opacity: 0;
                    }

                    40% {
                        opacity: 1;
                    }
                }
            }

            @if $form-spinner == 3 {
                $size: 0;
                $index-max: 0;

                // enforce 2x2, 3x3 or 4x4 elements
                @if $form-spinner-elements > 9 {
                    $size: 4;
                    $index-max: 7;
                    $form-spinner-elements: 16 !global;
                }
                @else if $form-spinner-elements > 4 {
                    $size: 3;
                    $index-max: 5;
                    $form-spinner-elements: 9 !global;
                }
                @else {
                    $size: 2;
                    $index-max: 3;
                    $form-spinner-elements: 4 !global;
                }

                > ::before,
                > ::after {
                    content: '';
                    display: inline-block;
                    width: round(100% / $size);
                    height: round(100% / $size);
                    animation: form-spinner $form-spinner-time infinite ease-in-out;

                    @if length($form-spinner-color) == 1 {
                        background: nth($form-spinner-color, 1);
                    }
                }

                @for $i from 1 through $form-spinner-elements-max {
                    @include form-spinner-element($i) {
                        @if $i <= $form-spinner-elements {
                            $row: ceil($i / $size);
                            $col: 1 + ($i - 1) % $size;
                            $index: $size - $row + $col;
                            $percent: ($index - 1) / $index-max;

                            animation-delay: $index * $form-spinner-element-time;

                            @if length($form-spinner-color) > 1 {
                                background: color-mix($percent, $form-spinner-color...);
                            }
                        }
                        @else {
                            @extend %form-spinner-element-hidden;
                        }
                    }
                }

                @keyframes form-spinner {
                    0%,
                    70%,
                    100% {
                        transform: scale(1);
                    }

                    35% {
                        transform: scale(0);
                    }
                }
            }

            @if $form-spinner == 4 {
                // convert percentage to absolute
                $form-spinner-element-width: form-spinner-size($form-spinner-element-width, $form-spinner-width) !global;

                border-radius: 50%;
                animation: form-spinner $form-spinner-time infinite linear;

                $color: nth($form-spinner-color, 1);
                $background: color-mix(90%, black, white);

                @if length($form-spinner-color) > 1 {
                    $background: nth($form-spinner-color, 2);
                }

                border: $form-spinner-element-width solid $background;
                border-left-color: $color;

                @keyframes form-spinner {
                    100% {
                        transform: rotate(360deg);
                    }
                }
            }

            @if $form-spinner == 5 {
                // convert percentage to absolute
                $form-spinner-element-width: form-spinner-size($form-spinner-element-width, $form-spinner-width) !global;
                $form-spinner-element-height: form-spinner-size($form-spinner-element-height, $form-spinner-height) !global;

                &::after {
                    content: '';
                    display: block;
                    border-radius: 50%;
                    width: $form-spinner-element-width;
                    height: $form-spinner-element-height;
                    transform: translateX(-2 * $form-spinner-element-width);
                    animation: form-spinner $form-spinner-time infinite ease;
                }

                @keyframes form-spinner {
                    $time: 0s;
                    $frames: max(1, $form-spinner-time / $form-spinner-element-time);
                    $time-per-frame: round($form-spinner-time / $frames * 1000000) / 1000000;
                    $time-per-step: round($form-spinner-element-time / max(1, $frames - 1) * 1000000) / 1000000;

                    @for $i from 0 through $frames - 1 {
                        $frame: round($i * (1 / $frames) * 100%);

                        // group frame 0% and 100%
                        @if $frame == 0% {
                            $frame: 0%, 100%;
                        }

                        #{$frame} {
                            $colors: ();
                            $shadows: ();

                            @for $n from 1 through $form-spinner-elements {
                                $percent: ($n - 1) / $form-spinner-elements;
                                $x: (1 + sin($percent * 360deg)) / 2;
                                $y: (1 - cos($percent * 360deg)) / 2;
                                $x: round($x * ($form-spinner-width - $form-spinner-element-width) + 2 * $form-spinner-element-width);
                                $y: round($y * ($form-spinner-height - $form-spinner-element-height));

                                // optimize css
                                @if $x == 0px {
                                    $x: 0;
                                }

                                // optimize css
                                @if $y == 0px {
                                    $y: 0;
                                }

                                $color: color-mix($percent, $form-spinner-color...);
                                $transparency: round(2 * (1 - (form-spinner-step($time, $time-per-step, $form-spinner-element-time) / $form-spinner-element-time)) * 10) / 10;

                                // node-sass precision bug
                                @if $transparency < 0.000001 {
                                    $transparency: 0;
                                }
                                @else if $transparency > 0.999999 {
                                    $transparency: 1;
                                }

                                // optimize css
                                @if $transparency == 1 {
                                    $color: transparent;
                                }
                                @else {
                                    $color: transparentize($color, $transparency);
                                }

                                $colors: append($colors, $x $y $color, comma);

                                //$shadow: $x $y 15px transparentize(black, $transparency);
                                //$shadows: append($shadows, $shadow, comma);

                                $time: $time + $time-per-step;
                            }

                            box-shadow: $colors, $shadows;
                        }

                        $time: $time + $time-per-frame;
                    }
                }
            }
        }
    }
}

%form-spinner-element-hidden {
    display: none;
}
