import { type Seed, type Generator } from 'toosoon-prng';
import type { Alphabet, Axiom, AxiomParameter, Command, CommandKey, Commands, DefaultAlphabet, Define, DefineKey, Defines, IgnoredAlphabet, ProductionParameter, Productions, SuccessorParameter, Symbol } from './types';
export type LSystemParameters<A extends Alphabet, I extends Alphabet = IgnoredAlphabet> = {
    /**
     * Represent the set of symbols used in an L-System
     */
    readonly alphabet?: A;
    /**
     * Represent the set of symbols to be ignored by the L-System
     */
    readonly ignoredSymbols?: I;
    /**
     * The initial phrase of the L-System
     */
    axiom?: AxiomParameter<A | I>;
    /**
     * The number of iterations to perform
     */
    iterations?: number;
    /**
     * Key-value Object to set constant values that will be used by the L-System
     */
    defines?: {
        [key in DefineKey]?: Define;
    };
    /**
     * Key-value Object to set the productions from one symbol to its axiom
     */
    productions?: {
        [successorParameter in SuccessorParameter<A>]?: ProductionParameter<A, I>;
    };
    /**
     * Key-value Object to set Functions be executed for each symbol in sequential order
     */
    commands?: {
        [key in CommandKey<A, I>]?: Command<A, I>;
    };
    /**
     * Seed string used for pseudo-random number generation in stochastic productions
     */
    seed?: Seed;
    /**
     * Generator function used for pseudo-random number generations in stochastic productions
     */
    generator?: Generator;
};
/**
 * LSystem class
 *
 * @exports
 * @class LSystem
 * @template {Alphabet} [A=DefaultAlphabet]
 * @template {Alphabet} [I=IgnoredAlphabet]
 */
export default class LSystem<A extends Alphabet = DefaultAlphabet, I extends Alphabet = IgnoredAlphabet> {
    readonly alphabet: A;
    readonly ignoredSymbols: I;
    axiom: Axiom<A | I>;
    iterations: number;
    readonly defines: Defines;
    readonly productions: Productions<A, I>;
    readonly commands: Commands<A, I>;
    private readonly _prng;
    /**
     * @param {LSystemParameters<A,I>} params
     */
    constructor({ alphabet, ignoredSymbols, axiom, iterations, defines, productions, commands, seed, generator }: LSystemParameters<A, I>);
    /**
     * Set the axiom of the L-System
     *
     * @param {AxiomParameter<A|I>} axiom Initial phrase of this L-System
     */
    setAxiom(axiom: AxiomParameter<A | I>): void;
    /**
     * Set a define for this L-System
     *
     * @param {DefineKey} key Key for defining constant
     * @param {Define} define A constant value
     */
    setDefine(key: DefineKey, define: Define): void;
    /**
     * Set multiple defines for the L-System.
     *
     * @param {object} defines Collection of defined constants
     */
    setDefines(defines: {
        [key in DefineKey]?: Define;
    }): void;
    /**
     * Clear all defines from this L-System
     */
    clearDefines(): void;
    /**
     * Set a production for the L-System.
     *
     * @param {SuccessorParameter<A>} successorParameter Successor symbol mapped to the production
     * @param {ProductionParameter<A,I>} productionParameter Production rule mapped to the symbol
     */
    setProduction(successorParameter: SuccessorParameter<A>, productionParameter: ProductionParameter<A, I>): void;
    /**
     * Set multiple productions for this L-System
     *
     * @param {object} productions Collection of production rules mapped to symbols
     */
    setProductions(productions: {
        [successorParameter in SuccessorParameter<A>]?: ProductionParameter<A, I>;
    }): void;
    /**
     * Clear all productions from the L-System
     */
    clearProductions(): void;
    /**
     * Return the result of a production rule
     *
     * @param {Production<A,I>} production
     * @param {AxiomPart<A|I>} part
     * @param {number} index
     * @param {boolean} [recursive=false]
     * @returns {ProductionResult<A|I>}
     */
    private _getProductionResult;
    /**
     * Apply productions rules on current axiom.
     * It corresponds to 1 iteration of this L-System.
     *
     * @returns {Axiom<A|I>}
     */
    private _applyProductions;
    /**
     * Set a command for this L-System
     *
     * @param {Symbol<A|I>} symbol Symbol used as a key for the command
     * @param {Command<A,I>} command Function to be executed for each corresponding symbol
     */
    setCommand(symbol: Symbol<A | I>, command: Command<A, I>): void;
    /**
     * Set multiple commands for this L-System
     *
     * @param {object} commands Collection of commands mapped to symbols
     */
    setCommands(commands: {
        [key in CommandKey<A, I>]?: Command<A, I>;
    }): void;
    /**
     * Clear all commands from this L-System
     */
    clearCommands(): void;
    /**
     * Execute the commands defined in this L-System
     */
    run(): void;
    /**
     * Perform a specified number of iterations on this L-System
     *
     * @param {number} [iterations] Number of iterations
     * @returns {Axiom<A|I>}
     */
    iterate(iterations?: number): Axiom<A | I>;
    /**
     * Get the current axiom of this L-System
     *
     * @returns {string}
     */
    getAxiomString(): string;
}
