import { StorageElementType, CanvasBaseInterface, ImageSprite, KeyframesType, AnimationOptions, UPDATE_PRIORITY, ObjectSegment, ObjectSegmentWithTransition, SequenceOptions, ShakeEffectProps, FadeAlphaTickerProps, MoveTickerProps, RotateTickerProps, ZoomTickerProps, ShowWithDissolveTransitionProps, ShowWithFadeTransitionProps, MoveInOutProps, ZoomInOutProps, PushInOutProps, ImageContainerOptions, ImageSpriteOptions, ImageSpriteMemory, VideoSpriteMemory, ImageContainerMemory, ContainerOptions, ContainerMemory, SoundPlayOptions, LabelRunModeType, StorageObjectType, StepLabelPropsType } from '@drincs/pixi-vn';
import { StepLabelPropsType as StepLabelPropsType$1, LabelAbstract, LabelProps, StepLabelType } from '@drincs/pixi-vn/narration';

type PixiVNJsonStepSwitchElementType<Then> = Then | PixiVNJsonConditionalStatements<Then> | PixiVNJsonConditionalResultToCombine<Then>;
type PixiVNJsonStepSwitchElementsType<Then> = PixiVNJsonStepSwitchElementType<Then>[] | PixiVNJsonConditionalStatements<Then[]>;
interface PixiVNJsonRandom<Then> {
    type: "stepswitch";
    choiceType: "random";
    elements: PixiVNJsonStepSwitchElementsType<Then>;
}
interface PixiVNJsonSequentialRandom<Then> {
    type: "stepswitch";
    choiceType: "sequentialrandom";
    elements: PixiVNJsonStepSwitchElementsType<Then>;
    /**
     * When the sequential ends, what should be the value? If undefined, it will return undefined.
     * If "lastItem", it will return the last item in the array.
     */
    end: undefined | "lastItem";
    /**
     * The subId is used for manager nested switches
     */
    nestedId?: string;
}
interface PixiVNJsonSequential<Then> {
    type: "stepswitch";
    choiceType: "sequential";
    elements: PixiVNJsonStepSwitchElementsType<Then>;
    /**
     * When the sequential ends, what should be the value? If undefined, it will return undefined.
     * If "lastItem", it will return the last item in the array.
     */
    end: undefined | "lastItem";
    /**
     * The subId is used for manager nested switches
     */
    nestedId?: string;
}
interface PixiVNJsonLoop<Then> {
    type: "stepswitch";
    choiceType: "loop";
    elements: PixiVNJsonStepSwitchElementsType<Then>;
    nestedId?: string;
}
type PixiVNJsonStepSwitch<Then> = PixiVNJsonRandom<Then> | PixiVNJsonSequential<Then> | PixiVNJsonLoop<Then> | PixiVNJsonSequentialRandom<Then>;

/**
 * This element is used in case a {@link PixiVNJsonConditionalStatements} gives a result that must be combined with another calculated through other {@link PixiVNJsonConditionalStatements}.
 * in case this possibility is not managed, it will be taken into consideration {@link PixiVNJsonConditionalResultToCombine.firstItem}
 */
type PixiVNJsonConditionalResultToCombine<T> = {
    type: "resulttocombine";
    /**
     * This variable is interpreted differently by Pixi'VN depending on the value
     */
    combine: "cross" | "union";
    firstItem?: T;
    secondConditionalItem?: PixiVNJsonStepSwitchElementType<T>[];
};

type PixiVNJsonStorageGet = {
    type: "value";
    storageOperationType: "get";
    /**
     * Key of the storage
     */
    key: string;
    /**
     * Type of the storage, if it is a flagStorage or a storage.
     * If it is a flagStorage, the value will be get with the function {@link getFlag}
     */
    storageType: "storage" | "flagStorage" | "tempstorage";
};
type PixiVNJsonParamGet = {
    type: "value";
    storageOperationType: "get";
    /**
     * Key of the storage
     */
    key: number;
    storageType: "params";
};
type PixiVNJsonLabelGet = {
    type: "value";
    storageOperationType: "get";
    /**
     * Id of the label
     */
    label: string;
    /**
     * If it is a label, the value will be get with the function {@link narration.getTimesLabelOpened}
     */
    storageType: "label";
};
type PixiVNJsonChoiceGet = {
    type: "value";
    storageOperationType: "get";
    /**
     * index of the choice
     */
    index: number;
    /**
     * If it is a choice, the value will be get with the function {@link narration.getTimesChoiceOpened}
     */
    storageType: "choice";
};
type PixiVNJsonLogicGet = {
    type: "value";
    storageOperationType: "get";
    operation: PixiVNJsonArithmeticOperations | PixiVNJsonConditions;
    storageType: "logic";
};
type PixiVNJsonValueGet = PixiVNJsonStorageGet | PixiVNJsonParamGet | PixiVNJsonLabelGet | PixiVNJsonChoiceGet | PixiVNJsonLogicGet;
type PixiVNJsonOnlyStorageSet = {
    type: "value";
    storageOperationType: "set";
    /**
     * Key of the storage
     */
    key: string;
    /**
     * Value to be set in the storage
     */
    value: StorageElementType | PixiVNJsonValueGet | PixiVNJsonArithmeticOperations | PixiVNJsonConditionalStatements<StorageElementType>;
    /**
     * Type of the storage, if it is a flagStorage or a storage.
     */
    storageType: "storage" | "tempstorage";
};
type PixiVNJsonOnlyParamSet = {
    type: "value";
    storageOperationType: "set";
    /**
     * Key of the storage
     */
    key: number;
    /**
     * Value to be set in the storage
     */
    value: StorageElementType | PixiVNJsonValueGet | PixiVNJsonArithmeticOperations | PixiVNJsonConditionalStatements<StorageElementType>;
    storageType: "params";
};
type PixiVNJsonFlagSet = {
    type: "value";
    storageOperationType: "set";
    /**
     * Key of the storage
     */
    key: string;
    /**
     * Value to be set in the storage
     */
    value: boolean;
    /**
     * Type of the storage, if it is a flagStorage or a storage.
     */
    storageType: "flagStorage";
};
type PixiVNJsonValueSet = PixiVNJsonOnlyStorageSet | PixiVNJsonFlagSet | PixiVNJsonOnlyParamSet;

interface PixiVNJsonArithmeticOperationsArithmetic {
    type: "arithmetic";
    /**
     * Left value of the arithmetic operation
     */
    leftValue: StorageElementType | PixiVNJsonValueGet | PixiVNJsonArithmeticOperations | PixiVNJsonConditionalStatements<StorageElementType | PixiVNJsonValueGet | PixiVNJsonArithmeticOperations>;
    /**
     * Right value of the arithmetic operation
     */
    rightValue: StorageElementType | PixiVNJsonValueGet | PixiVNJsonArithmeticOperations | PixiVNJsonConditionalStatements<StorageElementType | PixiVNJsonValueGet | PixiVNJsonArithmeticOperations>;
    /**
     * Operator of the arithmetic operation
     */
    operator: "*" | "/" | "+" | "-" | "%" | "POW" | "RANDOM";
}
interface PixiVNJsonArithmeticOperationsArithmeticSingle {
    type: "arithmeticsingle";
    /**
     * Left value of the arithmetic operation
     */
    leftValue: StorageElementType | PixiVNJsonValueGet | PixiVNJsonArithmeticOperations | PixiVNJsonConditionalStatements<StorageElementType | PixiVNJsonValueGet | PixiVNJsonArithmeticOperations>;
    /**
     * Operator of the arithmetic operation
     */
    operator: "INT" | "FLOOR" | "FLOAT";
}
/**
 * Arithmetic operations for the PixiVNJson
 */
type PixiVNJsonArithmeticOperations = PixiVNJsonArithmeticOperationsArithmeticSingle | PixiVNJsonArithmeticOperationsArithmetic;

type PixiVNJsonUnionConditionAndOr = {
    type: "union";
    conditions: PixiVNJsonConditions[];
    unionType: "and" | "or";
};
type PixiVNJsonUnionConditionNot = {
    type: "union";
    condition: PixiVNJsonConditions;
    unionType: "not";
};
type PixiVNJsonUnionCondition = PixiVNJsonUnionConditionAndOr | PixiVNJsonUnionConditionNot;

/**
 * Comparation for PixiVNJson.
 * In this comparation, the values to be converted to string and compared.
 */
type PixiVNJsonComparation = {
    type: "compare";
    /**
     * Left value of the comparation
     */
    leftValue: StorageElementType | PixiVNJsonValueGet | PixiVNJsonConditions;
    /**
     * Right value of the comparation
     */
    rightValue: StorageElementType | PixiVNJsonValueGet | PixiVNJsonConditions;
    /**
     * Operator of the comparation
     */
    operator: "==" | "!=" | "<" | "<=" | ">" | ">=" | "CONTAINS";
};
type PixiVNJsonValueCondition = StorageElementType | PixiVNJsonValueGet;
/**
 * Conditions for PixiVNJson
 */
type PixiVNJsonConditions = PixiVNJsonComparation | PixiVNJsonValueCondition | PixiVNJsonUnionCondition | PixiVNJsonArithmeticOperations;

/**
 * If-Else condition for PixiVNJson
 */
interface PixiVNJsonIfElse<Then> {
    type: "ifelse";
    /**
     * The list of conditions to be checked.
     */
    condition: PixiVNJsonConditions;
    /**
     * The value to be returned if the condition is true.
     */
    then: Then | PixiVNJsonIfElse<Then>;
    /**
     * The value to be returned if the condition is false.
     */
    else?: Then | PixiVNJsonIfElse<Then>;
}

type PixiVNJsonConditionalStatements<Then> = PixiVNJsonStepSwitch<Then> | PixiVNJsonIfElse<Then | PixiVNJsonConditionalStatements<Then> | PixiVNJsonConditionalResultToCombine<Then>>;

type PixiVNJsonAnimateBase<T extends CanvasBaseInterface<any>> = {
    type: "animate";
    alias: string | string[];
    keyframes: KeyframesType<T>;
    options?: AnimationOptions;
    priority?: UPDATE_PRIORITY;
};
type PixiVNJsonAnimateSequence<T extends CanvasBaseInterface<any>> = {
    type: "animate-sequence";
    alias: string;
    sequence: (ObjectSegment<T> | ObjectSegmentWithTransition<T>)[];
    options?: SequenceOptions;
    priority?: UPDATE_PRIORITY;
};
type PixiVNJsonCanvasAnimate<T extends CanvasBaseInterface<any> = ImageSprite> = PixiVNJsonAnimateBase<T> | PixiVNJsonAnimateSequence<T>;

type PixiVNJsonEffectShake = {
    type: "shake";
    alias: string;
    props: ShakeEffectProps;
    priority?: UPDATE_PRIORITY;
};
type PixiVNJsonCanvasEffect = PixiVNJsonEffectShake;

/**
 * @deprecated
 */
type PixiVNJsonTickerFade = {
    type: "fade";
    alias: string | string[];
    duration?: number;
    props: FadeAlphaTickerProps;
    priority?: UPDATE_PRIORITY;
};
/**
 * @deprecated
 */
type PixiVNJsonTickerMove = {
    type: "move";
    alias: string | string[];
    duration?: number;
    props: MoveTickerProps;
    priority?: UPDATE_PRIORITY;
};
/**
 * @deprecated
 */
type PixiVNJsonTickerRotate = {
    type: "rotate";
    alias: string | string[];
    duration?: number;
    props: RotateTickerProps;
    priority?: UPDATE_PRIORITY;
};
/**
 * @deprecated
 */
type PixiVNJsonTickerZoom = {
    type: "zoom";
    alias: string | string[];
    duration?: number;
    props: ZoomTickerProps;
    priority?: UPDATE_PRIORITY;
};
/**
 * @deprecated
 */
type PixiVNJsonCanvasTicker = PixiVNJsonTickerFade | PixiVNJsonTickerMove | PixiVNJsonTickerRotate | PixiVNJsonTickerZoom;

type DissolveTransition = {
    type: "dissolve";
    props?: ShowWithDissolveTransitionProps;
    priority?: UPDATE_PRIORITY;
};
type FadeTransition = {
    type: "fade";
    props?: ShowWithFadeTransitionProps;
    priority?: UPDATE_PRIORITY;
};
type MoveInOutTransition = {
    type: "movein" | "moveout";
    props?: MoveInOutProps;
    priority?: UPDATE_PRIORITY;
};
type ZoomInOutTransition = {
    type: "zoomin" | "zoomout";
    props?: ZoomInOutProps;
    priority?: UPDATE_PRIORITY;
};
type PushInOutTransition = {
    type: "pushin" | "pushout";
    props?: PushInOutProps;
    priority?: UPDATE_PRIORITY;
};
type PixiVNJsonMediaTransiotions = DissolveTransition | FadeTransition | MoveInOutTransition | ZoomInOutTransition | PushInOutTransition;

type PixiVNJsonCanvasImageVideoShow = {
    type: "image" | "video";
    operationType: "show";
    alias: string;
    /**
     * The url of the image or video.
     * If the url is not provided, the url will be set to the alias.
     */
    url?: string;
    props?: ImageSpriteOptions;
    transition?: PixiVNJsonMediaTransiotions;
};
type PixiVNJsonCanvasImageContainerShow = {
    type: "imagecontainer";
    operationType: "show";
    alias: string;
    urls: string[];
    props?: ImageContainerOptions<ImageSprite>;
    transition?: PixiVNJsonMediaTransiotions;
};
type PixiVNJsonImageEdit = {
    type: "image";
    operationType: "edit";
    alias: string;
    props?: Partial<ImageSpriteMemory>;
};
type PixiVNJsonVideoEdit = {
    type: "video";
    operationType: "edit";
    alias: string;
    props?: Partial<VideoSpriteMemory>;
};
type PixiVNJsonImageContainerEdit = {
    type: "imagecontainer";
    operationType: "edit";
    alias: string;
    props?: Partial<ImageContainerMemory>;
};
type PixiVNJsonUnknownEdit<T extends ContainerOptions> = {
    type: "canvaselement";
    operationType: "edit";
    alias: string;
    props?: Partial<T>;
};
type PixiVNJsonCanvasRemove = {
    type: "image" | "video" | "imagecontainer" | "canvaselement";
    operationType: "remove";
    alias: string;
    transition?: PixiVNJsonMediaTransiotions;
};
type PixiVNJsonVideoPauseResume = {
    type: "video";
    operationType: "pause" | "resume";
    alias: string;
};
type PixiVNJsonAssetsLoad = {
    type: "assets" | "bundle";
    operationType: "load" | "lazyload";
    aliases: string[];
};
type PixiVNJsonCanvasShow = PixiVNJsonCanvasImageContainerShow | PixiVNJsonCanvasImageVideoShow;
type PixiVNJsonCanvasEdit = PixiVNJsonImageEdit | PixiVNJsonVideoEdit | PixiVNJsonImageContainerEdit | PixiVNJsonUnknownEdit<ImageSpriteMemory | VideoSpriteMemory | ContainerMemory>;
type PixiVNJsonCanvas = PixiVNJsonCanvasShow | PixiVNJsonCanvasEdit | PixiVNJsonCanvasRemove | PixiVNJsonVideoPauseResume | PixiVNJsonAssetsLoad | PixiVNJsonCanvasTicker | PixiVNJsonCanvasAnimate | PixiVNJsonCanvasEffect;

type PixiVNJsonInputRequest = {
    type: "input";
    operationType: "request";
    valueType?: string;
    defaultValue?: any;
};
type PixiVNJsonInput = PixiVNJsonInputRequest;

type PixiVNJsonSoundPlay = {
    type: "sound";
    operationType: "play";
    alias: string;
    props?: SoundPlayOptions;
};
type PixiVNJsonSoundRemove = {
    type: "sound";
    operationType: "stop";
    alias: string;
};
type PixiVNJsonSoundPauseResume = {
    type: "sound";
    operationType: "pause" | "resume";
    alias: string;
};
type PixiVNJsonSoundVolume = {
    type: "sound";
    operationType: "volume";
    alias: string;
    value: number;
};
type PixiVNJsonSound = PixiVNJsonSoundPlay | PixiVNJsonSoundRemove | PixiVNJsonSoundPauseResume | PixiVNJsonSoundVolume;

type PixiVNJsonOperationString = {
    type: "operationtoconvert";
    values: (string | PixiVNJsonValueGet | PixiVNJsonConditionalStatements<string | PixiVNJsonValueGet>)[];
};
type PixiVNJsonOperation = PixiVNJsonValueSet | PixiVNJsonCanvas | PixiVNJsonSound | PixiVNJsonInput;
type PixiVNJsonConditionalOperation = PixiVNJsonOperation | PixiVNJsonIfElse<PixiVNJsonOperation> | PixiVNJsonOperationString;

type PixiVNJsonChoice = {
    /**
     * The text to be displayed.
     */
    text: PixiVNJsonDialogText;
    /**
     * The label id to be opened.
     */
    label: string;
    /**
     * Label opening mode
     */
    type: LabelRunModeType;
    /**
     * The properties to be passed to the label.
     */
    props: StorageObjectType;
    /**
     * If this is true, the choice can only be made once.
     */
    oneTime?: boolean;
    /**
     * If this is true, the choice can see only if there are no other choices. For example, all choices are one-time choices and they are already selected.
     */
    onlyHaveNoChoice?: boolean;
    /**
     * If this is true and if is the only choice, it will be automatically selected, and call/jump to the label.
     */
    autoSelect?: boolean;
};
type PixiVNJsonChoices = (PixiVNJsonChoice | PixiVNJsonConditionalStatements<PixiVNJsonChoice>)[];
type PixiVNJsonDialogText = string | PixiVNJsonValueGet | PixiVNJsonConditionalStatements<string | PixiVNJsonValueGet | string[]> | (string | PixiVNJsonValueGet | PixiVNJsonConditionalStatements<string | PixiVNJsonValueGet | string[]>)[];
type PixiVNJsonDialog<Text = string> = {
    /**
     * The character id that will speak.
     */
    character: string;
    /**
     * The text to be displayed.
     */
    text: Text;
} | Text;
type PixiVNJsonLabelToOpen<T extends {} = {}> = {
    /**
     * The id of the label to open.
     */
    label: string | PixiVNJsonValueGet;
    /**
     * Label opening mode
     */
    type: LabelRunModeType;
    /**
     * The properties to be passed to the label. if you don't want to pass a object, but a list of parameters, you can use the {@link PixiVNJsonLabelToOpen.params} attribute.
     */
    props?: StepLabelPropsType<T>;
    /**
     * **It is not recommended to use it, use it only if necessary**. The parameters to be passed to the label. If you want to pass an object, use the {@link PixiVNJsonLabelToOpen.props} attribute.
     * "params" attribute will be stored in the temp storage with the key: {@link PIXIVNJSON_PARAM_ID} + ({@link narration.openedLabels.length} - 1).
     */
    params?: any[];
};
/**
 * Steps of a label.
 * Order of operations:
 * 1. run all {@link PixiVNJsonLabelStep.operations}
 * 2. set {@link PixiVNJsonLabelStep.choices}, {@link PixiVNJsonLabelStep.dialogue}, {@link PixiVNJsonLabelStep.glueEnabled}
 * 3. open {@link PixiVNJsonLabelStep.labelToOpen}
 * 4. go to next step if {@link PixiVNJsonLabelStep.goNextStep} is true
 * 5. end the label if {@link PixiVNJsonLabelStep.end} is "label_end"
 */
type PixiVNJsonLabelStep = {
    operations?: PixiVNJsonConditionalOperation[];
    /**
     * Variable used to display a choice menu.
     */
    choices?: PixiVNJsonChoices | PixiVNJsonConditionalStatements<PixiVNJsonChoices>;
    /**
     * Variable used to display a dialog.
     */
    dialogue?: PixiVNJsonDialog<PixiVNJsonDialogText> | PixiVNJsonConditionalStatements<PixiVNJsonDialog<PixiVNJsonDialogText>>;
    /**
     * This variable is used to add the next dialog text into the current dialog memory.
     * This value was added to introduce Ink Glue functionality https://github.com/inkle/ink/blob/master/Documentation/WritingWithInk.md#glue
     */
    glueEnabled?: boolean | PixiVNJsonConditionalStatements<boolean>;
    /**
     * Variable used to open a label.
     */
    labelToOpen?: PixiVNJsonLabelToOpen | PixiVNJsonConditionalStatements<PixiVNJsonLabelToOpen> | (PixiVNJsonLabelToOpen | PixiVNJsonConditionalStatements<PixiVNJsonLabelToOpen>)[];
    /**
     * If is true, the next step will be executed automatically.
     */
    goNextStep?: boolean | PixiVNJsonConditionalStatements<boolean>;
    /**
     * Variable used to end some elements of the narrative.
     * - game_end: ends the game
     * - label_end: ends the label
     */
    end?: "game_end" | "label_end" | PixiVNJsonConditionalStatements<"game_end" | "label_end">;
    conditionalStep?: PixiVNJsonConditionalStatements<PixiVNJsonLabelStep | PixiVNJsonLabelStep[]>;
};

/**
 * Collection of labels to be used in the narrative.
 */
type PixiVNJsonLabels = {
    [labelId: string]: PixiVNJsonLabelStep[];
};

/**
 * PixiVNJson It can be defined as a programming language to write a narrative written in json.
 */
interface PixiVNJson {
    /**
     * The operations to be executed before the narrative starts.
     * For the set storage: They will be set only if there are no variables with the same key already.
     * For the det tempstorage: if there are variables with the same key already, they will be overwritten.
     */
    initialOperations?: PixiVNJsonConditionalOperation[];
    /**
     * The labels to be used in the narrative. They will be added to the system
     */
    labels?: PixiVNJsonLabels;
}

type LabelJsonOptions = {
    /**
     * Function that converts a string to a {@link PixiVNJsonOperation}.
     * If is a special operation you can return undefined and can run the operation.
     */
    operationStringConvert?: (value: string, step: PixiVNJsonLabelStep, props: StepLabelPropsType$1 | {}) => Promise<PixiVNJsonOperation | undefined>;
    /**
     * If true and a dialog is empty or has only spaces, {@link PixiVNJsonLabelStep.goNextStep} will be set to true.
     */
    skipEmptyDialogs?: boolean;
};
declare class LabelJson<T extends {} = {}> extends LabelAbstract<LabelJson<T>, T> {
    /**
     * @param id is the id of the label
     * @param steps is the list of steps that the label will perform
     * @param props is the properties of the label
     */
    constructor(id: string, steps: (PixiVNJsonLabelStep | (() => PixiVNJsonLabelStep))[], props?: LabelProps<LabelJson<T>>, options?: LabelJsonOptions);
    private _steps;
    get steps(): StepLabelType<T>[];
    get stepCount(): number;
    getStepById(stepId: number): StepLabelType<T> | undefined;
    private operationStringConvert?;
    private skipEmptyDialogs;
    getStepSha(index: number): string | undefined;
    private getDialogueText;
    private getDialogue;
    private getChoices;
    private stepConverter;
}

/**
 * Import a Pixi'VN JSON to the system.
 * This feature was created to give other developers the ability to create tools that can generate Pixi'VN labels or that generate Pixi'VN after extracting information from a programming language designed for writing narratives.
 * @param values The Pixi'VN JSON to be imported
 * @returns
 */
declare function importPixiVNJson(values: PixiVNJson | string | (PixiVNJson | string)[], options?: LabelJsonOptions): Promise<void>;

export { LabelJson, importPixiVNJson };
