// Copyright 2015 Palantir Technologies, Inc. All rights reserved.
// Licensed under the BSD-3 License as modified (the “License”); you may obtain a copy
// of the license at https://github.com/palantir/blueprint/blob/master/LICENSE
// and https://github.com/palantir/blueprint/blob/master/PATENTS

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

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

$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;

.pt-control {
  display: block;
  position: relative;
  margin-bottom: $pt-grid-size;
  cursor: pointer;
  // controls sometimes don't have text in their <label>, so we set a minimum height
  min-height: $control-indicator-size;
  padding-left: $control-indicator-size + $pt-grid-size;
  text-transform: none;
  line-height: $control-indicator-size;

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

  &.pt-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
  }

  .pt-control-indicator {
    @include pt-icon($pt-icon-size-standard);
    position: absolute;
    top: 0;
    left: 0;
    margin: 0;
    border: none;
    box-shadow: $button-box-shadow;
    background-clip: padding-box;
    background-color: $control-background-color;
    background-image: $button-gradient;
    cursor: pointer;
    width: $control-indicator-size;
    height: $control-indicator-size;
    line-height: $control-indicator-size;
    user-select: none;

    &::before {
      position: relative;
      content: "";
    }
  }

  input:checked ~ .pt-control-indicator {
    box-shadow: $button-intent-box-shadow;
    background-color: $control-checked-background-color;
    background-image: $button-intent-gradient;
    color: $white;
  }

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

    input:checked ~ .pt-control-indicator {
      box-shadow: $button-intent-box-shadow;
      background-color: $control-checked-background-color-hover;
    }
  }

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

    &:checked ~ .pt-control-indicator {
      box-shadow: $button-intent-box-shadow-active;
      background: $control-checked-background-color-active;
    }
  }

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

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

    &:checked ~ .pt-control-indicator {
      box-shadow: none;
      background: rgba($control-checked-background-color, 0.5);
    }
  }

  /*
  Checkbox

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

  :checked  - Checked
  :disabled - Disabled. Also add <code>.pt-disabled</code> to <code>.pt-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>.
  .pt-align-right - Right-aligned indicator
  .pt-large - Large

  Styleguide pt-checkbox
  */

  &.pt-checkbox {
    .pt-control-indicator {
      border-radius: $pt-border-radius;
      font-size: $control-indicator-size;
    }

    input:indeterminate,
    &:hover input:indeterminate {
      // :indeterminate should behave like :checked with different icon
      // stylelint-disable-next-line scss/at-extend-no-missing-placeholder
      @extend input:checked;
    }

    input:checked ~ .pt-control-indicator::before {
      content: $pt-icon-small-tick;
    }

    input:indeterminate ~ .pt-control-indicator::before {
      content: $pt-icon-small-minus;
    }
  }

  /*
  Radio

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

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

  Styleguide pt-radio
  */

  // stylelint-disable-next-line order/declaration-block-order
  $radio-indicator-font-size: $pt-grid-size * 0.6 !default;
  $radio-indicator-font-size-large: $pt-grid-size * 0.8 !default;

  &.pt-radio {
    .pt-control-indicator {
      border-radius: 50%;
      font-size: $radio-indicator-font-size;
    }

    input:checked ~ .pt-control-indicator::before {
      display: inline-block;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      background: $white;
      width: 1em;
      height: 1em;
      content: "";
    }

    input:checked:disabled ~ .pt-control-indicator::before {
      box-shadow: none;
    }

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

  /*
  Switch

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

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

  Styleguide pt-switch
  */

  // stylelint-disable-next-line order/declaration-block-order
  $switch-height: $control-indicator-size !default;
  $switch-height-large: $pt-grid-size * 2 !default;
  $switch-width: $pt-grid-size * 2.8 !default;
  $switch-width-large: $pt-grid-size * 3.2 !default;
  $switch-indicator-margin: $pt-grid-size * 0.2 !default;

  $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: $blue4 !default;
  $dark-switch-checked-background-color-active: $blue5 !default;
  $dark-switch-checked-background-color-disabled: rgba($blue1, 0.5) !default;

  $switch-indicator-border: border-shadow($pt-border-shadow-opacity) !default;
  $switch-indicator-background-color: $white !default;
  $switch-indicator-background-color-disabled: rgba($white, 0.8) !default;
  $dark-switch-indicator-border: border-shadow($pt-dark-border-shadow-opacity) !default;
  $dark-switch-indicator-background-color: $dark-gray4 !default;
  $dark-switch-indicator-background-color-disabled: rgba($black, 0.4) !default;

  &.pt-switch {
    padding-left: $switch-width + $pt-grid-size;

    .pt-control-indicator {
      border: none;
      border-radius: $switch-width;
      box-shadow: none;
      background: $switch-background-color;
      width: $switch-width;
      height: $switch-height;
      transition: background $pt-transition-duration $pt-transition-ease;

      &::before {
        display: block;
        top: $switch-indicator-margin;
        left: $switch-indicator-margin;
        border-radius: $switch-height;
        box-shadow: $button-box-shadow-overlay;
        background: $switch-indicator-background-color;
        background-clip: padding-box;
        width: $switch-height - ($switch-indicator-margin * 2);
        height: $switch-height - ($switch-indicator-margin * 2);
        content: "";
        transition: left $pt-transition-duration $pt-transition-ease;
      }
    }

    input:checked ~ .pt-control-indicator {
      box-shadow: none;
      background-color: $switch-checked-background-color;
      width: $switch-width;
      height: $switch-height;

      &::before {
        left: $switch-width - $switch-height + $switch-indicator-margin;
        box-shadow: $button-box-shadow-overlay;
      }
    }

    &:hover {
      .pt-control-indicator {
        background-color: $switch-background-color-hover;
      }

      input:checked ~ .pt-control-indicator {
        background-color: $switch-checked-background-color-hover;
      }
    }

    input:not(:disabled):active {
      ~ .pt-control-indicator {
        box-shadow: none;
        background-color: $switch-background-color-active;
      }

      &:checked ~ .pt-control-indicator {
        background-color: $control-checked-background-color-active;

        &::before {
          box-shadow: $button-box-shadow-overlay;
        }
      }
    }

    input:disabled {
      ~ .pt-control-indicator {
        background-color: $switch-background-color-disabled;

        &::before {
          box-shadow: none;
          background-color: $switch-indicator-background-color-disabled;
        }
      }

      &:checked ~ .pt-control-indicator {
        background-color: $switch-checked-background-color-disabled;
      }
    }
  }

  // right-aligned indicator is glued to the right side of the container
  &.pt-align-right {
    padding-right: $control-indicator-size + $pt-grid-size;
    padding-left: 0;

    .pt-control-indicator {
      right: 0;
      left: auto;
    }
  }

  &.pt-large {
    min-height: $control-indicator-size-large;
    padding-left: $control-indicator-size-large + $pt-grid-size;
    line-height: $control-indicator-size-large;
    font-size: $pt-font-size-large;

    .pt-control-indicator {
      width: $control-indicator-size-large;
      height: $control-indicator-size-large;
      line-height: $control-indicator-size-large;
      font-family: $icons20-family;
      font-size: $control-indicator-size-large;
    }

    &.pt-checkbox input:checked ~ .pt-control-indicator::before {
      top: 1px;
    }

    &.pt-radio .pt-control-indicator {
      font-size: $radio-indicator-font-size-large;
    }

    &.pt-switch {
      padding-left: $switch-width-large + $pt-grid-size;

      .pt-control-indicator {
        width: $switch-width-large;
        height: $switch-height-large;

        &::before {
          width: $switch-height-large - ($switch-indicator-margin * 2);
          height: $switch-height-large - ($switch-indicator-margin * 2);
        }
      }

      input:checked ~ .pt-control-indicator {
        width: $switch-width-large;
        height: $switch-height-large;

        &::before {
          left: $switch-width-large - $switch-height-large + $switch-indicator-margin;
        }
      }
    }
  }

  .pt-dark & {
    color: $pt-dark-text-color;

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

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

    input:checked ~ .pt-control-indicator {
      box-shadow: $dark-button-intent-box-shadow;
    }

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

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

      &:checked ~ .pt-control-indicator {
        box-shadow: $dark-button-intent-box-shadow-active;
        background-color: $control-checked-background-color-active;
      }
    }

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

      &:checked ~ .pt-control-indicator {
        box-shadow: none;
        background: rgba($control-checked-background-color-active, 0.5);
      }
    }

    &.pt-checkbox {
      input:checked {
        &:disabled ~ .pt-control-indicator::before {
          color: $dark-button-color-disabled;
        }
      }
    }

    &.pt-radio {
      input:checked:disabled ~ .pt-control-indicator::before {
        background: $dark-button-color-disabled;
      }
    }

    &.pt-switch {
      .pt-control-indicator {
        box-shadow: none;
        background: $dark-switch-background-color;

        &::before {
          box-shadow: $dark-button-box-shadow;
          background: $dark-switch-indicator-background-color;
        }
      }

      input:checked ~ .pt-control-indicator {
        box-shadow: none;
        background-color: $dark-switch-checked-background-color;

        &::before {
          box-shadow: inset $dark-button-box-shadow;
        }
      }

      &:hover {
        .pt-control-indicator {
          background: $dark-switch-background-color-hover;
        }

        input:checked ~ .pt-control-indicator {
          background: $dark-switch-checked-background-color-hover;
        }
      }

      input:not(:disabled):active {
        ~ .pt-control-indicator {
          box-shadow: none;
          background: $dark-switch-background-color-active;

          // we're in too deep to quit
          // stylelint-disable max-nesting-depth
          &::before {
            box-shadow: $dark-button-box-shadow;
          }
        }

        &:checked ~ .pt-control-indicator {
          background: $dark-switch-checked-background-color-active;

          &::before {
            box-shadow: inset $dark-button-box-shadow;
          }
        }
      }

      input:disabled {
        ~ .pt-control-indicator {
          background: $dark-switch-background-color-disabled;

          &::before {
            box-shadow: none;
            background: $dark-switch-indicator-background-color-disabled;
          }
          // stylelint-enable max-nesting-depth
        }

        &:checked ~ .pt-control-indicator {
          background: $dark-switch-checked-background-color-disabled;
        }
      }
    }
  }

  /*
  Inline labels

  Markup:
  <label class="pt-label">A group of related options</label>
  <label class="pt-control pt-checkbox pt-inline">
    <input type="checkbox" />
    <span class="pt-control-indicator"></span>
    First
  </label>
  <label class="pt-control pt-checkbox pt-inline">
    <input type="checkbox" />
    <span class="pt-control-indicator"></span>
    Second
  </label>
  <label class="pt-control pt-checkbox pt-inline">
    <input type="checkbox" />
    <span class="pt-control-indicator"></span>
    Third
  </label>

  Styleguide pt-checkbox.pt-inline
  */
}
