// Grids module
//
// The “grids” module contains most of the configurable variables and mixins you’ll need to create a layout.
//
// Weight: -10
//
// Style guide: grids

// Import the global variables needed by all of Zen Grids.
@import "./variables";
// Import the helper functions.
@import "./functions";

// zen-rtl()
//
// Includes inline Right-To-Left language support if the `$zen-rtl-selector` variable is set to `[dir="rtl"]` or some other useful CSS selector.
//
// Since `$zen-rtl-selector` defaults to `false`, inline Right-To-Left language support is off by default.
//
// $selector = $zen-rtl-selector - The RTL selector for this grid item. See the docs for [`$zen-rtl-selector`](section-grids.html#kssref-grids-variables-rtl-zen-rtl-selector).
//
// weight: 20
//
// Style guide: grids.zen-rtl

@mixin zen-rtl($selector: $zen-rtl-selector) {
  @if $selector {
    @if & {
      #{$selector} & {
        @content;
      }
    }
    @else {
      #{$selector} {
        @content;
      }
    }
  }
}

// zen-grid-container()
//
// Apply this to create a grid container element.
//
// If this grid is nested inside another grid, the `$context` parameter can be used to align the nested grid with the parent grid. `$context` can be set to `none` (the default), `grid-item`, or `flow`.
//
// If the nested grid’s container is a child element of the parent grid’s grid item, set `$context: flow`.
//
// Otherwise, if the nested grid’s container is the same element as the parent grid’s grid item, set `$context: grid-item` and apply this mixin *after* the [`zen-grid-item()`](#kssref-grids-zen-grid-item) mixin is applied for the parent grid. This mixin removes any gutters on the container since the nested grid will have its own gutters.
//
// Common usage:
// ```
// @include zen-grid-container();
// ```
// or:
// ```
// @include zen-grid-container(grid-item);
// ```
//
// $context            = none - If this grid is nested inside another grid, the `$context` parameter can be used to align the nested grid with the parent grid. It can be set to `none`, `grid-item`, or `flow`.
// $gutters            = $zen-gutters - The width of the gutters for this container. See the docs for [`$zen-gutters`](section-grids.html#kssref-grids-variables-zen-gutters).
// $gutter-method      = $zen-gutter-method - The gutter method to use for this container. See the docs for [`$zen-gutter-method`](section-grids.html#kssref-grids-variables-zen-gutter-method).
// $direction          = $zen-direction - The direction to use for this container. See the docs for [`$zen-direction`](section-grids.html#kssref-grids-variables-rtl-zen-direction).
// $switch-direction   = $zen-switch-direction - Whether to switch the default direction for this container. See the docs for [`$zen-switch-direction`](section-grids.html#kssref-grids-variables-rtl-zen-switch-direction).
// $rtl-selector       = $zen-rtl-selector - The RTL selector for this container. See the docs for [`$zen-rtl-selector`](section-grids.html#kssref-grids-variables-rtl-zen-rtl-selector).
//
// Style guide: grids.zen-grid-container
@mixin zen-grid-container(
  $context            : none,
  $gutters            : $zen-gutters,
  $gutter-method      : $zen-gutter-method,
  $direction          : $zen-direction,
  $switch-direction   : $zen-switch-direction,
  $rtl-selector       : $zen-rtl-selector
) {

  $dir: $direction;
  @if $switch-direction {
    $dir: zen-direction-switch($dir);
  }

  @if $context == flow-item {
    @warn "zen-grid-container()'s $context cannot be set to: flow-item. It has been set to: flow.";
    $context: flow;
  }
  @else if $context == grid {
    @warn "zen-grid-container()'s $context cannot be set to: grid. It has been set to: grid-item.";
    $context: grid-item;
  }

  // @TODO: This is a pre-IE8 line of code; don't remember why its needed.
  @if zen-support-for-ie(7) {
    *position: relative;
  }

  // We use the "micro clearfix", optimized to reduce the number of &.
  &:before {
    content: "";
    display: table;
  }
  &:after {
    content: "";
    display: table;
    clear: both;
  }
  @if zen-support-for-ie(7) {
    *zoom: 1;
  }

  // Un-do the gutter padding of the parent grid item.
  @if $context == flow and $gutter-method == padding {
    margin: {
      left: -(zen-half-gutter($gutters, left, $dir));
      right: -(zen-half-gutter($gutters, right, $dir));
    }

    // If $gutters is an odd number of pixels, we need special RTL handling.
    @if zen-half-gutter($gutters, left, $dir) != zen-half-gutter($gutters, right, $dir) {
      @include zen-rtl($rtl-selector) {
        margin: {
          left: -(zen-half-gutter($gutters, right, $dir));
          right: -(zen-half-gutter($gutters, left, $dir));
        }
      }
    }
  }

  // Prevent any padding from messing up the alignment of the nested grid.
  @if $context == grid-item or $context == flow {
    // Copy of undo-zen-apply-gutter-padding()
    padding: {
      left: 0;
      right: 0;
    }
  }
}

// zen-grid-item()
//
// Apply this to each grid item. Set the `$column-span` to the number of columns that the grid item spans. And set the `$column-position` to the column number the grid item starts on.
//
// To make the grid item float from the right, set the `$direction` to `right`; it defaults to `left` (the value of `$zen-direction`.) For grid items that are floated right, the `$column-position` is counted from the right instead of from the left.
//
// Common usage:
// ```
// // The grid item spans 2 columns starting from the 3rd column from the left,
// // e.g. It spans columns 3 and 4 counting from the left.
// @include zen-grid-item($column-span: 2, $column-position: 3);
// ```
// or:
// ```
// // The grid item spans 2 columns starting from the 3rd column from the right,
// // e.g. It spans columns 3 and 4 counting from the right.
// @include zen-grid-item(2, 3, right);
// ```
//
// $column-span        - Required. The number of columns the grid item will span.
// $column-position    - Required. The column number the grid item starts on.
// $direction          = $zen-direction - The floating direction to use for this grid item. See the docs for [`$zen-direction`](section-grids.html#kssref-grids-variables-rtl-zen-direction).
// $gutters            = $zen-gutters - The width of the gutters for this grid item. See the docs for [`$zen-gutters`](section-grids.html#kssref-grids-variables-zen-gutters).
// $gutter-method      = $zen-gutter-method - The gutter method to use for this grid item. See the docs for [`$zen-gutter-method`](section-grids.html#kssref-grids-variables-zen-gutter-method).
// $box-sizing         = $zen-box-sizing - The box sizing to use for this grid item. See the docs for [`$zen-box-sizing`](section-grids.html#kssref-grids-variables-zen-box-sizing).
// $switch-direction   = $zen-switch-direction - Whether to switch the default direction for this grid item. See the docs for [`$zen-switch-direction`](section-grids.html#kssref-grids-variables-rtl-zen-switch-direction).
// $rtl-selector       = $zen-rtl-selector - The RTL selector for this grid item. See the docs for [`$zen-rtl-selector`](section-grids.html#kssref-grids-variables-rtl-zen-rtl-selector).
// $include-base       = $zen-auto-include-grid-item-base - Whether to auto-include the zen-grid-item-base() mixin. See the docs for [`$zen-auto-include-grid-item-base`](section-grids.html#kssref-grids-variables-zen-auto-include-grid-item-base).
//
// Style guide: grids.zen-grid-item
@mixin zen-grid-item(
  $column-span,
  $column-position,
  $direction          : $zen-direction,
  $columns            : $zen-columns,
  $gutters            : $zen-gutters,
  $gutter-method      : $zen-gutter-method,
  $grid-width         : $zen-grid-width,
  $box-sizing         : $zen-box-sizing,
  $switch-direction   : $zen-switch-direction,
  $rtl-selector       : $zen-rtl-selector,
  $include-base       : $zen-auto-include-grid-item-base
) {

  // Calculate the unit width.
  $unit-width: zen-unit-width($columns, $gutters, $gutter-method, $grid-width);

  // Calculate the item's width.
  $width: zen-grid-item-width($column-span, $columns, $gutters, $gutter-method, $grid-width, $box-sizing);

  // Calculate the margin from the container's edge.
  $margin: ($column-position - 1) * $unit-width;
  @if $gutter-method == margin {
    $margin: $margin + (floor($column-position) - 1) * $gutters;
  }

  // Determine the float direction and its reverse.
  $dir: $direction;
  @if $switch-direction {
    $dir: zen-direction-switch($dir);
  }
  $rev: zen-direction-switch($dir);

  float: $dir;
  width: $width;
  margin: {
    #{$dir}: $margin;
    #{$rev}: -100%;
  }
  @if zen-support-for-ie(7) {
    // @TODO: This interpolation fails on libsass 3.3.0: *margin-#{$rev}: -99.9%;
    #{'*margin-' + $rev}: -99.9%;
  }
  @include zen-rtl($rtl-selector) {
    float: $rev;
    margin: {
      #{$rev}: $margin;
      #{$dir}: -100%;
    }
    @if zen-support-for-ie(7) {
      // @TODO: This interpolation fails on libsass 3.3.0: *margin-#{$rev}: -99.9%;
      #{'*margin-' + $dir}: -99.9%;
    }
  }

  // Include the grid item base mixin.
  @if $include-base {
    @include zen-grid-item-base($gutters, $gutter-method, $box-sizing, $direction, $switch-direction, $rtl-selector);
  }
  // If the $gutters parameter has been used, set the gutters even if
  // $include-base is false.
  @else if $gutters != $zen-gutters and $gutter-method == padding {
    @include zen-apply-gutter-padding($gutters, $direction, $switch-direction, $rtl-selector);
  }
}

// zen-grid-item-base()
//
// Applies a standard set of properties for grid items in the layout.
//
// See the documentation for the [`$zen-auto-include-grid-item-base`](#kssref-grids-variables-zen-auto-include-grid-item-base) and [`$zen-auto-include-flow-item-base`](section-flow.html#kssref-flow-variables-zen-auto-include-flow-item-base) variables for when to use this mixin.
//
// Common usage:
// ```
// @include zen-grid-item-base();
// ```
//
// $gutters            = $zen-gutters - The width of the gutters for this grid item. See the docs for [`$zen-gutters`](section-grids.html#kssref-grids-variables-zen-gutters).
// $gutter-method      = $zen-gutter-method - The gutter method to use for this grid item. See the docs for [`$zen-gutter-method`](section-grids.html#kssref-grids-variables-zen-gutter-method).
// $box-sizing         = $zen-box-sizing - The box sizing to use for this grid item. See the docs for [`$zen-box-sizing`](section-grids.html#kssref-grids-variables-zen-box-sizing).
// $direction          = $zen-direction - The floating direction to use for this grid item. See the docs for [`$zen-direction`](section-grids.html#kssref-grids-variables-rtl-zen-direction).
// $switch-direction   = $zen-switch-direction - Whether to switch the default direction for this grid item. See the docs for [`$zen-switch-direction`](section-grids.html#kssref-grids-variables-rtl-zen-switch-direction).
// $rtl-selector       = $zen-rtl-selector - The RTL selector for this grid item. See the docs for [`$zen-rtl-selector`](section-grids.html#kssref-grids-variables-rtl-zen-rtl-selector).
//
// weight: 10
//
// Style guide: grids.zen-grid-item-base
@mixin zen-grid-item-base(
  $gutters            : $zen-gutters,
  $gutter-method      : $zen-gutter-method,
  $box-sizing         : $zen-box-sizing,
  $direction          : $zen-direction,
  $switch-direction   : $zen-switch-direction,
  $rtl-selector       : $zen-rtl-selector
) {

  // Specify the padding if the gutter method uses padding.
  @if $gutter-method == padding {
    @include zen-apply-gutter-padding($gutters, $direction, $switch-direction, $rtl-selector);
  }

  // Specify the border-box properties.
  @if $box-sizing == border-box {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
  }
  // Prevent left/right borders since they'll break the layout with content-box.
  @else if $box-sizing == content-box {
    border: {
      left: 0 !important;
      right: 0 !important;
    }
    @if $gutter-method == margin {
      padding: {
        left: 0 !important;
        right: 0 !important;
      }
    }
  }

  @if zen-support-for-ie(7) {
    @if $box-sizing == border-box and $box-sizing-polyfill-path == "" {
      @warn 'Setting $box-sizing to border-box will fail for IE 7 and earlier because the $box-sizing-polyfill-path is empty.';
    }
    @if $box-sizing-polyfill-path != "" {
      *behavior: url($box-sizing-polyfill-path);
    }
    @if zen-support-for-ie(6) {
      // Display inline or double your floated margin!
      // @see http://www.positioniseverything.net/explorer/doubled-margin.html
      _display: inline;
      // Prevent overflowing content from breaking the layout.
      _overflow: hidden;
      // In IE6, overflow visible is broken.
      // @see http://www.howtocreate.co.uk/wrongWithIE/?chapter=overflow%3Avisible%3B
      _overflow-y: visible;
    }
    // Prevent overflowing content from being hidden beneath other grid items.
    *word-wrap: break-word;
  }
}

// zen-new-row()
//
// Apply this to a grid item so that it starts a new row.
//
// Common usage:
// ```
// @include zen-new-row();
// ```
// or:
// ```
// @include zen-new-row(right);
// ```
//
// $clear             = $zen-direction - The floating direction to use for this grid item. See the docs for [`$zen-direction`](section-grids.html#kssref-grids-variables-rtl-zen-direction).
// $switch-direction  = $zen-switch-direction - Whether to switch the default direction for this grid item. See the docs for [`$zen-switch-direction`](section-grids.html#kssref-grids-variables-rtl-zen-switch-direction).
// $rtl-selector      = $zen-rtl-selector - The RTL selector for this grid item. See the docs for [`$zen-rtl-selector`](section-grids.html#kssref-grids-variables-rtl-zen-rtl-selector).
//
// Style guide: grids.zen-new-row
@mixin zen-new-row(
  $clear              : $zen-direction,
  $switch-direction   : $zen-switch-direction,
  $rtl-selector       : $zen-rtl-selector
) {
  // Determine the clearing direction.
  @if $switch-direction {
    $clear: zen-direction-switch($clear);
  }
  clear: $clear;

  @if $clear == left or $clear == right {
    @include zen-rtl($rtl-selector) {
      clear: zen-direction-switch($clear);
    }
  }
}

// zen-apply-gutter-padding()
//
// Applies the gutter to a grid item when using the padding gutter method.
//
// Common usage:
// ```
// @include zen-apply-gutter-padding();
// ```
//
// $gutters           = $zen-gutters - The width of the gutters. See the docs for [`$zen-gutters`](section-grids.html#kssref-grids-variables-zen-gutters).
// $direction         = $zen-direction - The floating direction to use. See the docs for [`$zen-direction`](section-grids.html#kssref-grids-variables-rtl-zen-direction).
// $switch-direction  = $zen-switch-direction - Whether to switch the default direction. See the docs for [`$zen-switch-direction`](section-grids.html#kssref-grids-variables-rtl-zen-switch-direction).
// $rtl-selector      = $zen-rtl-selector - The RTL selector. See the docs for [`$zen-rtl-selector`](section-grids.html#kssref-grids-variables-rtl-zen-rtl-selector).
//
// weight: 30
//
// Style guide: grids.zen-apply-gutter-padding
@mixin zen-apply-gutter-padding(
  $gutters            : $zen-gutters,
  $direction          : $zen-direction,
  $switch-direction   : $zen-switch-direction,
  $rtl-selector       : $zen-rtl-selector
) {

  $dir: $direction;
  @if $switch-direction {
    $dir: zen-direction-switch($dir);
  }

  padding: {
    left: zen-half-gutter($gutters, left, $dir);
    right: zen-half-gutter($gutters, right, $dir);
  }

  // If $gutters is an odd number of pixels, we need special RTL handling.
  @if zen-half-gutter($gutters, left, $dir) != zen-half-gutter($gutters, right, $dir) {
    @include zen-rtl($rtl-selector) {
      padding: {
        left: zen-half-gutter($gutters, right, $dir);
        right: zen-half-gutter($gutters, left, $dir);
      }
    }
  }
}
