import type FeatureFilter from "./FeatureFilter.js";
import type { JSONSupport, JSONSupportMixinProperties } from "../../core/JSONSupport.js";
import type { EffectPropertyAPI } from "../effects/types.js";
import type { FeatureFilterProperties } from "./FeatureFilter.js";

export interface FeatureEffectProperties extends JSONSupportMixinProperties, Partial<Pick<FeatureEffect, "excludedEffect" | "excludedLabelsVisible" | "includedEffect">> {
  /**
   * The [filter](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureFilter.html) that drives the effect.
   * Features that meet the requirements specified in the filter will have the [includedEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#includedEffect) applied
   * while features that do not meet the filter requirements will have the [excludedEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#excludedEffect) applied.
   * A [FeatureEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html) can only be persisted to a [WebMap](https://developers.arcgis.com/javascript/latest/api-reference/esri-WebMap.html) if an
   * [attribute](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureFilter.html#where) filter is the only property set on `FeatureFilter`.
   */
  filter?: FeatureFilterProperties | null;
}

/**
 * FeatureEffect allows you to emphasize or deemphasize features that
 * satisfy a [filter](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#filter) in 2D [MapView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html). The [includedEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#includedEffect) and
 * [excludedEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#excludedEffect) properties allow you to apply [CSS filters](https://developer.mozilla.org/en-US/docs/Web/CSS/filter)
 * to features that are either included or excluded from the filter. Typically, you use `includedEffect` to emphasize features that
 * are included in the filter and `excludedEffect` to deemphasize features excluded from the filter.
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * > FeatureEffect is not supported in the following scenarios:
 * >    * In 3D [SceneViews](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-SceneView.html)
 * >    * When [FeatureReductionCluster](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#featureReduction) is enabled
 * > A FeatureEffect set on a layerView cannot persisted in a [WebMap](https://developers.arcgis.com/javascript/latest/api-reference/esri-WebMap.html).
 * > See [print](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-print.html) for known printing limitations.
 *
 * ```js
 * // apply a feature effect to features that do not
 * // meet the filter requirements
 * const featureFilter = new FeatureFilter({
 *   geometry: filterGeometry,
 *   spatialRelationship: "intersects",
 *   distance: distance,
 *   units: units
 * });
 *
 * // set effect on excluded features
 * // make them gray and transparent
 * layer.featureEffect = new FeatureEffect({
 *   filter: featureFilter,
 *   excludedEffect: "grayscale(100%) opacity(30%)"
 * });
 * ```
 *
 * @since 4.22
 * @see [Sample - Apply effects to features](https://developers.arcgis.com/javascript/latest/sample-code/featureeffect-geometry/)
 * @see [Sample - Apply drop-shadow effect to a layerView](https://developers.arcgis.com/javascript/latest/sample-code/featureeffect-drop-shadow/)
 * @see [All samples that use effect](https://developers.arcgis.com/javascript/latest/sample-code/?search=effect)
 */
export default class FeatureEffect extends JSONSupport {
  /**
   * @example
   * // Typical usage
   * const effect = new FeatureEffect({
   *   filter: new FeatureFilter({
   *     where: "magnitude >= 3"
   *   }),
   *   excludedEffect: "grayscale(100%) opacity(30%)"
   * });
   *
   * layer.featureEffect = effect;
   */
  constructor(properties?: FeatureEffectProperties);
  /**
   * The [EffectPropertyAPI](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-effects-types.html#EffectPropertyAPI) applied to features that do not meet
   * the [filter](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#filter) requirements. Effect allows you to apply [css filter-like](https://developer.mozilla.org/en-US/docs/Web/CSS/filter)
   * functions to layers and layerViews to create custom visual effects to enhance the cartographic quality of your maps.
   *
   * @see [Sample - Apply effects to features](https://developers.arcgis.com/javascript/latest/sample-code/featureeffect-geometry/)
   * @see [Sample - Apply drop-shadow effect to a layerView](https://developers.arcgis.com/javascript/latest/sample-code/featureeffect-drop-shadow/)
   * @see [All samples that use effect](https://developers.arcgis.com/javascript/latest/sample-code/?search=effect)
   * @example
   * const excludedEffect = "grayscale(50%) opacity(30%)";
   *
   * layer.featureEffect = new FeatureEffect({
   *   filter: new FeatureFilter({
   *     where: "POPULATION > 1000000"
   *   }),
   *   excludedEffect: excludedEffect
   * });
   */
  accessor excludedEffect: EffectPropertyAPI | null | undefined;
  /**
   * Indicates if labels are visible for features that are [excluded](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#excludedEffect) from the [filter](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#filter).
   * This property must be set to `true` in order to persist the [FeatureEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html) to a [WebMap](https://developers.arcgis.com/javascript/latest/api-reference/esri-WebMap.html).
   *
   * @default false
   */
  accessor excludedLabelsVisible: boolean;
  /**
   * The [filter](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureFilter.html) that drives the effect.
   * Features that meet the requirements specified in the filter will have the [includedEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#includedEffect) applied
   * while features that do not meet the filter requirements will have the [excludedEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#excludedEffect) applied.
   * A [FeatureEffect](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html) can only be persisted to a [WebMap](https://developers.arcgis.com/javascript/latest/api-reference/esri-WebMap.html) if an
   * [attribute](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureFilter.html#where) filter is the only property set on `FeatureFilter`.
   */
  get filter(): FeatureFilter | null | undefined;
  set filter(value: FeatureFilterProperties | null | undefined);
  /**
   * The [EffectPropertyAPI](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-effects-types.html#EffectPropertyAPI) applied to features that meet the [filter](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html#filter) requirements.
   * Effect allows you to apply [css filter-like](https://developer.mozilla.org/en-US/docs/Web/CSS/filter)
   * functions to layers and layerViews to create custom visual effects to enhance the cartographic quality of your maps.
   *
   * @see [Sample - Apply effects to features](https://developers.arcgis.com/javascript/latest/sample-code/featureeffect-geometry/)
   * @see [Sample - Apply drop-shadow effect to a layerView](https://developers.arcgis.com/javascript/latest/sample-code/featureeffect-drop-shadow/)
   * @see [Sample - Apply multiple effect to a layerView](https://developers.arcgis.com/javascript/latest/sample-code/featureeffect-multiple-effects/)
   * @see [All samples that use effect](https://developers.arcgis.com/javascript/latest/sample-code/?search=effect)
   * @example
   * const includedEffect = "sepia(70%) saturate(150%) hue-rotate(320deg) opacity(60%)";
   * layer.featureEffect = new FeatureEffect({
   *   filter: new FeatureFilter({
   *     where: "POPULATION > 1000000"
   *   }),
   *   includedEffect: includedEffect
   * });
   */
  accessor includedEffect: EffectPropertyAPI | null | undefined;
  /**
   * Creates a deep clone of FeatureEffect object.
   *
   * @returns A new instance of a FeatureEffect
   */
  clone(): FeatureEffect;
}