@use '../variables' as var;

$-color-overlay: var.$color-overlay;
$-color-overlay--light: var.$color-overlay--light;

/**
 * Apply a margin to all sides (default) or designated `$side` in specified
 * `$size` (default: spacing-unit 5)
 *
 * @param {number} [$size] - spacing-unit 0-9, default 5
 * @param {'left'|'right'|'top'|'bottom'} [$side]
 */
@mixin margin($size: 5, $side: null) {
  @if ($side) {
    margin-#{$side}: var.space($size);
  } @else {
    margin: var.space($size);
  }
}

/**
 * Apply padding to all sides (default) or designated `$side` in specified
 * `$size` (default: spacing-unit 3)
 *
 * @param {number} [$size] - spacing-unit 0-9, default 3
 * @param {'left'|'right'|'top'|'bottom'} [$side]
 */
@mixin padding($size: 3, $side: null) {
  @if ($side) {
    padding-#{$side}: var.space($size);
  } @else {
    padding: var.space($size);
  }
}

/**
 * Abstract mixin for establishing basic flex container. External users should
 * use `row` or `column` as needed. Default values here reflect default CSS
 * values for flex rules.
 *
 * @param {string} $direction [row] - value for flex-direction (row or column).
 * @param {string} $justify [flex-start] - How to align contents on main axis.
 *                                    Accepts and maps special value of 'right'
 *                                   (roughly analogous to horizontal alignment)
 * @param {string} $align [stretch] - How to align contents on cross axis.
 *                                    (roughly analogous to vertical alignment)
 */
@mixin flex($direction: row, $justify: flex-start, $align: stretch) {
  display: flex;
  flex-direction: $direction;

  @if $justify == right {
    justify-content: flex-end;
  } @else {
    justify-content: $justify;
  }
  align-items: $align;
}

/**
 * Establish a column (flex-direction: column) flex container.
 *
 * @param {string} $justify [flex-start] - How to justify flex contents
 * @param {string} $align [stretch] - How to align flex contents
 */
@mixin column($justify: flex-start, $align: stretch) {
  @include flex(column, $justify, $align);
}

/**
 * Establish a row (flex-direction: column) flex container.
 *
 * @param {string} $justify [flex-start] - How to justify flex contents
 * @param {string} $align [stretch] - How to align flex contents
 */
@mixin row($justify: flex-start, $align: stretch) {
  @include flex(row, $justify, $align);
}

/**
 * Put `$size` of vertical space between all immediate children.
 *
 * @param {length} [$size] - Relative size of spacing, 0 - 9. Default 5
 */
@mixin vertical-spacing($size: 5) {
  & > :not(:first-child) {
    margin-top: var.space($size);
  }

  & > :first-child {
    margin-top: 0;
  }

  & > :last-child {
    margin-bottom: 0;
  }
}

/**
 * Put `$size` of horizontal space between all immediate children.
 *
 * @param {length} [$size] - Relative size of spacing, 0 - 9. Default 3
 */
@mixin horizontal-spacing($size: 3) {
  & > :not(:first-child) {
    margin-left: var.space($size);
  }

  & > :first-child {
    margin-left: 0;
  }

  & > :last-child {
    margin-right: 0;
  }
}

/**
 * Position an element vertically and horizontally within the viewport
 */
@mixin fixed-centered {
  z-index: 20;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/**
 * Position an element, absolutely, vertically and horizontally
 */
@mixin absolute-centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/**
 * Semi-opaque overlay, full-viewport
 */
@mixin overlay($variant: 'dark') {
  $-background: $-color-overlay;
  @if ($variant == 'light') {
    $-background: $-color-overlay--light;
  }
  z-index: 10;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: $-background;
}
