import { PredefinedVariableName, VariableType } from "../definitions/variables/VariableTypes";
import { RecordFactory } from "../R/RecordFactory";
import { ClipboardR, RecordMap, RecordNode } from "../R/RecordNode";
import { RT } from "../R/RecordTypes";
import { fn } from "../definitions";
import { ElementType } from "../definitions/elements/ElementDefinition";
import { SceneType } from "../definitions/special";
type variable = RT.variable;
declare const variable = RT["variable"];
/**
 * @example
 * projectFactory1  = r.project(projectJson): ProjectFactory
 * project1         = r.project(projectJson).json(): RecordNode<project> (project1 === projectJson)
 *
 * Add Scene:
 * t.project(projectJson).addScene(scene1Json).json(): RecordNode<scene>
 */
export declare class ProjectFactory extends RecordFactory<RT.project> {
    constructor(json: RecordNode<RT.project>);
    /**
     * addBlankRecord calls addRecord internally. So just overriding addRecord is enough.
     *
     * Override adding of scene -
     *   Also add scene_id to the menu in case auto_add_new_scene_to_menu is true
     * Override adding of lead_gen_field -
     *   All lead gen fields need a corresponding variable in which its value is saved
     *   The corresponding variable is saved in the field var_id (of type string) in lead_gen_field
     *   These variable definitions (like name/type) shouldn't be modifiable by the user (read only = true)
     */
    addRecord<N extends RT>(this: ProjectFactory, record: RecordNode<N>, position?: number): RecordNode<N>;
    /**
     * Adding custom logic for:
     * lead_gen_field: Renaming lead_gen_field should rename the linked variable name
     */
    changeRecordName<N extends RT>(this: ProjectFactory, type: N, id: number, newName?: string): RecordNode<N> | undefined;
    addElementOfTypeToScene(this: ProjectFactory, { sceneId, elementType, position, groupElementId }: {
        sceneId: number;
        elementType: ElementType;
        position?: number;
        groupElementId?: number;
    }): RecordNode<RT.element> | undefined;
    /**
     * Updated version of addSceneSubRecord
     * Takes in groupElementId to add record to nth level as well.
     */
    addSceneDeepRecord<N extends RT>(this: ProjectFactory, { sceneId, record, position, groupElementId }: {
        sceneId: number;
        record: RecordNode<N>;
        position?: number;
        groupElementId?: number;
    }): RecordNode<N> | undefined;
    /**
     * Ideally elements should be renamed via SceneFactory. But because want media_upload element rename to impact
     * its linked variable, we do this via ProjectFactory (as only ProjectFactory has access to variables).
     */
    changeSceneSubRecordName<N extends RT>(this: ProjectFactory, sceneId: number, type: N, id: number, newName?: string): RecordNode<N> | undefined;
    /**
     * Ideally elements should get deleted via SceneFactory. But because we want deletion of media_upload element to delete the linked
     * variable, we do this via ProjectFactory (as only ProjectFactory has access to variables).
     */
    deleteSceneDeepRecord<N extends RT>(this: ProjectFactory, sceneId: number, type: N, id: number): RecordNode<N> | undefined;
    /**
     * Update from previous function.
     * This has been written in Project Factory so that we can add linked variables to elements like SCORM and Media Upload
     * since only Project Factory has access to variables.
     */
    duplicateSceneDeepRecord<N extends RT>(this: ProjectFactory, sceneId: number, type: N, id: number): RecordNode<N> | undefined;
    /**
     * Override from record factory
     * Since only Project Factory has access to variables, get the deep records in the override and add the linked variables for SCORM and Media Upload.
     */
    duplicateDeepRecord<N extends RT>(this: ProjectFactory, type: N, id: number): RecordNode<N> | undefined;
    /**
     * Adding custom logic for:
     * variable: Deleting a variable should also delete its rules
     * scene: Should delete from menu and tour_mode lists also
     * lead_gen_field: Should delete the linked autogenerated variable
     */
    deleteRecord<N extends RT>(this: ProjectFactory, type: N, id: number): RecordNode<N> | undefined;
    /**
     * Override general variable defaults with the defaults specified for the given variableType
     */
    addVariableOfType(this: ProjectFactory, variableType: VariableType, id?: number): RecordNode<variable>;
    /**
     * Variables linked to specific functions, that need specific fixed ids (and names)
     * Predefined variables cannot be renamed or delted by the user, and are not shown on Variables interface
     */
    addPredefinedVariable(this: ProjectFactory, predefinedVariableName: PredefinedVariableName): RecordNode<variable>;
    addGlobalVariable(this: ProjectFactory, globalVar: RecordNode<RT.variable>): RecordNode<variable> | undefined;
    /**
     * This needs to be done everytime before the project is loaded in the editor.
     * Because the definitions of the global vars might get updated anytime.
     */
    updateGlobalVariableProperties(this: ProjectFactory, gvsMap: RecordMap<RT.variable>): void;
    /**
     * Function to be used to add linked variables for element types like SCORM and Media Upload.
     * Just need to update this function for any other element type to be added in future
     * Takes the elements as an array and adds variables to project factory
     */
    addLinkedVariables<N extends RT>(this: ProjectFactory, records: RecordNode<N>[]): void;
    /**
     * Function to be used to delete linked variables for element types like SCORM and Media Upload.
     * Just need to update this function for any other element type to be added in future
     * Takes the elements as an array and deletes variables from project factory
     */
    deleteLinkedVariables<N extends RT>(this: ProjectFactory, records: RecordNode<N>[]): void;
    getInitialSceneId(this: ProjectFactory): number;
    addMenuAndTourModeRecord(this: ProjectFactory, sceneId: number): void;
    /**
     * Note: A thumbnail is different form logo.
     * Logo is displayed above clickToStart. Can be the org logo for example.
     * Thumbnail shows is displayed in project listing page. Can be distinguish the project visually.
     *
     * Temporary until a full-fledged thumbnail generator is created
     * Works only on projects that have gone through "injectSourceIntoProject" (i.e. its source.file_urls are populated)
     * This just gets the first scene of the project and returns the thubmnail of the first pano it finds in it
     */
    getProjectThumbnail(this: ProjectFactory): string | undefined;
    getFileIdsFromProject(this: ProjectFactory): number[];
    injectSourceIntoProject(this: ProjectFactory, sourceMap: {
        [id: number]: fn.Source;
    }): void;
    getMetadata(this: ProjectFactory): string[];
    /**
     * Scene copy logic:
     * In scene rules, vars can be referenced via ids or via variable names (in templates used in elements)
     * Copy all variables referenced.
     * @param ids - list of ids for child records
     */
    copyToClipboardObject(this: ProjectFactory, ids: number[]): ClipboardR;
    /**
     * Variable paste logic: [FYI: Variables only get copied when a scene(s) is using them]
     * For EACH variable which was copied
     * - If the variable id and name doesn't exist - paste it (1)
     * - If the variable id exists, but name doesn't - ignore it. (2) (To make this work, we need to go to each string template used in rules
     * and elements in the new scene, and change the templates to use the new name)
     * - If the variable id doesn't exist, but name does (3) - replace the variable id in the new scene being pasted (in all rules)
     * with the new variable id
     * - If both the variable id and name exist - ignore it (4)
     * @param obj
     * @param position
     */
    pasteFromClipboardObject(this: ProjectFactory, { obj, position, groupElementId, sceneId }: {
        obj: ClipboardR;
        position?: number;
        groupElementId?: number;
        sceneId?: number;
    }): void;
    getAllRecordsForLinkedVariables(this: ProjectFactory, records: RecordNode<RT>[]): RecordNode<RT.element>[];
    /**
     * Overriding this function from base class as there is element specific code.
     * Check base class implementation for reference on function usage and examples
     */
    reParentRecordsWithAddress(this: ProjectFactory, destParentAddr: string, sourceRecordAddr: {
        parentAddr: string;
        recordAddr: string;
    }[], destPosition?: number): [RecordNode<RT>[], RecordNode<RT>[]];
    /**
     * Get Address for a deep record in a particular scene, also has the capability to attach parent address
     * If you want the full address for an element (might be a duplicate => there might be two elements with same ID but in different scenes)
     * send scene id (scene in which the element is present) and parent address (project address) => can be found via projectF.getSelfRecordAddress()
     *
     * If just the scene Id is provided => the address will be starting from the scene instead of the project.
     * If neither scene Id or parent address is provided => the full address will be returned but might be from a different scene
     */
    getDeepChildRecordAddress(this: ProjectFactory, { id, type, sceneId, parentAddr }: {
        id: number;
        type: RT;
        sceneId?: number;
        parentAddr?: string;
    }): string | undefined;
    /**
     * This method is called from the UI to resolve inconsistencies in the menu records.
     * It is called only if the number of menu entries != number of scene entries
     */
    syncMenuWithScenes(this: ProjectFactory): void;
}
export declare class ProjectUtils {
    ruleNamesDict: {
        [key: string]: number[];
    };
    accentColorsDict: {
        [key: string]: number[];
    };
    elementNamesDict: {
        [key: string]: number[];
    };
    variableNamesDict: {
        [key: string]: number[];
    };
    propsNameDict: {
        [key: string]: number[];
    };
    actionDict: {
        [key: string]: number[];
    };
    eventsDict: {
        [key: string]: number[];
    };
    constructor();
    buildRulesDictionary: (project: RecordNode<RT.project>, sceneId: number) => void;
    simpleSearchInRules({ searchString, accentColor }: {
        searchString: string;
        accentColor?: string;
    }): number[];
    /**
     * Returns all records in a project that use string templating.
     * Generally, string templating is used in
     * 1. Text elements
     * 2. EmbedHTML elements
     * 3. Rules -> then_action with `open_url` action
     */
    static getAllTemplatedRecords(project: RecordNode<RT.project>): RecordNode<RT.element | RT.then_action>[];
    /**
     * Given the records from getAllTemplatedRecords, this function actually replaces the older variable name
     * with the newer variable name in all the properties of the records that hold string templates
     */
    static updateStringTemplates(records: RecordNode<RT>[], oldVarName: string, newVarName: string): void;
    static addNewScene(project: RecordNode<RT.project>, sceneType: SceneType): void;
    static addDefaultLightRig(project: RecordNode<RT.project>, sceneId: number, envElementId?: number): void;
}
export {};
