import { FullModelOf, InitModelOf, ModelOf, TypeDescriptorOptions } from './index';
export type ObjectCreator = (model?: any) => object;
export type ObjectType<TObject = object, TModel = ModelOf<TObject>> = string | (new (model?: TModel) => TObject);
export interface ObjectFactoryOptions extends TypeDescriptorOptions {
    /**
     * Model object to be passed to the constructor or create function.
     */
    model?: object;
    /**
     * Controls if the resulting object should be assigned the attribute "id" if it is not defined.
     * If the created object has an init() function, we also set the property 'id' on the model object to allow the init() function to copy the attribute from the model to the scoutObject.
     * Default is true.
     */
    ensureUniqueId?: boolean;
}
export interface RegisterNamespaceOptions {
    /**
     * List of object names that are allowed to be replaced, see the description for the thrown error. Default is an empty array.
     */
    allowedReplacements?: string[];
}
/**
 * @singleton
 */
export declare class ObjectFactory {
    /** use {@link createUniqueId} to generate a new ID */
    uniqueIdSeqNo: number;
    protected _registry: Map<ObjectType, ObjectCreator>;
    protected _objectTypeMap: Map<new () => object, string>;
    constructor();
    static NAMESPACE_SEPARATOR: string;
    static MODEL_VARIANT_SEPARATOR: string;
    /**
     * Creates an object from the given objectType. Only the constructor is called.
     *
     * OBJECT TYPE:
     *
     * A string based object type may consist of three parts: [name.space.]Class[:Variant]
     * 1. Name spaces (optional)
     *    All name space parts have to end with a dot ('.') character. If this part is omitted, the default
     *    name space "scout." is assumed.
     *    Examples: "scout.", "my.custom.namespace."
     * 2. Scout class name (mandatory)
     *    Examples: "Desktop", "Session", "StringField"
     * 3. Model variant (optional)
     *    Custom variants of a class can be created by adding the custom class prefix after
     *    the Scout class name and a colon character (':'). This prefix is then combined with
     *    the class name.
     *    Examples: ":Offline", ":Horizontal"
     *
     * Full examples:
     *   Object type: Outline                                      -> Constructor: Outline
     *   Object type: myNamespace.Outline                          -> Constructor: myNamespace.Outline
     *   Object type: Outline:MyVariant                            -> Constructor: scout.MyVariantOutline
     *   Object type: myNamespace.Outline:MyVariant                -> Constructor: myNamespace.MyVariantOutline
     *   Object type: Outline:myNamespace.MyVariant                -> Constructor: myNamespace.MyVariantOutline
     *   Object type: myNamespace.Outline:yourNamespace.MyVariant  -> Constructor: yourNamespace.MyVariantOutline
     *
     * RESOLVING THE CONSTRUCTOR:
     *
     * When the object factory contains a create function for the given objectType, this function is called.
     *
     * Otherwise, it tries to find the constructor function by the following logic:
     * If the objectType provides a name space, it is used. Otherwise, it takes the default "scout" name space.
     * If the object type provides a variant ("Type:Variant"), the final object type is built by prepending
     * the variant to the type ("VariantType"). If no such type can be found and the option "variantLenient"
     * is set to true, a second attempt is made without the variant.
     *
     * @param objectType A class reference to the object to be created. Or a string describing the type of the object to be created.
     */
    protected _createObjectByType<T>(objectType: ObjectType<T>, options?: ObjectFactoryOptions): any;
    /**
     * Creates and initializes a new Scout object. When the created object has an init function, the
     * model object is passed to that function. Otherwise, the init call is omitted.
     *
     * @param objectTypeOrModel A class reference to the object to be created. Or a string with the requested objectType.
     *        This argument is optional, but if it is omitted, the argument "model" becomes mandatory and MUST contain a
     *        property named "objectType". If both, objectType and model, are set, the
     *        objectType parameter always wins before the model.objectType property.
     * @param modelOrOptions The model object passed to the constructor function and to the init() method.
     *        This argument is mandatory if it is the first argument, otherwise it is
     *        optional (see above). This function may set/overwrite the properties 'id' and
     *        'objectType' on the model object.
     * @throws Error if the argument list does not match the definition.
     */
    create<T extends object>(objectTypeOrModel: ObjectType<T> | FullModelOf<T>, modelOrOptions?: InitModelOf<T>, options?: ObjectFactoryOptions): T;
    /**
     * Returns a new unique ID to be used for Widgets/Adapters created by the UI
     * without a model delivered by the server-side client.
     * @returns ID with prefix 'ui'
     */
    createUniqueId(): string;
    resolveTypedObjectType(objectType: ObjectType): ObjectType;
    register(objectType: ObjectType, createFunc: ObjectCreator): void;
    unregister(objectType: ObjectType): void;
    protected _objectTypeToDebugStr(objectType: ObjectType): string;
    get(objectType: ObjectType): ObjectCreator;
    /**
     * Returns the object type as string for the given class.
     */
    getObjectType(Class: ObjectType): string;
    /**
     * Cannot init ObjectFactory until Log4Javascript is initialized.
     * That's why we call this method in the scout._init method.
     */
    init(): void;
    /**
     * The namespace is an object on the window containing object names as keys and object references as values.
     * The type of the object is not restricted, mostly it is a class but may also be a function or a plain object used as enum.
     * <p>
     * Registering classes enables creating an instance of the class by its name using the ObjectFactory (e.g. scout.create(Button, {}) ).
     * This is necessary to import string based models, e.g. if the model is delivered by a server (Scout Classic).
     * Registering objects in general is also necessary, if the application does not use EcmaScript imports or the imports are treated as externals and transpiled to a window lookup (see Webpack root external for details).
     * <p>
     * Registering the namespace also makes it possible to resolve the name of a class including its namespace for any registered class, even if the code is minified.
     * This is used by the ObjectFactory to store the objectType as string on the created object, which maintains backwards compatibility.
     *
     * @param namespace the name of the object on the window
     * @param objects the objects to be put on the namespace
     * @throws Error if the object is already registered on the namespace to avoid accidental replacements.
     *               Such replacements would not work if the object is created using a class reference because in that case the namespace is not used.
     *               If you want to force a replacement, you can allow it by using the option allowedReplacements.
     */
    registerNamespace(namespace: string, objects: object, options?: RegisterNamespaceOptions): void;
    static get(): ObjectFactory;
    protected static _set(newFactory: ObjectFactory): void;
}
//# sourceMappingURL=ObjectFactory.d.ts.map