import type { Properties } from 'gis-tools/index.js';
import type { Comparator, NestedKey, NotNullOrObject } from './style.spec.js';
/** Input condition could be a string, number, string[], or number[] */
export type InputCondition = string | number | string[] | number[];
/** Conditional function build for filtering */
export type ConditionFunction = (input: InputCondition, properties: Properties) => boolean;
/** Filter function */
export type FilterFunction = (properties: Properties) => boolean;
/** Conditional manager */
export interface Conditional {
    keyCondition?: {
        key: string;
        keyFunction: ConditionFunction;
    };
    filterCondition?: FilterFunction;
}
/**
 * Condition object.
 *
 * ### Properties
 * - `key`: [See {@link NestedKey}] The key to pull the value from the properties to compare
 * - `comparator`: [See {@link Comparator}] Used by the filter function to determine if a feature should be included in the render.
 * - `value`: [See {@link NotNullOrObject}] optional value to compare against
 *
 * When creating conditionals, you have two ways to do it:
 *
 * ## 1. keyCondition
 *
 * ```json
 * { "filter": { "key": "type", "comparator": "in", "value": ["ocean", "lake"] } }
 *
 * ## 2. filterCondition
 *
 * ```json
 * { "filter": { "and": [{ "key": "class", "comparator": "==", "value": "ocean" }, { "key": "size", "comparator": "==", "value": "large" }, { "key": "type", "comparator": "!=", "value": "pacific" }] } }
 * ```
 *
 * ## Nesting
 *
 * Sometimes vector data's properties are complex objects. To access nested fields, you can use dot notation.
 *
 * ```json
 * { "filter": { "nestedKey": "class", "key": { "key": "type", "comparator": "==", "value": "ocean" } } }
 * ```
 */
export interface Condition extends NestedKey {
    /**
     * One of `"==" | "!=" | ">" | ">=" | "<" | "<=" | "in" | "!in" | "has" | "!has"`
     * Used by the filter function to determine if a feature should be included in the render.
     *
     * NOTE: "in" means "in the array" and "has" means "has the key"
     *
     * ex.
     * ```json
     * { "filter": { "key": "type", "comparator": "in", "value": ["ocean", "lake"] } }
     * ```
     * this would be used to filter features where `feature.properties.type` is either "ocean" or "lake"
     *
     * ex.
     * ```json
     * { "filter": { "key": "type", "comparator": "has", "value": "ocean" } }
     * ```
     * this would be used to filter features where `feature.properties.type` is an array that has the key "ocean"
     */
    comparator: Comparator;
    /**
     * A non null object.
     *
     * Must be an array for "in" or "!in"
     */
    value?: NotNullOrObject;
}
/**
 * Filter Definition
 *
 * A filter is a set of conditions that are used to filter out features.
 *
 * ### Forms
 * - And Gate Filter: {@link AndFilter}
 * - Or Gate Filter: {@link OrFilter}
 * - Condition: {@link Condition}
 *
 * ### Condition Parameters
 * - `key`: The key to filter on
 * - `comparator`: [See {@link Comparator}] The comparator to use
 * - `value`: The value to compare
 *
 * example:
 *
 * ```json
 * "filter": { "key": "class", "comparator": "==", "value": "ocean" }
 * ```
 *
 * another example:
 *
 * ```json
 * "filter": {
 *  "or": [
 *    { "key": "class", "comparator": "==", "value": "ocean" },
 *    { "key": "class", "comparator": "==", "value": "bay" }
 *  ]
 * }
 * ```
 *
 * another example:
 *
 * ```json
 * "filter": {
 *  "and": [
 *    { "key": "class", "comparator": "==", "value": "ocean" },
 *    { "key": "size", "comparator": "==", "value": "large" },
 *    { "key": "type", "comparator": "!=", "value": "pacific" }
 *  ]
 * }
 * ```
 */
export type Filter = AndFilter | OrFilter | Condition;
/** And Gate Filter */
export interface AndFilter {
    and: Filter[];
}
/** Or Gate Filter */
export interface OrFilter {
    or: Filter[];
}
/**
 * Parse a filter into a filter function
 * @param filter - input user defined filter
 * @returns a filter function that represents the user defined filter
 */
export default function parseFilter(filter?: Filter): FilterFunction;
