/**
 * Style an element as a column with a gutter.
 * @param {number} [$ratios=1] - A width relative to its container as a fraction.
 * @param {number} [$offset=0] - A offset specified as a fraction (see $ratios).
 * @param {number} [$cycle=0] - Easily create an nth column grid where $cycle equals the number of columns.
 * @param {number} [$uncycle=0] - Undo a previous cycle value to allow for a new one.
 * @param {number} [$gutter=$jeet-gutter] - Specify the gutter width as a percentage of the containers width.
 */
@mixin column($ratios: 1, $offset: 0, $cycle: 0, $uncycle: 0, $gutter: $jeet-gutter) {
  $side: jeet-get-layout-direction();
  $opposite-side: jeet-opposite-direction($side);
  $column-widths: jeet-get-column($ratios, $gutter);
  $margin-last: 0;
  $margin-l: $margin-last;
  $margin-r: nth($column-widths, 2);

  @if $offset != 0 {
    @if $offset < 0 {
      $offset: $offset * -1;
      $offset: nth(jeet-get-column($offset, nth($column-widths, 2)), 1);
      $margin-last: $offset + nth($column-widths, 2) * 2;
      $margin-r: $margin-last;
    } @else {
      $offset: nth(jeet-get-column($offset, nth($column-widths, 2)), 1);
      $margin-l: $offset + nth($column-widths, 2);
    }
  }

  @include cf;
  float: $side;
  clear: none;
  text-align: inherit;
  width: nth($column-widths, 1) * 1%;
  margin: {
    #{$side}: $margin-l * 1%;
    #{$opposite-side}: $margin-r * 1%;
  };

  @if $uncycle != 0 {
    &:nth-of-type(#{$uncycle}n) {
      margin-#{jeet-opposite-direction($side)}: $margin-r * 1%;
      float: $side;
    }
    &:nth-of-type(#{$uncycle}n + 1) {
      clear: none;
    }
  }

  @if $cycle != 0 {
    &:nth-of-type(#{$cycle}n) {
      margin-#{jeet-opposite-direction($side)}: $margin-last * 1%;
      float: jeet-opposite-direction($side);
    }
    &:nth-of-type(#{$cycle}n + 1) {
      clear: both;
    }
  } @else {
    &:last-child {
      margin-#{jeet-opposite-direction($side)}: $margin-last * 1%;
    }
  }
}

/**
 * An alias for the column mixin.
 * @param [$args...] - All arguments get passed through to column().
 */
@mixin col($args...) {
  @include column($args...);
}

/**
 * Get the width of a column and nothing else.
 * @param {number} [$ratios=1] - A width relative to its container as a fraction.
 * @param {number} [$gutter=$jeet-gutter] - Specify the gutter width as a percentage of the containers width.
 */
@function column-width($ratios: 1, $gutter: $jeet-gutter) {
  @return unquote(nth(jeet-get-column($ratios, $gutter), 1) + '%');
}

/**
 * Get the gutter size of a column and nothing else.
 * @param {number} [ratios=1] - A width relative to its container as a fraction.
 * @param {number} [gutter=jeet.gutter] - Specify the gutter width as a percentage of the containers width.
 */
@function column-gutter($ratios: 1, $gutter: $jeet-gutter) {
  @return unquote(nth(jeet-get-column($ratios, $gutter), 2) + '%');
}

/**
 * An alias for the column-width function.
 * @param [$args...] - All arguments get passed through to column().
 */
@function cw($args...) {
  @return column-width($args...);
}

/**
 * An alias for the column-gutter function.
 * @param [$args...] - All arguments get passed through to column().
 */
@function cg($args...) {
  @return column-gutter($args...);
}

/**
 * Style an element as a column without any gutters for a seamless row.
 * @param {number} [$ratios=1] - A width relative to its container as a fraction.
 * @param {number} [$offset=0] - A offset specified as a fraction (see $ratios).
 * @param {number} [cycle=0] - Easily create an nth column grid where cycle equals the number of columns.
 * @param {number} [uncycle=0] - Undo a previous cycle value to allow for a new one.
 */
@mixin span($ratio: 1, $offset: 0, $cycle: 0, $uncycle: 0) {
  $side: jeet-get-layout-direction();
  $opposite-side: jeet-opposite-direction($side);
  $span-width: jeet-get-span($ratio);
  $margin-r: 0;
  $margin-l: $margin-r;
  @if $offset != 0 {
    @if $offset < 0 {
      $offset: $offset * -1;
      $margin-r: jeet-get-span($offset);
    } @else {
      $margin-l: jeet-get-span($offset);
    }
  }

  @include cf;
  float: $side;
  clear: none;
  text-align: inherit;
  width: $span-width * 1%;
  margin: {
    #{$side}: $margin-l * 1%;
    #{$opposite-side}: $margin-r * 1%;
  };

  @if $cycle != 0 {
    &:nth-of-type(#{$cycle}n) {
      float: $opposite-side;
    }
    &:nth-of-type(#{$cycle}n + 1) {
      clear: both;
    }
  }

  @if $uncycle != 0 {
    &:nth-of-type(#{$uncycle}n) {
      float: $side;
    }
    &:nth-of-type(#{$uncycle}n + 1) {
      clear: none;
    }
  }

}

/**
 * Reorder columns without altering the HTML.
 * @param {number} [$ratios=0] - Specify how far along you want the element to move.
 * @param {string} [$col-or-span=column] - Specify whether the element has a gutter or not.
 * @param {number} [$gutter=$jeet-gutter] - Specify the gutter width as a percentage of the containers width.
 */
@mixin shift($ratios: 0, $col-or-span: column, $gutter: $jeet-gutter) {
  $translate: '';
  $side: jeet-get-layout-direction();

  @if $side == right {
    $ratios: jeet-replace-nth($ratios, 0, nth($ratios, 1) * -1);
  }

  @if index("column" "col" "c", $col-or-span) {
    $column-widths: jeet-get-column($ratios, $gutter);
    $translate: nth($column-widths, 1) + nth($column-widths, 2);
  } @else {
    $translate: jeet-get-span($ratios);
  }

  position: relative;
  left: $translate * 1%;
}

/**
 * Reset an element that has had shift() applied to it.
 */
@mixin unshift() {
  position: static;
  left: 0;
}

/**
 * View the grid and its layers for easy debugging.
 * @param {string} [$color=black] - The background tint applied.
 * @param {boolean} [$important=false] - Whether to apply the style as !important.
 */
@mixin edit($color: black, $important: false) {
  @if $important {
    * {
      background: rgba($color, .05) !important;
    }
  } @else {
    * {
      background: rgba($color, .05);
    }
  }
}

/**
 *  Alias for edit().
 */
@mixin debug() {
  @include edit;
}

/**
 * Horizontally center an element.
 * @param {number} [$max-width=1410px] - The max width the element can be.
 * @param {number} [$pad=0] - Specify the element's left and right padding.
 */
@mixin center($max-width: $jeet-max-width, $pad: 0) {
  @include cf;
  width: auto;
  max-width: $max-width;
  float: none;
  display: block;
  margin: {
    right: auto;
    left:  auto;
  };
  padding: {
    left:  $pad;
    right: $pad;
  };
}

/**
 * Uncenter an element.
 */
@mixin uncenter() {
  max-width: none;
  margin-right: 0;
  margin-left: 0;
  padding-left: 0;
  padding-right: 0;
}

/**
 * Stack an element so that nothing is either side of it.
 * @param {number} [$pad=0] - Specify the element's left and right padding.
 * @param {boolean/string} [$align=false] - Specify the text align for the element.
 */
@mixin stack($pad: 0, $align: false) {
  $side: jeet-get-layout-direction();
  $opposite-side: jeet-opposite-direction($side);

  display: block;
  clear: both;
  float: none;
  width: 100%;
  margin: {
    left:  auto;
    right: auto;
  };

  &:first-child {
    margin-#{$side}: auto;
  }

  &:last-child {
    margin-#{$opposite-side}: auto;
  }

  @if $pad != 0 {
    padding: {
      left:  $pad;
      right: $pad;
    }
  }

  @if ($align is not false) {
    @if index("center" "c", $align) {
      text-align: center;
    } @else if index("left" "l", $align) {
      text-align: left;
    } @else if index("right" "r", $align) {
      text-align: right;
    }
  }
}

/**
 * Unstack an element.
 */
@mixin unstack() {
  $side: jeet-get-layout-direction();
  $opposite-side: jeet-opposite-direction($side);

  text-align: $side;
  display: inline;
  clear: none;
  width: auto;
  margin: {
    left:  0;
    right: 0;
  };

  &:first-child {
    margin-#{$side}: 0;
  }

  &:last-child {
    margin-#{jeet-opposite-direction($side)}: 0;
  }
}

/**
 * Center an element on either or both axes.
 * @requires A parent container with relative positioning.
 * @param {string} [$direction=both] - Specify which axes to center the element on.
 */
@mixin align($direction: both) {
  position: absolute;
  transform-style: preserve-3d;

  @if index("horizontal" "h", $direction) {
    left: 50%;
    transform: translateX(-50%);
  } @else if index("vertical" "v", $direction) {
    top: 50%;
    transform: translateY(-50%);
  } @else {
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
}

/**
 * Apply a clearfix to an element.
 */
@mixin cf() {
  *zoom: 1;

  &:before, &:after {
    content: '';
    display: table;
  }

  &:after {
    clear: both;
  }
}
