@import "../error-message/index";
@import "../fieldset/index";
@import "../hint/index";
@import "../label/index";

@include moaland-exports("moaland/component/checkboxes") {

  $moaland-touch-target-size: 44px;
  $moaland-checkboxes-size: 40px;
  $moaland-small-checkboxes-size: 24px;
  $moaland-checkboxes-label-padding-left-right: moaland-spacing(3);

  .moaland-checkboxes__item {
    @include moaland-font($size: 19);

    display: block;
    position: relative;

    min-height: $moaland-checkboxes-size;

    margin-bottom: moaland-spacing(2);
    padding-left: $moaland-checkboxes-size;

    clear: left;
  }

  .moaland-checkboxes__item:last-child,
  .moaland-checkboxes__item:last-of-type {
    margin-bottom: 0;
  }

  .moaland-checkboxes__input {
    $input-offset: ($moaland-touch-target-size - $moaland-checkboxes-size) / 2;

    cursor: pointer;

    // IE8 doesn’t support pseudo-elements, so we don’t want to hide native
    // elements there.
    @include moaland-not-ie8 {
      position: absolute;

      z-index: 1;
      top: $input-offset * -1;
      left: $input-offset * -1;

      width: $moaland-touch-target-size;
      height: $moaland-touch-target-size;
      margin: 0;

      opacity: 0;
    }

    @include moaland-if-ie8 {
      margin-top: 10px;
      margin-right: $moaland-checkboxes-size / -2;
      margin-left: $moaland-checkboxes-size / -2;
      float: left;

      // add focus outline to input
      &:focus {
        outline: $moaland-focus-width solid $moaland-focus-colour;
      }
    }
  }

  .moaland-checkboxes__label {
    display: inline-block;
    margin-bottom: 0;
    padding: 8px $moaland-checkboxes-label-padding-left-right moaland-spacing(1);
    cursor: pointer;
    // remove 300ms pause on mobile
    -ms-touch-action: manipulation;
        touch-action: manipulation;
  }

  // [ ] Check box
  .moaland-checkboxes__label:before {
    content: "";
    box-sizing: border-box;
    position: absolute;
    top: 0;
    left: 0;
    width: $moaland-checkboxes-size;
    height: $moaland-checkboxes-size;
    border: $moaland-border-width-form-element solid currentColor;
    background: transparent;
  }

  // ✔ Check mark
  //
  // The check mark is a box with a border on the left and bottom side (└──),
  // rotated 45 degrees
  .moaland-checkboxes__label:after {
    content: "";
    box-sizing: border-box;

    position: absolute;
    top: 11px;
    left: 9px;
    width: 23px;
    height: 12px;

    -webkit-transform: rotate(-45deg);

        -ms-transform: rotate(-45deg);

            transform: rotate(-45deg);
    border: solid;
    border-width: 0 0 5px 5px;
    // Fix bug in IE11 caused by transform rotate (-45deg).
    // See: alphagov/govuk_elements/issues/518
    border-top-color: transparent;

    opacity: 0;

    background: transparent;
  }

  .moaland-checkboxes__hint {
    display: block;
    padding-right: $moaland-checkboxes-label-padding-left-right;
    padding-left: $moaland-checkboxes-label-padding-left-right;
  }

  // Focused state
  .moaland-checkboxes__input:focus + .moaland-checkboxes__label:before {
    border-width: 4px;
    box-shadow: 0 0 0 $moaland-focus-width $moaland-focus-colour;
  }

  // Selected state
  .moaland-checkboxes__input:checked + .moaland-checkboxes__label:after {
    opacity: 1;
  }

  // Disabled state
  .moaland-checkboxes__input:disabled,
  .moaland-checkboxes__input:disabled + .moaland-checkboxes__label {
    cursor: default;
  }

  .moaland-checkboxes__input:disabled + .moaland-checkboxes__label {
    opacity: .5;
  }

  // =========================================================
  // Conditional reveals
  // =========================================================

  // The narrow border is used in the conditional reveals because the border has
  // to be an even number in order to be centred under the 40px checkbox or radio.
  $conditional-border-width: $moaland-border-width-narrow;
  // Calculate the amount of padding needed to keep the border centered against the checkbox.
  $conditional-border-padding: ($moaland-checkboxes-size / 2) - ($conditional-border-width / 2);
  // Move the border centered with the checkbox
  $conditional-margin-left: $conditional-border-padding;
  // Move the contents of the conditional inline with the label
  $conditional-padding-left: $conditional-border-padding + $moaland-checkboxes-label-padding-left-right;

  .moaland-checkboxes__conditional {
    @include moaland-responsive-margin(4, "bottom");
    margin-left: $conditional-margin-left;
    padding-left: $conditional-padding-left;
    border-left: $conditional-border-width solid $moaland-border-colour;

    .js-enabled &--hidden {
      display: none;
    }

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

  // =========================================================
  // Small checkboxes
  // =========================================================

  .moaland-checkboxes--small {

    $input-offset: ($moaland-touch-target-size - $moaland-small-checkboxes-size) / 2;
    $label-offset: $moaland-touch-target-size - $input-offset;

    .moaland-checkboxes__item {
      @include moaland-clearfix;
      min-height: 0;
      margin-bottom: 0;
      padding-left: $label-offset;
      float: left;
    }

    // Shift the touch target into the left margin so that the visible edge of
    // the control is aligned
    //
    //   ┆What colours do you like?
    //  ┌┆───┐
    //  │┆[] │ Purple
    //  └┆▲──┘
    //  ▲┆└─ Check box pseudo element, aligned with margin
    //  └─── Touch target (invisible input), shifted into the margin
    .moaland-checkboxes__input {
      @include moaland-not-ie8 {
        left: $input-offset * -1;
      }

      @include moaland-if-ie8 {
        margin-left: $moaland-small-checkboxes-size * -1;
      }
    }

    // Adjust the size and position of the label.
    //
    // Unlike larger checkboxes, we also have to float the label in order to
    // 'shrink' it, preventing the hover state from kicking in across the full
    // width of the parent element.
    .moaland-checkboxes__label {
      margin-top: -2px;
      padding: 13px moaland-spacing(3) 13px 1px;
      float: left;

      @include moaland-media-query($from: tablet) {
        padding: 11px moaland-spacing(3) 10px 1px;
      }
    }

    // [ ] Check box
    //
    // Reduce the size of the check box [1], vertically center it within the
    // touch target [2]
    .moaland-checkboxes__label:before {
      top: $input-offset - $moaland-border-width-form-element; // 2
      width: $moaland-small-checkboxes-size; // 1
      height: $moaland-small-checkboxes-size; // 1
    }

    // ✔ Check mark
    //
    // Reduce the size of the check mark and re-align within the checkbox
    .moaland-checkboxes__label:after {
      top: 15px;
      left: 6px;
      width: 12px;
      height: 6.5px;
      border-width: 0 0 3px 3px;
    }

    // Fix position of hint with small checkboxes
    //
    // Do not use hints with small checkboxes – because they're within the input
    // wrapper they trigger the hover state, but clicking them doesn't actually
    // activate the control.
    //
    // (If you do use them, they won't look completely broken... but seriously,
    // don't use them)
    .moaland-checkboxes__hint {
      padding: 0;
      clear: both;
    }

    // Align conditional reveals with small checkboxes
    .moaland-checkboxes__conditional {
      $margin-left: ($moaland-small-checkboxes-size / 2) - ($conditional-border-width / 2);
      margin-left: $margin-left;
      padding-left: $label-offset - ($margin-left + $conditional-border-width);
      clear: both;
    }

    // Hover state for small checkboxes.
    //
    // We use a hover state for small checkboxes because the touch target size
    // is so much larger than their visible size, and so we need to provide
    // feedback to the user as to which checkbox they will select when their
    // cursor is outside of the visible area.
    .moaland-checkboxes__item:hover .moaland-checkboxes__input:not(:disabled) + .moaland-checkboxes__label:before {
      box-shadow: 0 0 0 $moaland-hover-width $moaland-hover-colour;
    }

    // Because we've overridden the border-shadow provided by the focus state,
    // we need to redefine that too.
    //
    // We use two box shadows, one that restores the original focus state [1]
    // and another that then applies the hover state [2].
    .moaland-checkboxes__item:hover .moaland-checkboxes__input:focus + .moaland-checkboxes__label:before {
      box-shadow:
        0 0 0 $moaland-focus-width $moaland-focus-colour, // 1
        0 0 0 $moaland-hover-width $moaland-hover-colour; // 2
    }

    // For devices that explicitly don't support hover, don't provide a hover
    // state (e.g. on touch devices like iOS).
    //
    // We can't use `@media (hover: hover)` because we wouldn't get the hover
    // state in browsers that don't support `@media (hover)` (like Internet
    // Explorer) – so we have to 'undo' the hover state instead.
    @media (hover: none), (pointer: coarse) {
      .moaland-checkboxes__item:hover .moaland-checkboxes__input:not(:disabled) + .moaland-checkboxes__label:before {
        box-shadow: initial;
      }

      .moaland-checkboxes__item:hover .moaland-checkboxes__input:focus + .moaland-checkboxes__label:before {
        box-shadow: 0 0 0 $moaland-focus-width $moaland-focus-colour;
      }
    }
  }
}
