// Background Grid Syntax
// ======================

$susy-overlay-grid-head-exists: false;


// Show Grid/s
// -----------
// Show grid on any element using either background or overlay.
// - [$grid]  : <settings>
@mixin show-grid(
  $grid: $susy
) {
  $output: debug-get(output, $grid);

  @if $output == overlay {
    @include overlay-grid($grid);
  } @else {
    @include background-grid($grid);
  }
}

@mixin show-grids(
  $grid: $susy
) {
  @include show-grid($grid);
}

// Background Grid
// ---------------
// Show a grid background on any element.
// - [$grid]  : <settings>
@mixin background-grid(
  $grid: $susy
) {
  $output: get-background($grid);

  @if length($output) > 0 {
    $flow: susy-get(flow, $grid);

    $image: ();
    @each $name, $layer in map-get($output, image) {
      $direction: if($name == baseline, to bottom, to to($flow));
      $image: append($image, linear-gradient($direction, $layer...), comma);
    }
    $output: map-merge($output, (image: $image));

    @include background-grid-output($output...);
  }
}


// Overlay Grid
// ------------
// Generate an icon to trigger grid-overlays on any given elements.
// $grids...  : <selector> [<settings>] [, <selector>]*
@mixin overlay-grid (
  $grid: $susy
) {
  @if not $susy-overlay-grid-head-exists {
    @at-root head { @include overlay-head; }
    $susy-overlay-grid-head-exists: true !global;
  }

  $selector: #{&};

  @at-root head:hover {
    ~ #{$selector},
    ~ body #{$selector} {
      position: relative;
      &::before {
        @include grid-overlay-base;
        @include background-grid($grid);
      }
    }
  }
}


// [Private] Overlay Head
// ----------------------
// <head> styles to create grid overlay toggle
@mixin overlay-head {
  $toggle: debug-get(toggle);
  $horz: null;
  $vert: null;

  @each $side in $toggle {
    $horz: if($side == left or $side == right, $side, $horz);
    $vert: if($side == top or $side == bottom, $side, $vert);
  }

  display: block;
  position: fixed;
  #{$horz}: 10px;
  #{$vert}: 10px;
  z-index: 999;
  color: #333;
  background: rgba(white, .25);
  &::before {
    content: "|||";
    display: block;
    padding: 5px 10px;
    font: {
      family: sans-serif;
      size: 16px;
      weight: bold;
    }
  }
  &:hover {
    box-shadow: 0 0 1px rgba(#333,.5);
    background: rgba(white, .5);
  }
}


// [Private] Grid Overlay Base
// ---------------------------
// Base styles for generating a grid overlay
@mixin grid-overlay-base() {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  content: " ";
  z-index: 998;
}


// Get Symmetrical Background
// --------------------------
// - $grid: <map>
@function get-background-sym(
  $grid
) {
  $grid           : parse-grid($grid);
  $gutters        : susy-get(gutters, $grid);
  $column-width   : susy-get(column-width, $grid);
  $math           : susy-get(math, $grid);

  $color          : debug-get(color);
  $trans          : transparent;
  $light          : lighten($color, 15%);

  $end            : 1 + $gutters;
  $after          : percentage(1/$end);
  $stops          : ();

  @if is-inside($grid) {
    $stops: $color, $light;
  } @else if is-split($grid) {
    $split: $gutters/2;
    $before: percentage($split/$end);
    $after: percentage((1 + $split)/$end);
    $stops: $trans $before, $color $before, $light $after, $trans $after;
  } @else {
    $stops: $color, $light $after, $trans $after;
  }

  $background: (
    image: (columns: $stops),
    size: if($math == static, $column-width * $end, span(1 $grid wide)),
  );

  @return $background;
}


// Get Asymmetrical Inside
// -----------------------
// - $grid: <settings>
@function get-asym-inside(
  $grid
) {
  $grid     : parse-grid($grid);
  $columns  : susy-get(columns, $grid);

  $color    : debug-get(color);
  $light    : lighten($color, 15%);
  $stops    : ();

  @for $location from 1 through column-count($columns) {
    $this-stop: ();

    @if $location == 1 {
      $this-stop: append($this-stop, $color, comma);
    } @else {
      $start: parse-span(1 at $location $grid);
      $start: get-isolation($start);
      $this-stop: append($this-stop, $color $start, comma);
    }

    @if $location == column-count($columns) {
      $this-stop: append($this-stop, $light, comma);
    } @else {
      $end: parse-span(1 at ($location + 1) $grid);
      $end: get-isolation($end);
      $this-stop: append($this-stop, $light $end, comma);
    }

    $stops: join($stops, $this-stop, comma);
  }

  @return $stops;
}


// Get Asymmetrical Split
// ----------------------
// - $grid: <settings>
@function get-asym-split(
  $grid
) {
  $grid     : parse-grid($grid);
  $columns  : susy-get(columns, $grid);

  $color    : debug-get(color);
  $light    : lighten($color, 15%);
  $stops    : ();

  @for $location from 1 through column-count($columns) {
    $this-stop: ();

    $start: parse-span(1 at $location $grid);
    $start: get-isolation($start);
    $this-stop: append($this-stop, transparent $start, comma);
    $this-stop: append($this-stop, $color $start, comma);

    $end: $start + span(1 at $location $grid);
    $this-stop: append($this-stop, $light $end, comma);
    $this-stop: append($this-stop, transparent $end, comma);

    $stops: join($stops, $this-stop, comma);
  }

  @return $stops;
}


// Get Asymmetrical Outside
// ------------------------
// - $grid: <settings>
@function get-asym-outside(
  $grid
) {
  $grid     : parse-grid($grid);
  $columns  : susy-get(columns, $grid);

  $color    : debug-get(color);
  $light    : lighten($color, 15%);
  $trans    : transparent;
  $stops    : ();

  @for $location from 1 through column-count($columns) {
    $this-stop: ();

    @if $location == 1 {
      $this-stop: append($this-stop, $color, comma);
    } @else {
      $start: parse-span(1 at $location $grid);
      $start: get-isolation($start);
      $this-stop: append($this-stop, $color $start, comma);
    }

    @if $location == column-count($columns) {
      $this-stop: append($this-stop, $light, comma);
    } @else {
      $gutter: get-span-width(first $location $grid);

      $end: parse-span(1 at ($location + 1) $grid);
      $end: get-isolation($end);

      $gutter: $light $gutter, $trans $gutter, $trans $end;
      $this-stop: join($this-stop, $gutter, comma);
    }

    $stops: join($stops, $this-stop, comma);
  }

  @return $stops;
}


// Get Asymmetrical Background
// ---------------------------
// - $grid: <settings>
@function get-background-asym(
  $grid
) {
  $stops: ();

  @if is-inside($grid) {
    $stops: get-asym-inside($grid);
  } @else if is-split($grid) {
    $stops: get-asym-split($grid);
  } @else {
    $stops: get-asym-outside($grid);
  }

  @return (image: (columns: $stops));
}


// Get Background
// --------------
// - $grid: <settings>
@function get-background(
  $grid
) {
  $grid     : parse-grid($grid);
  $show     : susy-get(debug image, $grid);
  $return   : ();

  @if $show and $show != hide {
    $line-height: variable-exists(base-line-height);
    $line-height: if($line-height, $base-line-height, false);
    $columns: susy-get(columns, $grid);

    @if $show != show-baseline {
      $sym: is-symmetrical($columns);
      $return: if($sym, get-background-sym($grid), get-background-asym($grid));
      $return: map-merge($return, (clip: content-box));
    } @else if not $line-height {
      @warn 'Please provide $base-line-height in order to see baseline grids.';
    }

    @if $line-height {
      @if $show != show-columns {
        $color: variable-exists(grid-background-baseline-color);
        $color: if($color, $grid-background-baseline-color, black);

        $image: map-get($return, image);
        $size: map-get($return, size);
        $baseline: (baseline: ($color 5%, rgba($color, 0) 5%));
        $baseline-size: 100% $line-height;

        $return: map-merge($return, (
          image: if($image, map-merge($image, $baseline), $baseline),
          size: if($size, append($size, $baseline-size, comma), $baseline-size),
        ));
      }

      @if $show == show {
        $clip: map-get($return, clip);
        $return: map-merge($return, (clip: join($clip, border-box, comma)));
      }
    }
  }

  @if map-get($return, image) {
    $return: map-merge($return, (flow: susy-get(flow, $grid)));
  }

  @return $return;
}


// Get Debug
// ---------
// Return the value of a debug setting
// - $key: <setting>
@function debug-get(
  $key,
  $grid: $susy
) {
  $key: join(debug, $key, space);
  @return susy-get($key);
}