// Span Syntax
// ===========

// Span [mixin]
// ------------
// Set a spanning element using shorthand syntax.
// - $span  : <span>
@mixin span(
  $span
) {
  $inspect: $span;
  $span: parse-span($span);
  $output: span-math($span);
  $nesting: susy-get(span, $span);
  $clear: susy-get(clear, $span);

  $box: susy-get(box-sizing, $span);
  $content-box: if(susy-get(global-box-sizing) != 'border-box', true, false);
  $box: $box or if(is-inside($span) and $content-box, border-box, null);

  @if $clear == break {
    @include break;
  } @else if $clear == nobreak {
    @include nobreak;
  }

  @include susy-inspect(span, $inspect);
  @include output((box-sizing: $box));
  @include float-span-output($output...);

  @if valid-columns($nesting, silent) {
    @include nested($span) { @content; }
  } @else {
    @content;
  }
}

// Span [function]
// ---------------
// Return the width of a span.
// - $span  : <span>
@function span(
  $span
) {
  @return get-span-width($span);
}

// Span Math
// ---------
// Get all the span results.
// - $span: <map>
@function span-math(
  $span
) {
  $nest             : if(susy-get(role, $span) == nest, true, false);
  $split-nest       : if(is-split($span) and $nest, true, false);
  $edge             : get-edge($span);
  $location         : get-location($span);

  $float            : from;
  $padding-before   : null;
  $padding-after    : null;
  $margin-before    : null;
  $margin-after     : null;

  // calculate widths
  $spread: index(map-values($span), spread);
  $span: if($split-nest and not($spread), map-merge($span, (spread: wide)), $span);
  $width: get-span-width($span);
  $gutters: get-gutters($span);

  // apply gutters
  @if is-inside($span) {
    @if not(susy-get(role, $span)) {
      $padding-before: map-get($gutters, before);
      $padding-after: map-get($gutters, after);
    }
  } @else {
    @if not($split-nest) {
      $margin-before: map-get($gutters, before);
      $margin-after: map-get($gutters, after);
    }
  }

  // special margin handling
  @if susy-get(output, $span) == isolate and $location {
    $margin-before: get-isolation($span);
    $margin-after: -100%;
  } @else if $edge {
    $is-split: is-split($span);
    $pos: susy-get(gutter-position, $span);

    @if $edge == last {
      $float: susy-get(last-flow, $span);
    }

    @if not($is-split) {
      @if $edge == full or ($edge == first and $pos == before) {
        $margin-before: 0;
      }
      @if $edge == full or ($edge == last and $pos == after) {
        $margin-after: 0;
      }
    }

  }

  @return (
    width           : $width,
    float           : $float,
    margin-before   : $margin-before,
    margin-after    : $margin-after,
    padding-before  : $padding-before,
    padding-after   : $padding-after,
    flow            : susy-get(flow, $span),
  );
}

// Get Span Width
// --------------
// Return span width.
// - $span: <map>
@function get-span-width(
  $span
) {
  $span     : parse-span($span);

  $n        : susy-get(span, $span);
  $location : get-location($span);
  $columns  : susy-get(columns, $span);
  $gutters  : susy-get(gutters, $span);
  $spread   : susy-get(spread, $span);

  $context  : null;
  $span-sum : null;
  $width    : null;

  @if $n == 'full' {
    $pos: susy-get(gutter-position, $span);
    $role: susy-get(role, $span);
    $n: if($pos == split and $role != nest, susy-count($columns), 100%);
  }

  @if type-of($n) != number {
    @warn "(#{type-of($n)}) #{$n} is not a valid span.";
  } @else if unitless($n) {
    $context: susy-sum($columns, $gutters, if(is-split($span), wide, narrow));
    $spread: if(is-inside($span), $spread or wide, $spread);
    $span-sum: susy($n, $location, $columns, $gutters, $spread);

    $_math: susy-get(math, $span);
    $_column-width: susy-get(column-width, $span);
    @if $_math == static {
      $width: $span-sum * valid-column-math($_math, $_column-width);
    } @else {
      $width: percentage($span-sum / $context);
    }
  } @else {
    $width: $n;
  }

  @return $width;
}
