// Copyright 2015 Palantir Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0.

@import "../../common/mixins";
@import "../../common/variables";
@import "../button/common";

$control-background-color: $button-background-color !default;
$control-background-color-hover: $button-background-color-hover !default;
$control-background-color-active: $button-background-color-active !default;
$dark-control-background-color: $dark-button-background-color !default;
$dark-control-background-color-hover: $dark-button-background-color-hover !default;
$dark-control-background-color-active: $dark-button-background-color-active !default;

$control-checked-background-color: nth(map-get($button-intents, "primary"), 1) !default;
$control-checked-background-color-hover: nth(map-get($button-intents, "primary"), 2) !default;
$control-checked-background-color-active: nth(map-get($button-intents, "primary"), 3) !default;

$control-indicator-size: $pt-icon-size-standard !default;
$control-indicator-size-large: $pt-icon-size-large !default;
$control-indicator-spacing: $pt-grid-size !default;

@mixin control-checked-colors($selector: ":checked") {
  input#{$selector} ~ .#{$ns}-control-indicator {
    box-shadow: $button-intent-box-shadow;
    background-color: $control-checked-background-color;
    background-image: $button-intent-gradient;
    color: $white;
  }

  &:hover input#{$selector} ~ .#{$ns}-control-indicator {
    box-shadow: $button-intent-box-shadow;
    background-color: $control-checked-background-color-hover;
  }

  input:not(:disabled):active#{$selector} ~ .#{$ns}-control-indicator {
    box-shadow: $button-intent-box-shadow-active;
    background: $control-checked-background-color-active;
  }

  input:disabled#{$selector} ~ .#{$ns}-control-indicator {
    box-shadow: none;
    background: rgba($control-checked-background-color, 0.5);
  }

  .#{$ns}-dark & {
    input#{$selector} ~ .#{$ns}-control-indicator {
      box-shadow: $dark-button-intent-box-shadow;
    }

    &:hover input#{$selector} ~ .#{$ns}-control-indicator {
      box-shadow: $dark-button-intent-box-shadow;
      background-color: $control-checked-background-color-hover;
    }

    input:not(:disabled):active#{$selector} ~ .#{$ns}-control-indicator {
      box-shadow: $dark-button-intent-box-shadow-active;
      background-color: $control-checked-background-color-active;
    }

    input:disabled#{$selector} ~ .#{$ns}-control-indicator {
      box-shadow: none;
      background: rgba($control-checked-background-color-active, 0.5);
    }
  }
}

@mixin indicator-position($size) {
  $padding: $size + $control-indicator-spacing;

  &:not(.#{$ns}-align-right) {
    padding-left: $padding;

    .#{$ns}-control-indicator {
      margin-left: -$padding;
    }
  }

  &.#{$ns}-align-right {
    padding-right: $padding;

    .#{$ns}-control-indicator {
      margin-right: -$padding;
    }
  }
}

.#{$ns}-control {
  @include control-checked-colors();
  @include indicator-position($control-indicator-size);

  display: block;
  position: relative;
  margin-bottom: $pt-grid-size;
  cursor: pointer;
  text-transform: none;

  &.#{$ns}-disabled {
    cursor: not-allowed;
    color: $pt-text-color-disabled;
  }

  &.#{$ns}-inline {
    display: inline-block;
    margin-right: $pt-grid-size * 2;
  }

  input {
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0;
    z-index: -1; // don't let it intercept clicks
  }

  .#{$ns}-control-indicator {
    display: inline-block;
    position: relative;
    margin-top: -3px;
    margin-right: $control-indicator-spacing;
    border: none;
    box-shadow: $button-box-shadow;
    background-clip: padding-box;
    background-color: $control-background-color;
    background-image: $button-gradient;
    cursor: pointer;
    width: 1em;
    height: 1em;
    vertical-align: middle;
    // font-size is used to size indicator for all control types,
    // to reduce property changes needed across types and sizes (large).
    font-size: $control-indicator-size;
    user-select: none;

    &::before {
      display: block;
      width: 1em;
      height: 1em;
      content: "";
    }
  }

  &:hover .#{$ns}-control-indicator {
    background-color: $control-background-color-hover;
  }

  input:not(:disabled):active ~ .#{$ns}-control-indicator {
    box-shadow: $button-box-shadow-active;
    background: $control-background-color-active;
  }

  input:disabled ~ .#{$ns}-control-indicator {
    box-shadow: none;
    background: $button-background-color-disabled;
    cursor: not-allowed;
  }

  input:focus ~ .#{$ns}-control-indicator {
    @include focus-outline();
  }

  // right-aligned indicator is glued to the right side of the container
  &.#{$ns}-align-right .#{$ns}-control-indicator {
    float: right;
    margin-top: 1px;
    margin-left: $control-indicator-spacing;
  }

  &.#{$ns}-large {
    @include indicator-position($control-indicator-size-large);
    // larger text
    font-size: $pt-font-size-large;

    .#{$ns}-control-indicator {
      // em-based sizing
      font-size: $control-indicator-size-large;
    }

    &.#{$ns}-align-right .#{$ns}-control-indicator {
      margin-top: 0;
    }
  }

  /*
  Checkbox

  Markup:
  <label class="#{$ns}-control #{$ns}-checkbox {{.modifier}}">
    <input type="checkbox" {{:modifier}} />
    <span class="#{$ns}-control-indicator"></span>
    Checkbox
  </label>

  :checked  - Checked
  :disabled - Disabled. Also add <code>.#{$ns}-disabled</code> to <code>.#{$ns}-control</code> to change text color (not shown below).
  :indeterminate - Indeterminate. Note that this style can only be achieved via JavaScript
                   <code>input.indeterminate = true</code>.
  .#{$ns}-align-right - Right-aligned indicator
  .#{$ns}-large - Large

  Styleguide checkbox
  */

  &.#{$ns}-checkbox {
    @mixin indicator-inline-icon($icon) {
      &::before {
        // embed SVG icon image as backgroud-image above gradient.
        // the SVG image content is inlined into the CSS, so use this sparingly.
        background-image: svg-icon("16px/#{$icon}.svg", (path: (fill: $white)));
      }
    }

    // make :indeterminate look like :checked _for Checkbox only_
    @include control-checked-colors(":indeterminate");

    .#{$ns}-control-indicator {
      border-radius: $pt-border-radius;
    }

    input:checked ~ .#{$ns}-control-indicator {
      @include indicator-inline-icon("small-tick");
    }

    input:indeterminate ~ .#{$ns}-control-indicator {
      @include indicator-inline-icon("small-minus");
    }
  }

  /*
  Radio

  Markup:
  <label class="#{$ns}-control #{$ns}-radio {{.modifier}}">
    <input type="radio" name="docs-radio-regular" {{:modifier}} />
    <span class="#{$ns}-control-indicator"></span>
    Radio
  </label>

  :checked  - Selected
  :disabled - Disabled. Also add <code>.#{$ns}-disabled</code> to <code>.#{$ns}-control</code> to change text color (not shown below).
  .#{$ns}-align-right - Right-aligned indicator
  .#{$ns}-large - Large

  Styleguide radio
  */

  &.#{$ns}-radio {
    .#{$ns}-control-indicator {
      border-radius: 50%;
    }

    input:checked ~ .#{$ns}-control-indicator::before {
      background-image: radial-gradient($white, $white 28%, transparent 32%);
    }

    input:checked:disabled ~ .#{$ns}-control-indicator::before {
      opacity: 0.5;
    }

    input:focus ~ .#{$ns}-control-indicator {
      -moz-outline-radius: $control-indicator-size;
    }
  }

  /*
  Switch

  Markup:
  <label class="#{$ns}-control #{$ns}-switch {{.modifier}}">
    <input type="checkbox" {{:modifier}} />
    <span class="#{$ns}-control-indicator"></span>
    Switch
  </label>

  :checked  - Selected
  :disabled - Disabled. Also add <code>.#{$ns}-disabled</code> to <code>.#{$ns}-control</code> to change text color (not shown below).
  .#{$ns}-align-right - Right-aligned indicator
  .#{$ns}-large - Large

  Styleguide switch
  */

  // stylelint-disable-next-line order/order
  $switch-width: 1.75em !default;
  $switch-indicator-margin: 2px !default;
  $switch-indicator-size: calc(1em - #{$switch-indicator-margin * 2});

  $switch-indicator-child-height: 1em;
  $switch-indicator-child-outside-margin: 0.5em;
  $switch-indicator-child-inside-margin: 1.2em;

  $switch-indicator-text-font-size: 0.7em;

  $switch-background-color: rgba($gray4, 0.5) !default;
  $switch-background-color-hover: rgba($gray2, 0.5) !default;
  $switch-background-color-active: rgba($gray1, 0.5) !default;
  $switch-background-color-disabled: $button-background-color-disabled !default;
  $switch-checked-background-color: $control-checked-background-color !default;
  $switch-checked-background-color-hover: $control-checked-background-color-hover !default;
  $switch-checked-background-color-active: $control-checked-background-color-active !default;
  $switch-checked-background-color-disabled: rgba($blue3, 0.5) !default;

  $dark-switch-background-color: rgba($black, 0.5) !default;
  $dark-switch-background-color-hover: rgba($black, 0.7) !default;
  $dark-switch-background-color-active: rgba($black, 0.9) !default;
  $dark-switch-background-color-disabled: $dark-button-background-color-disabled !default;
  $dark-switch-checked-background-color: $control-checked-background-color !default;
  $dark-switch-checked-background-color-hover: $control-checked-background-color-hover !default;
  $dark-switch-checked-background-color-active: $control-checked-background-color-active !default;
  $dark-switch-checked-background-color-disabled: rgba($blue1, 0.5) !default;

  $switch-indicator-background-color: $white !default;
  $switch-indicator-background-color-disabled: rgba($white, 0.8) !default;
  $dark-switch-indicator-background-color: $dark-gray5 !default;
  $dark-switch-indicator-background-color-disabled: rgba($black, 0.4) !default;

  &.#{$ns}-switch {
    @mixin indicator-colors(
      $selector,
      $color,
      $hover-color,
      $active-color,
      $disabled-color,
      $disabled-indicator-color
    ) {
      input#{$selector} ~ .#{$ns}-control-indicator {
        background: $color;
      }

      &:hover input#{$selector} ~ .#{$ns}-control-indicator {
        background: $hover-color;
      }

      input#{$selector}:not(:disabled):active ~ .#{$ns}-control-indicator {
        background: $active-color;
      }

      input#{$selector}:disabled ~ .#{$ns}-control-indicator {
        background: $disabled-color;

        &::before {
          background: $disabled-indicator-color;
        }
      }
    }

    @include indicator-colors(
      "",
      $switch-background-color,
      $switch-background-color-hover,
      $switch-background-color-active,
      $switch-background-color-disabled,
      $switch-indicator-background-color-disabled
    );
    @include indicator-colors(
      ":checked",
      $switch-checked-background-color,
      $switch-checked-background-color-hover,
      $switch-checked-background-color-active,
      $switch-checked-background-color-disabled,
      $switch-indicator-background-color-disabled
    );
    // convert em variable to px value
    @include indicator-position($switch-width / 1em * $control-indicator-size);

    .#{$ns}-control-indicator {
      border: none;
      border-radius: $switch-width;
      // override default button styles, never have a box-shadow here.
      // stylelint-disable-next-line declaration-no-important
      box-shadow: none !important;
      width: auto;
      min-width: $switch-width;
      transition: background-color $pt-transition-duration $pt-transition-ease;

      &::before {
        position: absolute;
        left: 0;
        margin: $switch-indicator-margin;
        border-radius: 50%;
        box-shadow: $button-box-shadow-overlay;
        background: $switch-indicator-background-color;
        width: $switch-indicator-size;
        height: $switch-indicator-size;
        transition: left $pt-transition-duration $pt-transition-ease;
      }
    }

    input:checked ~ .#{$ns}-control-indicator::before {
      // 1em is size of indicator
      left: calc(100% - 1em);
    }

    &.#{$ns}-large {
      @include indicator-position($switch-width / 1em * $control-indicator-size-large);
    }

    .#{$ns}-dark & {
      @include indicator-colors(
        "",
        $dark-switch-background-color,
        $dark-switch-background-color-hover,
        $dark-switch-background-color-active,
        $dark-switch-background-color-disabled,
        $dark-switch-indicator-background-color-disabled
      );
      @include indicator-colors(
        ":checked",
        $dark-switch-checked-background-color,
        $dark-switch-checked-background-color-hover,
        $dark-switch-checked-background-color-active,
        $dark-switch-checked-background-color-disabled,
        $dark-switch-indicator-background-color-disabled
      );

      .#{$ns}-control-indicator::before {
        box-shadow: $dark-button-box-shadow;
        background: $dark-switch-indicator-background-color;
      }

      input:checked ~ .#{$ns}-control-indicator::before {
        // inset shadow so it forms a dark line instead of blurring into the blue
        box-shadow: inset $dark-button-box-shadow;
      }
    }

    .#{$ns}-switch-inner-text {
      text-align: center;
      font-size: $switch-indicator-text-font-size;
    }

    .#{$ns}-control-indicator-child {
      &:first-child {
        visibility: hidden;
        margin-right: $switch-indicator-child-inside-margin;
        margin-left: $switch-indicator-child-outside-margin;
        line-height: 0;
      }

      &:last-child {
        visibility: visible;
        margin-right: $switch-indicator-child-outside-margin;
        margin-left: $switch-indicator-child-inside-margin;
        line-height: $switch-indicator-child-height;
      }
    }

    input:checked ~ .#{$ns}-control-indicator .#{$ns}-control-indicator-child {
      &:first-child {
        visibility: visible;
        line-height: $switch-indicator-child-height;
      }

      &:last-child {
        visibility: hidden;
        line-height: 0;
      }
    }
  }

  .#{$ns}-dark & {
    color: $pt-dark-text-color;

    &.#{$ns}-disabled {
      color: $pt-dark-text-color-disabled;
    }

    .#{$ns}-control-indicator {
      box-shadow: $dark-button-box-shadow;
      background-color: $dark-control-background-color;
      background-image: $dark-button-gradient;
    }

    &:hover .#{$ns}-control-indicator {
      background-color: $dark-control-background-color-hover;
    }

    input:not(:disabled):active ~ .#{$ns}-control-indicator {
      box-shadow: $dark-button-box-shadow-active;
      background: $dark-control-background-color-active;
    }

    input:disabled ~ .#{$ns}-control-indicator {
      box-shadow: none;
      background: $dark-button-background-color-disabled;
      cursor: not-allowed;
    }

    &.#{$ns}-checkbox input:disabled {
      &:checked,
      &:indeterminate {
        ~ .#{$ns}-control-indicator {
          color: $dark-button-color-disabled;
        }
      }
    }
  }

  /*
  Inline labels

  Markup:
  <div>
    <label class="#{$ns}-label">A group of related options</label>
    <label class="#{$ns}-control #{$ns}-checkbox #{$ns}-inline">
      <input type="checkbox" />
      <span class="#{$ns}-control-indicator"></span>
      First
    </label>
    <label class="#{$ns}-control #{$ns}-checkbox #{$ns}-inline">
      <input type="checkbox" />
      <span class="#{$ns}-control-indicator"></span>
      Second
    </label>
    <label class="#{$ns}-control #{$ns}-checkbox #{$ns}-inline">
      <input type="checkbox" />
      <span class="#{$ns}-control-indicator"></span>
      Third
    </label>
  </div>

  Styleguide checkbox-inline
  */
}
