@import "../settings.colors";
@import "../settings.button-colors";

@import "tools.functions";
@import "tools.mixins";

// --------------------------------------------------
// Base
// --------------------------------------------------

@mixin c-button {
  @include remove-button-appearance;
  @include font-gm-sans-bold;
  @include font-rendering-fix;
  @include c-button--visible;
  @include c-button--regular;
  @include c-button--regular-icon;
  min-width: rem(44);
  padding-top: rem(9);
  padding-bottom: rem(9);
  border: 1px solid;
  border-radius: rem(2);
  line-height: 1;
  letter-spacing: rem(1);
  vertical-align: middle;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  &,
  .c-button__icon {
    transition-property: background-color, color, fill, opacity;
    transition-duration: 0.25s;
    transition-timing-function: ease-out;
  }
  &:active,
  &:active .c-button__icon {
    transition: none;
  }
  .c-button__icon {
    margin-right: rem(5);
  }
  .c-button__icon,
  .c-button__text {
    vertical-align: middle;
    display: inline-block;
  }
  @supports (display: inline-flex) {
    align-items: center;
    justify-content: center;
    .c-button__icon {
      margin-right: rem(9);
    }
  }
  @include c-button-theme("white-primary"); // Default colour theme
}

// --------------------------------------------------
// Colours
// --------------------------------------------------

// Generates selectors for a single button type
// These styles should be included inside a .c-button{} selector block

@mixin c-button-theme($bg, $text: $color-grey-660, $transform: null) {
  $bg-base: $bg;
  $bg-default: null;
  $bg-default-override: null;
  $bg-hover: null;
  $bg-active: null;
  $bg-disabled: $color-white;

  $text-base: $text;
  $text-default: null;
  $text-hover: null;
  $text-active: null;
  $text-disabled: $color-stone-500;

  $border: $color-stone-500;

  // In cases where we want the button to appear white by default then become
  // some other colour on hover, we're unable to use white as the base colour
  // because darkening white results in a grey/black colour, which may not be
  // what we want. So, we must use a lighter tint of the desired hover colour
  // as the base, then override the default background colour later (see below).
  @if (type-of($bg-base) == string and str-index($bg-base, "white-primary") == 1) {
    $bg-default-override: $color-white;
  }

  // If the background colour is provided as a string instead of a colour,
  // attempt to retrieve the matching colour from the $c-button-colors map
  @if (type-of($bg-base) == string) {
    $col: map-get($c-button-colors, $bg-base);
    @if ($col) {
      $bg-base: $col;
    }
  }

  // Background colours for hover and active states
  @if ($transform == "opacity") {
    $bg-default: rgba($bg-base, 0.15);
    $bg-hover: rgba($bg-base, 0.25);
    $bg-active: rgba($bg-base, 0.35);
  } @else {
    $bg-default: $bg-base;
    $bg-hover: darken($bg-base, 8%);
    $bg-active: darken($bg-base, 16%);
  }

  // Text colours for hover and active states
  @if ($transform == "opacity") {
    $text-default: $color-white;
    $text-hover: $color-white;
    $text-active: $color-white;
  } @else {
    // Decide whether the text should be light or dark
    @if ($text-base == $color-grey-660 and contrast($bg-base, $text-base) < 4.5) {
      // If the default text colour is being used (i.e. a custom value has not
      // been provided) and it does not have sufficient contrast when placed
      // over top of the given background colour, force the text to be white
      $text-default: $color-white;
      $text-hover: rgba($text-default, 0.75);
      $text-active: rgba($text-default, 0.45);
    } @else {
      $text-default: $text-base;
      $text-hover: darken($text-default, 15%);
      $text-active: darken($text-default, 25%);
    }
    // Warn developers when colour contrast is insufficient
    $contrast: contrast($bg-base, $text-default);
    @if ($contrast < 4.5) { // WCAG-2.0 Level AA
      @warn "Insufficient button colour contrast (bg: #{$bg-base} text: #{$text-default}): #{$contrast} ❌";
    }
  }

  // Button styles
  @if ($bg-default-override) {
    background-color: $bg-default-override;
  } @else {
    background-color: $bg-default;
  }
  color: $text-default;
  border-color: $border;
  .c-button__icon {
    fill: $text-default;
  }
  &:hover,
  &:focus {
    background-color: $bg-hover;
    color: $text-hover;
    border-color: $border;
    .c-button__icon {
      fill: $text-hover;
    }
  }
  &:active {
    background-color: $bg-active;
    color: $text-active;
    border-color: $border;
    .c-button__icon {
      fill: $text-active;
    }
  }
  &[disabled], // for anchors
  &:disabled {
    background-color: $bg-disabled;
    color: $text-disabled;
    border-color: $border;
    .c-button__icon {
      fill: $text-disabled;
    }
  }
}

// Dynamically-generated mixin names are not yet supported in SASS:
// https://stackoverflow.com/questions/15748937/how-to-define-a-dynamic-mixin-or-function-name-in-sass
//
// @each $color-name, $color in $c-button-colors {
//   @mixin c-button--#{$color-name} {
//     @include c-button-theme($color-name);
//   }
// }

// --------------
// Custom themes
// --------------

// White buttons with custom text colours

@mixin c-button-theme--white-primary-red-text {
  @include c-button-theme("white-primary", $text: $color-red-600);
}

// Transparent buttons

@mixin c-button-theme--semi-transparent-lighten {
  @include c-button-theme($color-white, $transform: "opacity");
}

@mixin c-button-theme--semi-transparent-darken {
  @include c-button-theme(#000, $transform: "opacity");
}

@mixin c-button-theme--transparent-lighten {
  @include c-button-theme($color-white, $transform: "opacity");
  background-color: transparent;
}

@mixin c-button-theme--transparent-darken {
  @include c-button-theme(#000, $transform: "opacity");
  background-color: transparent;
}

// --------------------------------------------------
// Display options
// --------------------------------------------------

// Use this mixin when buttons are hidden then need to be revealed again,
// because it isn't safe to assume that "display: inline-flex" is supported

@mixin c-button--visible {
  display: inline-block;
  @supports (display: inline-flex) {
    display: inline-flex;
  }
}

@mixin c-button--regular {
  min-height: rem(44);
  padding-left: rem(20);
  padding-right: rem(20);
  font-size: rem(14);
}

@mixin c-button--regular-icon {
  .c-button__icon {
    min-width: rem(18);
    width: rem(18);
    height: rem(18);
  }
}

@mixin c-button--badge {
  padding: rem(6);
  border-radius: rem(4);
  text-align: left;
  .c-button__icon {
    min-width: rem(32);
    width: rem(32);
    height: rem(32);
  }
  .c-button__text {
    font-size: rem(12);
    line-height: line-height(12, 15);
  }
  .c-button__primary-text {
    display: block;
  }
  .c-button__secondary-text {
    @include font-gm-sans;
  }
}

@mixin c-button--icon-only {
  padding-left: rem(9);
  padding-right: rem(9);
  .c-button__icon {
    margin-right: 0;
  }
}

@mixin c-button--no-border {
  border: none;
}

@mixin c-button--no-border-radius {
  border-radius: 0;
}

@mixin c-button--full-width {
  width: 100%;
}

@mixin c-button--truncated($max-width) {
  .c-button__text {
    width: 100%;
    max-width: $max-width;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

@mixin c-button--small {
  min-height: rem(34);
  padding-left: rem(10);
  padding-right: rem(10);
  font-size: rem(12);
}

@mixin c-button--small-icon {
  .c-button__icon {
    min-width: rem(14);
    width: rem(14);
    height: rem(14);
  }
}
