// ---------------------------------------------------------------------------
// Imports

// We need access to some basic font settings for handling media-queries.
@import "compass/typography/vertical_rhythm";

// For now, we also need this...
$browser-default-font-size-px       : 16px;
$browser-default-font-size-percent  : 100%;
$browser-default-font-size-pt       : 12pt;

$rem-with-px-fallback               : true !default;

// ---------------------------------------------------------------------------
// Sass list Functions

// Return a list with specific items removed
//
// filter($list, $target)
// - $list    : The list to filter.
// - $target  : An item to be removed from the list.
@function filter($list, $target) {
  $clean: compact();
  @if index($list, $target) {
    @each $item in $list {
      $clean: if($item == $target, $clean, append($clean, $item));
    }
  } @else { $clean: $list; }
  @return $clean;
}

// ---------------------------------------------------------------------------
// Don't use static output when it will break things

// Switch element-level output to fluid, when container-width is wrong for static
//
// fix-static-misalignment([$style, $width])
// - $style: $container-style.
// - $width: $container-width.
@function fix-static-misalignment(
  $style: $container-style,
  $width: $container-width
) {
  @if $container-width and $container-width != container-outer-width($width: false) {
    $style: fluid;
  }
  @return $style;
}

// ---------------------------------------------------------------------------
// Grid Functions

// Returns the full width of a grid based on your grid settings.
//
//  $columns  : The number of columns to get width for.
@function columns-width(
  $columns  : $total-columns
) {
  @if round($columns) != $columns {
    @warn "Susy works best with integer column-spans." +
    "For partial-columns, you may need to finesse the math by hand using functions directly.";
  }
  @return ($columns * $column-width) + (if($columns >= 1, ceil($columns - 1), 0) * $gutter-width);
}

// Return the grid width after adding or subtracting grid padding
//
// $width     : the width of the grid without padding;
// $operation : ( add | subtract ) if padding should be added or subtracted;
@function handle-grid-padding(
  $width,
  $operation : subtract
) {
  $pad: $grid-padding*2;

  @if comparable($width, $grid-padding) {
    $width: if($operation == subtract, $width - $pad, $width + $pad);
  } @else {
    @warn "$grid-padding must be set in units comparable to the container width.";
  }

  @return $width;
}

// Return the full outer width of a Container element.
//
//  $columns  : The number of columns in the Grid Layout.
@function container-outer-width(
  $columns  : $total-columns,
  $width    : $container-width
) {
  $outerwidth: if($width, $width, columns-width($columns));

  @if $width {
    @if not($border-box-sizing) { $outerwidth: handle-grid-padding($outerwidth, subtract); }
  } @else {
    @if $border-box-sizing { $outerwidth: handle-grid-padding($outerwidth, add); }
  }

  @return $outerwidth;
}

// Return the percentage width of a single column in a given 'context'.
//
//  $context  : The grid context in columns, if nested.
//  $style    : The container style to use.
@function column(
  $context  : $total-columns,
  $style    : fix-static-misalignment()
) {
  @return if($style == static, $column-width, relative-width($column-width, $context));
}

// Return the percentage width of multiple 'columns' in a given 'context'.
//
//  $columns  : The number of columns to get relative width for.
//  $context  : The grid context in columns, if nested.
//  $style    : The container style to use.
@function columns(
  $columns,
  $context  : $total-columns,
  $style    : fix-static-misalignment()
) {
  @return if($style == static, columns-width($columns), relative-width(columns-width($columns), $context));
}

// Return the percentage width of a single gutter in a given 'context'.
//
//  $context  : The grid context in columns, if nested.
//  $style    : The container style to use.
@function gutter(
  $context  : $total-columns,
  $style    : fix-static-misalignment()
) {
  @return if($style == static, $gutter-width, relative-width($gutter-width, $context));
}

// Return the percentage width of a given value in a given 'context'.
//
//  $width    : Any given width value.
//  $context  : The grid context in columns, if nested.
@function relative-width(
  $width,
  $context : $total-columns
) {
  @return percentage($width / columns-width($context));
}

// Return the total space occupied by multiple columns and associated gutters.
// Useful for adding padding or margins (prefix, suffix, push, pull, etc.)
//
//  $columns  : The number of columns to get relative space for.
//  $context  : The grid context in columns, if nested.
//  $style    : The container style to use.
@function space(
  $columns,
  $context  : $total-columns,
  $style    : fix-static-misalignment()
) {
  @return columns($columns, $context, $style) + if($columns >= 1, gutter($context, $style), 0);
}

// Accept a list including column-count and (optional) position.
// Return either the column count or the position alone.
//
//  $columns  : the list to split and interprate.
//  $request  : The value to return, either 'columns' or 'position'.
@function split-columns-value(
  $columns,
  $request : columns
) {
  $pos  : false;
  $cols : false;

  @each $var in $columns {
    @if (type-of($var) == 'string') {
      $pos: $var;
    } @else {
      @if (type-of($var) == 'number') and (unitless($var)) {
        $cols: $var;
      } @else {
        @warn '"#{$var}" is not a valid part of "$columns: #{$columns}" in the columns() mixin.';
      }
    }
  }

  @if $request == 'columns' {
    @return $cols;
  } @else {
    @if $request == 'position' {
      @return $pos;
    } @else {
      @warn '"#{$request}" is not a valid value for $request';
    }
  }
}

// Accept nth-selector variables, and format them as a valid CSS3 selector.
//
// $n         : [first | only | last | <equation>]
// $selector  : [child | last-child | of-type | last-of-type ]
@function format-nth(
  $n        : last,
  $selector : child
) {
  @if ($n == 'last') or ($n =='first') or ($n =='only') {
    $selector: '#{$n}-#{$selector}';
  } @else {
    $selector: 'nth-#{$selector}(#{$n})';
  }
  @return $selector;
}

// ---------------------------------------------------------------------------
// Media Functions

// Return an em value adjusted to match the browser default font size.
// Note: This only works if actual sizes are set relative to browser defaults.
//
// $ems         : The initial value to be converted.
// $font-size   : The current font-size in.
@function base-ems(
  $ems,
  $font-size: $base-font-size
){
  $font-size  : if(unit($ems) == 'rem', $base-font-size, $font-size);
  $unit       : unit($font-size);
  $mult       : $ems / ($ems * 0 + 1);

  @if $unit == 'px' {
    @return $font-size / $browser-default-font-size-px * $mult * 1em;
  }
  @else if $unit == '%' {
    @return $font-size / $browser-default-font-size-percent * $mult * 1em;
  }
  @else if $unit == 'em' {
    @return $font-size / 1em * $mult * 1em;
  }
  @else if $unit == 'pt' {
    @return $font-size / $browser-default-font-size-pt * $mult * 1em;
  }
  @else {
    @warn 'Variable $base-font-size does not have a valid font unit. Valid units for fonts in CSS are px, pt, em, and %.';
  }
}

// This name will be deprecated...
@function absolute-ems(
  $ems,
  $font-size: $base-font-size
){
  @return base-ems( $ems, $font-size);
  }

// Return a length, after any em-values have been sent through absolute-ems().
//
// $length      : The length value to be checked and adjusted if necessary.
// $font-size   : The current font-size in px.
@function fix-ems(
  $length,
  $font-size: $base-font-size
){
  @if $length {
    @if (unit($length) == 'em') or (unit($length) == 'rem') {
      $length: absolute-ems($length,$font-size);
    }
  }
  @return $length;
}

// Sort a list of arguments into "$min $layout $max $ie" order, and return the list.
//
// $media-layout  : a list of values [$min $layout $max $ie] including...
//                : - one unitless number (columns in a layout)
//                : - two optional lengths (min and max-width media-query breakpoints).
//                : - one optional boolean or string to trigger fallback support for IE.
// $font-size     : [optional] The base font-size of your layout, if you are using ems.
//                : - defaults to $base-font-size
@function medialayout(
  $media-layout,
  $font-size: $base-font-size
) {
  $media        : false;
  $min          : false;
  $layout       : false;
  $max          : false;
  $ie           : false;
  $has-layout   : false;

  @each $val in $media-layout {
    @if (type-of($val) == "number") {
      @if unitless($val) {
        $layout     : $val;
        $has-layout : true;
      } @else {
        @if ($has-layout) and not($media) {
          $max: $val;
        } @else {
          @if $media {
            $media: join($media,$val);
          } @else {
            $media: $val;
          }
        }
      }
    } @else {
      $ie: $val;
    }
  }
  @if (length($media) > 0) {
    @if (length($media) == 1) {
      $min: nth($media,1);
    } @else {
      $min: nth($media,1);
      $max: nth($media,2);
      @if comparable($min, $max) {
        @if ($min > $max) {
          $max: nth($media,1);
          $min: nth($media,2);
        }
      } @else {
        @warn "Can't compare incompatible units." +
         "Using #{$min} for min-width, and #{$max} for max-width";
      }
      @if (length($media) > 2) {
        @warn "You can only send two lengths: a min-width and an (optional) max-width." +
         "You sent #{length($media)}: #{$media}";
      }
    }
  }

  // media-queries must be set in ems relative to the browser default
  // rather than the font-size set in CSS.
  $min: fix-ems($min,$font-size);
  $max: fix-ems($max,$font-size);

  @return $min $layout $max $ie;
}

// Return the nearest layout (column-count) above a given breakpoint.
//
// $min : The min-width media-query breakpoint above which to establish a new layout.
@function get-layout(
  $min
) {
  $min      : fix-ems($min);
  $return   : false;

  @if comparable($min, $column-width) {
    $return : ceil(($min + $gutter-width) / ($column-width + $gutter-width));
  } @else {
    @warn "Can't determine a layout, becuse #{$min} and #{$column-width} are not comparable.";
  }

  @return $return;
}

// Check to see if a given $media-layout list is simply the default.
//
// $media-layout  : a list of values including -
//                : One unitless number (columns in a layout)
//                : Two optional lengths (min and max-width media-query breakpoints).
//                : One optional boolean or string to trigger fallback support for IE.
@function is-default-layout(
  $media-layout
) {
  $media-layout : medialayout($media-layout);
  $min          : nth($media-layout,1);
  $layout-cols  : nth($media-layout,2);
  $max          : nth($media-layout,3);

  @if $min or $max {
    @return false;
  } @else {
    @return if($layout-cols == $total-columns,true,false);
  }
}
