@import './theming';

// Whether duplication warnings should be disabled. Warnings enabled by default.
$mat-theme-ignore-duplication-warnings: false !default;

// Warning that will be printed if duplicated styles are generated by a theme.
$_mat-theme-duplicate-warning: 'Read more about how style duplication can be avoided in a ' +
  'dedicated guide. https://github.com/angular/components/blob/master/guides/duplicate-theming-styles.md';

// These variable are not intended to be overridden externally. They use `!default` to
// avoid being reset every time this file is imported.
$_mat-theme-emitted-color: () !default;
$_mat-theme-emitted-typography: () !default;
$_mat-theme-emitted-density: () !default;

// Checks if configurations that have been declared in the given theme have been generated
// before. If so, warnings will be reported. This should notify developers in case duplicate
// styles are accidentally generated due to wrong usage of the all-theme mixins.
//
// Additionally, this mixin controls the default value for the density configuration. By
// default, density styles are generated at scale zero. If the same density styles would be
// generated a second time though, the default value will change to avoid duplicate styles.
//
// The mixin keeps track of all configurations in a list that is scoped to the specified
// id. This is necessary because a given theme can be passed to multiple disjoint theme mixins
// (e.g. `angular-material-theme` and `angular-material-mdc-theme`) without causing any
// style duplication.
@mixin _mat-check-duplicate-theme-styles($theme-or-color-config, $id) {
  $theme: _mat-legacy-get-theme($theme-or-color-config);
  $color-config: mat-get-color-config($theme);
  $density-config: mat-get-density-config($theme);
  $typography-config: mat-get-typography-config($theme);
  // Lists of previous `color`, `density` and `typography` configurations.
  $previous-color: map_get($_mat-theme-emitted-color, $id) or ();
  $previous-typography: map_get($_mat-theme-emitted-typography, $id) or ();
  $previous-density: map_get($_mat-theme-emitted-density, $id) or ();
  // Whether duplicate legacy density styles would be generated.
  $duplicate-legacy-density: false;

  // Check if the color configuration has been generated before.
  @if $color-config != null {
    @if index($previous-color, $color-config) != null and
        not $mat-theme-ignore-duplication-warnings {
      @warn 'The same color styles are generated multiple times. ' +
          $_mat-theme-duplicate-warning;
    }
    $previous-color: append($previous-color, $color-config);
  }

  // Check if the typography configuration has been generated before.
  @if $typography-config != null {
    @if index($previous-typography, $typography-config) != null and
        not $mat-theme-ignore-duplication-warnings {
      @warn 'The same typography styles are generated multiple times. ' +
          $_mat-theme-duplicate-warning;
    }
    $previous-typography: append($previous-typography, $typography-config);
  }

  // Check if the density configuration has been generated before.
  @if $density-config != null {
    @if index($previous-density, $density-config) != null {
      // Only report a warning if density styles would be duplicated for non-legacy theme
      // definitions. For legacy themes, we have compatibility logic that avoids duplication
      // of default density styles. We don't want to report a warning in those cases.
      @if _mat-is-legacy-constructed-theme($theme) {
        $duplicate-legacy-density: true;
      }
      @else if not $mat-theme-ignore-duplication-warnings {
        @warn 'The same density styles are generated multiple times. ' +
           $_mat-theme-duplicate-warning;
      }
    }
    $previous-density: append($previous-density, $density-config);
  }

  $_mat-theme-emitted-color: map_merge(
      $_mat-theme-emitted-color, ($id: $previous-color)) !global;
  $_mat-theme-emitted-density: map_merge(
      $_mat-theme-emitted-density, ($id: $previous-density)) !global;
  $_mat-theme-emitted-typography: map_merge(
      $_mat-theme-emitted-typography, ($id: $previous-typography)) !global;

  // Optionally, consumers of this mixin can wrap contents inside so that nested
  // duplicate style checks do not report another warning. e.g. if developers include
  // the `angular-material-theme` mixin twice, only the top-level duplicate styles check
  // should report a warning. Not all individual components should report a warning too.
  $orig-mat-theme-ignore-duplication-warnings: $mat-theme-ignore-duplication-warnings;
  $mat-theme-ignore-duplication-warnings: true !global;

  // If duplicate default density styles would be generated for a legacy constructed theme,
  // we adjust the density generation so that no density styles are generated by default.
  // If no default density styles have been generated yet, we ensure that the styles
  // are generated at root. For legacy themes our goal is to generate default density
  // styles **once** and at root. This matches the old behavior where density styles were
  // part of the base component styles (that did not use view encapsulation).
  // TODO: Remove this compatibility logic when the legacy theming API is removed.
  $_mat-density-generate-at-root: _mat-is-legacy-constructed-theme($theme) !global;
  $_mat-density-generate-styles: not $duplicate-legacy-density !global;

  @content;
  $mat-theme-ignore-duplication-warnings: $orig-mat-theme-ignore-duplication-warnings !global;

  $_mat-density-generate-at-root: false !global;
  $_mat-density-generate-styles: true !global;
}
