// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@import 'package:angular_components/css/material/material';
@import 'package:angular_components/css/material/shadow';
// TODO(google): Remove once glyph has been replaced with material-icon.
@import 'package:angular_components/glyph/mixins';
@import 'package:angular_components/material_icon/mixins';
@import 'package:angular_components/theme/mixins';

$fab-size: $mat-grid * 7;
$fab-mini-size: $mat-grid * 5;
$fab-icon-size: $mat-grid * 3;

$button-horizontal-padding: .57em;
$button-vertical-padding: .7em;
$button-min-width: 8 * $mat-grid; // Value from mdc-button.

// From spec http://www.google.com/design/spec/components/buttons.html#buttons-flat-raised-buttons
$button-disabled-color: rgba(0, 0, 0, $mat-opacity-lightest);
$button-disabled-background: rgba(0, 0, 0, $mat-divider-opacity);

// Deprecated
// No longer used by material buttons. Hover color is now based on the button
// color.
$button-hovered-background: rgba(158, 158, 158, .20);

$button-disabled-color-dark: rgba(255, 255, 255, $mat-dark-opacity-lightest);
$button-disabled-background-dark: rgba(255, 255, 255, $mat-divider-opacity);

// Private used for external mixin, and button-base only.
@mixin _button-raised {
  @include material-shadow;

  @include acx-theme-dark {
    background-color: $mat-blue;
  }

  &[disabled] {
    background: $button-disabled-background;
    @include shadow-none;

    @include acx-theme-dark {
      background: $button-disabled-background-dark;
    }
  }
}

/// Mixin used for styling dense buttons local to a view. Private to this
/// file.
@mixin _button-dense {
  &:not([icon]) {
    height: $mat-grid * 4;
    font-size: $mat-font-size-body;
  }
}

/// Mixin used for styling compact buttons local to a view. Private to this
/// file.
@mixin _button-compact {
  &:not([icon]) {
    padding: 0 $mat-grid;
  }
}

/// Private mixin for styling the highlight when a button is hovered or focused.
@mixin _button-hover {
  &:not([disabled]):not([icon]):hover::after,
  &.is-focused::after {
    @content
  }
}

/// Mixin to remove the highlight when a button is hovered or focused.
@mixin no-button-hover($selector) {
  ::ng-deep #{$selector} {
    @include _button-hover {
      display: none;
    }
  }
}


@mixin button-base {
  @include acx-theme-dark {
    color: $mat-white;
  }

  // TODO(google): Migrate to extended mixin mat-font-button

  font-size: $mat-font-size-button;

  font-weight: $mat-font-weight-medium;

  text-transform: uppercase;

  user-select: none;
  background: transparent;
  border-radius: inherit;
  box-sizing: border-box;
  cursor: pointer;
  display: inline-block;
  letter-spacing: .01em;
  line-height: normal;
  outline: none;
  position: relative;
  text-align: center;

  &:not([icon]) {
    margin: 0 .29em;
  }

  &[dense] {
    @include _button-dense;
  }

  &[compact] {
    @include _button-compact;
  }

  &[disabled] {
    @include acx-theme-dark {
      color: $button-disabled-color-dark;
    }

    color: $button-disabled-color;
    cursor: not-allowed;

    >* {
      pointer-events: none;
    }
  }

  @media (hover: hover) {
    @include _button-hover {
      content: '';
      display: block;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: currentColor;
      // For windows high contrast.
      outline: 2px solid transparent;
      opacity: $mat-divider-opacity;
      border-radius: inherit;
      pointer-events: none;
    }
  }

  &[raised] {
    @include _button-raised;

    &.highlighted:not([disabled]) {
      background-color: $mat-blue-500;
      color: $mat-white;
    }
  }

  &[no-ink] material-ripple {
    display: none;
  }

  &[clear-size] {
    margin: 0;
  }

  .content {
    display: inline-flex;
    align-items: center;
  }
}

@mixin material-button {
  @include button-base;

  &:not([icon]) {
    border-radius: 2px;
    min-width: $button-min-width;

    .content {
      padding: $button-vertical-padding $button-horizontal-padding;
    }
  }

  &[icon] {
    border-radius: 50%;

    .content {
      padding: $mat-grid;
    }
  }

  &[clear-size] {
    min-width: 0;
  }
}

@mixin fab-size($size) {
  border-radius: $size / 2;

  .content {
    height: $size;
    width: $size;
  }
}

@mixin fab-base($size) {
  @include button-base;
  @include fab-size($size);

  .content {
    justify-content: center;
  }
}

@mixin fab {
  @include fab-base($fab-size);
}

@mixin fab-mini {
  @include fab-base($fab-mini-size);
}

// Allow customized size and icon-size on fab button.
@mixin fab-custom-size($size, $icon-size: $fab-icon-size) {
  border-radius: $size / 2;

  ::ng-deep {
    .content.content {
      height: $size;
      width: $size;
    }

    material-icon {
      @include material-icon-size($icon-size);
    }

    // TODO(google): Remove once glyph has been replaced with material-icon.
    glyph {
      @include glyph-size($icon-size);
    }
  }
}

// Apply button color to a button matching the selector.
//
// The color given is not applied to disabled button, as it could otherwise look
// as an enabled button.
//
@mixin button-color($selector, $color) {
  ::ng-deep #{$selector}:not([disabled]):not([icon]) {
    color: $color;
  }
}

@mixin button-disabled-color($selector, $disabled-color) {
  ::ng-deep #{$selector}[disabled] {
    color: $disabled-color;
  }
}

@mixin button-background-color($selector, $background-color) {
  ::ng-deep #{$selector}:not([disabled]) {
    background-color: $background-color;
  }
}

/// Offsets the button content so it's left aligned, without removing the
/// padding.
@mixin button-left-aligned-content {
  margin-left: -$button-horizontal-padding;
}

/// Applies letter-spacing to the text of <material-button>.
@mixin button-letter-spacing($selector, $letter-spacing) {
  ::ng-deep #{$selector} div {
    letter-spacing: $letter-spacing;
  }
}

@mixin icon-button-hover-color($selector, $color) {
  @media (hover: hover) {
    ::ng-deep #{$selector}[icon]:not([disabled]):hover {
      > .content > material-icon,
      // TODO(google): Remove once glyph has been replaced with material-icon.
      > .content > glyph {
        color: $color;
      }
    }
  }
}

@mixin icon-button-focus-color($selector, $color) {
  ::ng-deep #{$selector}[icon]:not([disabled]):focus {
    > .content > material-icon,
    // TODO(google): Remove once glyph has been replaced with material-icon.
    > .content > glyph {
      color: $color;
    }
  }
}

@mixin icon-button-color($selector, $color) {
  ::ng-deep #{$selector}[icon]:not([disabled]) {
    // Set the color here to be found by the ripple
    color: $color;

    > .content > material-icon,
    // TODO(google): Remove once glyph has been replaced with material-icon.
    > .content > glyph {
      // And here for the icon itself.
      color: $color;
    }
  }
}

/// Sets padding for the icon button.
// @deprecated use button-padding instead.
@mixin icon-button-padding($selector, $padding) {
  #{$selector}[icon] ::ng-deep .content.content {
    padding: $padding;
  }
}

/// Sets the padding for a button.
///
/// Should target the button specifically. Works for standard and icon buttons.
///   Example:
///   ```scss
///   material-button.padding {
///     @include button-padding($mat-grid);
///   }
///   ```
@mixin button-padding($padding) {
  ::ng-deep .content.content.content {
    padding: $padding;
  }
}

/// Sets the vertical alignment for a button.
///
/// Should target the button specifically.
///   Example:
///   ```scss
///   material-button.bottom {
///     @include vertical-align(bottom);
///   }
///   ```
@mixin vertical-align($value) {
  ::ng-deep .content.content {
    vertical-align: $value;
  }
}

/// Mixin to create a raised button taking an optional color of the button.
///
/// Should be scopped to the specific button needed to make raised.
///   Example:
///   ```scss
///   :host {
///     @include raised-button('material-button.my-raised', $mat-blue);
///   }
///   ```
@mixin raised-button($selector, $color: null) {
  ::ng-deep #{$selector} {
    @include _button-raised;
  }

  @if $color {
    @include button-background-color($selector, $color);
    @include button-color($selector, $mat-white);
  } @else {
    // Specifically set raised buttons to transparent. This ensures hover,
    // and other colors are correct.
    @include button-background-color($selector, transparent);
  }
}

/// Mixin to create a dense button. Use this mixin enable dense buttons
/// to all components below the given scope. Do not provide a scope if all
/// all buttons or all buttons of a certain selector on the page should be
/// dense.
///
/// Should be scopped unless all buttons on the page should be dense.
///   Example:
///   ```scss
///   :host {
///     @include button-dense-theme('material-button.dense');
///   }
///   ```
@mixin button-dense-theme($selector) {
  ::ng-deep #{$selector} {
    @include _button-dense;
  }
}

/// Mixin to create a compact button. Use this mixin enable compact buttons
/// to all components below the given scope. Do not provide a scope if all
/// all buttons or all buttons of a certain selector on the page should be
/// compact.
///
/// Should be scopped unless all buttons on the page should be compact.
///   Example:
///   ```scss
///   :host {
///     @include button-compact-theme('material-button.compact');
///   }
///   ```
@mixin button-compact-theme($selector) {
  ::ng-deep #{$selector} {
    @include _button-compact;
  }
}

/// Resets the text-transform property of the button.
///
/// This removes the uppercase transform default for the button and allows the
/// content itself to control capitalization.
@mixin reset-button-text-transform {
  ::ng-deep .content {
    text-transform: initial;
  }
}
