/// 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.
/// @param {Number} $cycle [0] - Easily create an nth column grid where $cycle equals the number of columns.
/// @param {Number} $gutter [$jeet-gutter] - Specify the gutter width as a percentage of the containers width.
@mixin j-column($ratios: 1, $offset: 0, $cycle: 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);
    }
  }

  float: $side;
  clear: none;
  width: jeet-get-percentage(nth($column-widths, 1));

  margin: {
    #{$side}: jeet-get-percentage($margin-l);
    #{$opposite-side}: jeet-get-percentage($margin-r);
  };

  @if $cycle != 0 {
    &:nth-of-type(n) {
      margin-#{jeet-opposite-direction($side)}: jeet-get-percentage($margin-r);
      float: $side;
      clear: none;
    }

    &:nth-of-type(#{$cycle}n) {
      margin-#{jeet-opposite-direction($side)}: jeet-get-percentage($margin-last);
      float: jeet-opposite-direction($side);
    }

    &:nth-of-type(#{$cycle}n + 1) {
      clear: both;
    }
  } @else {
    &:last-child {
      margin-#{jeet-opposite-direction($side)}: jeet-get-percentage($margin-last);
    }
  }
}

/// Get the width of a column and nothing else.
/// @access private
/// @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 j-column-width($ratios: 1, $gutter: $jeet-gutter) {
  @return jeet-get-percentage(nth(jeet-get-column($ratios, $gutter), 1));
}

/// Get the gutter size of a column and nothing else.
/// @access private
/// @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 j-column-gutter($ratios: 1, $gutter: $jeet-gutter) {
  @return jeet-get-percentage(nth(jeet-get-column($ratios, $gutter), 2));
}

/// 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.
/// @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 j-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);
    }
  }

  float: $side;
  clear: none;
  width: jeet-get-percentage($span-width);

  margin: {
    #{$side}: jeet-get-percentage($margin-l);
    #{$opposite-side}: jeet-get-percentage($margin-r);
  };

  @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 j-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: jeet-get-percentage($translate);
}

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

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

/// 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 j-center($max-width: $jeet-max-width, $pad: 0) {
  width: auto;
  max-width: $max-width;
  float: none;
  display: block;

  margin: {
    right: auto;
    left: auto;
  };

  padding: {
    left: $pad;
    right: $pad;
  };
}

/// Uncenter an element.
@mixin j-uncenter() {
  max-width: none;

  margin: {
    right: 0;
    left: 0;
  };

  padding: {
    left: 0;
    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 {Bool | String} $align [false] - Specify the text align for the element.
@mixin j-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 j-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 element with relative positioning.
/// @param {String} $direction [both] - Specify which axes to center the element on.
@mixin j-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 if index("none", $direction) {
    top: auto;
    left: auto;
    transform: translate(0, 0);
  } @else {
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
}

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

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

  &:after {
    clear: both;
  }
}
