/**
 * @license
 * Copyright 2023 Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
// Copyright 2016 Google Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// stylelint-disable selector-class-pattern --
// Selector '.forge-*' should only be used in this project.

@use 'sass:math';
@use 'sass:map';
@use 'sass:list';
@use '@material/elevation/elevation-theme' as mdc-elevation-theme;
@use '@material/feature-targeting/feature-targeting' as mdc-feature-targeting;
@use '@material/rtl/mixins' as mdc-rtl-mixins;
@use '@material/shape/mixins' as mdc-shape-mixins;
@use '@material/shape/functions' as mdc-shape-functions;
@use '@material/theme/state' as mdc-state;
@use '@material/theme/theme-color' as mdc-theme-color;
@use '@material/theme/theme' as mdc-theme;
@use '@material/typography/typography' as mdc-typography;
@use './fab-theme';

$extended-icon-padding: 12px !default;
$extended-label-padding: 20px !default;
$extended-height: 48px !default;

$_extended-light-theme: (
  container-color: mdc-theme-color.$surface,
  container-shape: 50%,
  container-height: 56px,
  container-elevation: mdc-elevation-theme.get-elevation(3),
  icon-size: 36px,
  icon-color: null,
  label-text-font: mdc-typographyget-font(button),
  label-text-size: mdc-typographyget-size(button),
  label-text-weight: mdc-typographyget-weight(button),
  label-text-tracking: mdc-typographyget-tracking(button),
  label-text-color: mdc-theme-color.$on-surface,
  hover-container-elevation: null,
  hover-state-layer-color: mdc-theme-color.$primary,
  hover-state-layer-opacity: null,
  hover-icon-color: null,
  hover-label-text-color: null,
  focus-container-elevation: null,
  focus-state-layer-color: mdc-theme-color.$primary,
  focus-state-layer-opacity: null,
  focus-outline-color: null,
  focus-outline-width: null,
  focus-icon-color: null,
  focus-label-text-color: null,
  pressed-container-elevation: null,
  pressed-ripple-color: mdc-theme-color.$primary,
  pressed-ripple-opacity: null,
  pressed-icon-color: null,
  pressed-label-text-color: null,
);

@mixin theme($theme) {
  @include mdc-theme.validate-theme($_extended-light-theme, $theme);
  @include fab-theme.base-theme($theme);
  $container-shape: map.get($theme, container-shape);
  @if $container-shape {
    @include extended-shape-radius($container-shape);
  }
  @include _label-color(
    (
      default: map.get($theme, label-text-color),
      hover: map.get($theme, hover-label-text-color),
      focus: map.get($theme, focus-label-text-color),
      pressed: map.get($theme, pressed-label-text-color),
    )
  );
  @include _label-typography(
    (
      font: map.get($theme, label-text-font),
      size: map.get($theme, label-text-size),
      weight: map.get($theme, label-text-weight),
      tracking: map.get($theme, label-text-tracking),
    )
  );
}

@mixin extended-fluid($query: mdc-feature-targeting.all()) {
  $feat-structure: mdc-feature-targeting.create-target($query, structure);

  @include mdc-feature-targeting.targets($feat-structure) {
    width: 100%;
  }
}

@mixin extended-padding(
  $icon-padding,
  $label-padding,
  $focus-outline-width: null,
  $query: mdc-feature-targeting.all()
) {
  $feat-structure: mdc-feature-targeting.create-target($query, structure);

  @include extended-label-padding($label-padding, $query: $query);

  // Offsets the outer label padding by deducting it from icon padding.
  .forge-fab__icon {
    @include mdc-feature-targeting.targets($feat-structure) {
      @include extended-icon-padding($icon-padding, $label-padding);
    }
  }

  // For Extended FAB with text label followed by icon.
  .forge-fab__label + .forge-fab__icon {
    @include mdc-feature-targeting.targets($feat-structure) {
      @include extended-icon-padding(
        $icon-padding,
        $label-padding,
        $is-icon-at-end: true
      );
    }
  }

  @if $focus-outline-width {
    @include fab-theme.focus-outline-width(
      $focus-outline-width,
      $padding: 0 $label-padding
    );
  }
}

@mixin extended-icon-padding(
  $icon-padding,
  $label-padding,
  $is-icon-at-end: false
) {
  $start: 'calc(icon - label)';
  $end: $icon-padding;

  @if $is-icon-at-end {
    $start: $icon-padding;
    $end: 'calc(icon - label)';
  }

  @include mdc-rtl-mixins.reflexive-property(
    margin,
    $start,
    $end,
    $replace: (icon: $icon-padding, label: $label-padding)
  );
}

@mixin extended-label-padding($label-padding, $query: mdc-feature-targeting.all()) {
  $feat-structure: mdc-feature-targeting.create-target($query, structure);

  @include mdc-feature-targeting.targets($feat-structure) {
    @include mdc-theme.property(padding-left, $label-padding, $gss: (noflip: true));
    @include mdc-theme.property(
      padding-right,
      $label-padding,
      $gss: (noflip: true)
    );
  }
}

@mixin extended-shape-radius(
  $radius,
  $rtl-reflexive: false,
  $query: mdc-feature-targeting.all()
) {
  // Extended FABs _do_ need a $component-height since they are not circular.
  // Percentage radii must be resolved.
  @include mdc-shape-mixins.radius(
    $radius,
    $rtl-reflexive,
    $component-height: $extended-height,
    $query: $query
  );

  #{fab-theme.$ripple-target} {
    @include mdc-shape-mixins.radius(
      $radius,
      $rtl-reflexive,
      $component-height: $extended-height,
      $query: $query
    );
  }
}

@mixin _label-color($color-or-map) {
  &:not(:disabled) {
    @include _set-label-color(mdc-state.get-default-state($color-or-map));

    &:hover {
      @include _set-label-color(mdc-state.get-hover-state($color-or-map));
    }

    &:focus {
      @include _set-label-color(mdc-state.get-focus-state($color-or-map));
    }

    &:active {
      @include _set-label-color(mdc-state.get-pressed-state($color-or-map));
    }
  }

  &:disabled {
    @include _set-label-color(mdc-state.get-disabled-state($color-or-map));
  }
}

@mixin _set-label-color($color) {
  .forge-fab__label {
    @include mdc-theme.property(color, $color);
  }
}

@mixin _label-typography($typography-map) {
  font-family: map.get($typography-map, font);
  font-size: map.get($typography-map, size);
  font-weight: map.get($typography-map, weight);
  letter-spacing: map.get($typography-map, tracking);
}
