import { FileChange, SASObjectAttachedFile, SASUploadedFile } from "../file/file-api";
import { PageEventsApiBase, PageMode, PageModel } from "../page-model/page-model-api";
import { FieldType, FieldTypeToValue } from "./data-types";
import { PageDataChange, PageModeChange, StateChange } from "./events";
import { Control, RefreshablePageControlOptions, SlidingPanelContent, SlidingPanelProperties, TypeAttributes } from "./page";
import { FieldTypeToClientFieldProperties } from "./client-field-properties";
import { FieldTypeToRestrictions, FileRestrictions } from "./restrictions";
import { AttachmentFormData } from "./file";
import { MaskingControlApi, MaskingPageApi } from "./masking-api";
/**
 * The minimum API that should be supported on control members across solutions.
 */
export interface ControlMemberApiBase<ControlTypeAttributes extends TypeAttributes = TypeAttributes, ControlFieldType extends FieldType = never> {
    /**
     * Methods related to this control.
     */
    readonly control: ControlApiBase<ControlTypeAttributes, ControlFieldType>;
    /**
     * Methods related to the entire page.
     */
    readonly page: ControlPageApiBase;
}
/**
 * {@link ControlMemberApiBase} extension that provides more functionality.
 * @extends ControlMemberApiBase
 * @category API
 */
export interface ControlMemberApi<ControlTypeAttributes extends TypeAttributes = TypeAttributes, ControlFieldType extends FieldType = any> extends ControlMemberApiBase<ControlTypeAttributes, ControlFieldType> {
    /**
     * Methods related to this control.
     */
    readonly control: ControlApi<ControlTypeAttributes, ControlFieldType>;
    /**
     * Methods related to the entire page the control is on.
     */
    readonly page: ControlPageApi;
    /**
     * Methods available when administering this control.
     */
    readonly admin: ControlAdminApi;
}
/**
 * This Control API relates to functionality that checks the state, registers event handlers, and so on.
 */
export interface ControlApiBase<ControlTypeAttributes extends TypeAttributes = TypeAttributes, ControlFieldType extends FieldType = never> {
    /**
     * Methods related to the state of the control.
     */
    readonly state: ControlStateApi;
    /** Control type. */
    readonly type: string;
    /**
     * Control Mask
     * @deprecated Use `api.control.masking.isConfiguredForMasking` instead.
     */
    isMaskedControl(): boolean;
    /**
     * Control Mask Authorization
     * @deprecated Use `api.control.masking.isAuthorizedToUnmask` instead.
     */
    isAuthorizedToUnmask(): boolean;
    /**
     * Sets the value of the control's field.
     * Field must be configured as dataSource in the control's typeAttributes.
     * @method
     * @param value {FieldTypeToValue<ControlFieldType>} New field value.
     */
    setFieldValue(value: FieldTypeToValue<ControlFieldType>): void;
    /**
     * Gives the value of the control's field.
     * Field must be configured as dataSource in the control's typeAttributes.
     * @method
     * @returns The value of the control's field.
     */
    getFieldValue(): FieldTypeToValue<ControlFieldType>;
    /**
     * Returns the formatted value of the control's field.
     * Field must be configured as dataSource in the control's typeAttributes.
     * @method
     * @returns A promise that resolves to the formatted field value, or undefined if the field is not found.
     */
    getFormattedDisplayValue(): Promise<string | undefined>;
    /**
     * Returns the client field properties that are associated with the calling control.
     * Field must be configured as dataSource in the control's typeAttributes.
     * @method
     * @returns The client field properties that should be applied.
     */
    getClientFieldProperties(): FieldTypeToClientFieldProperties<ControlFieldType> | undefined;
    /**
     * Returns the field restrictions that are associated with the calling control.
     * Field must be configured as dataSource in the control's typeAttributes.
     * @method
     * @returns The field restrictions that should be applied.
     */
    getFieldRestrictions(): FieldTypeToRestrictions<ControlFieldType>;
    /**
     * Returns the restrictions of the control's file category.
     * File category must be configured as fileCategory in the control's typeAttributes.
     * @method
     * @returns The file restrictions that should be applied.
     */
    getFileRestrictions(): FileRestrictions;
    /**
     * Returns the calling control object.
     * @method
     * @returns Object representing the calling control.
     */
    getControl(): Control<ControlTypeAttributes>;
    /**
     * Access the Control Data Masking API.
     */
    masking: MaskingControlApi;
}
/**
 * This API relates to administration functionality for controls, for example registering resources.
 *
 * @category API
 */
export interface ControlAdminApi {
    /**
     * Registers a function to be invoked when retrieving this control's internationalization resources.
     * @method
     * @param fn {function} A function that returns each internationalization resource's key and value.
     * No parameters. Return type: Record<string, string>
     */
    registerGetI18nResourcesFn(fn: () => Record<string, string>): void;
}
/**
 * Extension of {@link ControlApiBase} supplied by SAS Visual Investigator to provide more functionality.
 * @extends ControlApiBase
 * @category API
 */
export interface ControlApi<ControlTypeAttributes extends TypeAttributes = TypeAttributes, ControlFieldType extends FieldType = never> extends ControlApiBase<ControlTypeAttributes, ControlFieldType> {
    /**
     * Methods related to the state of the control.
     */
    readonly state: ControlStateApi;
    /**
     * Space for component specific API functions.
     */
    readonly component?: any;
    /**
     * Returns the calling control's parent object.
     * @method
     * @returns Object representing the calling control's parent.
     */
    getParentControl(): Control | undefined;
    /**
     * Returns the parent ancestor with the given type for this control.
     * @method
     * @param ofType {string} Type of ancestor to be returned.
     * @returns Object representing the calling control's ancestor, or undefined if no match.
     */
    getAncestorControl(ofType: string): Control | undefined;
    /**
     * Returns a string that can be used as an aria label for the field, which includes its required state.
     * Uses the typeAttributes.title.text field for the label.
     * @method
     * @returns The aria label that should be applied.
     */
    getAriaLabel: () => string;
    /**
     * Sets the value of the component specific API.
     * @param componentSpecificApi
     */
    setComponentSpecificApi(componentSpecificApi?: any): void;
}
/**
 * Methods and properties related to the state of the control.
 *
 * @category API
 */
export interface ControlStateApi {
    /**
     * Returns the read-only state of the calling control.
     * True if the control is read-only, otherwise false.
     */
    readonly readOnly: boolean;
    /**
     * Returns the required state of the calling control.
     * True if control is required, otherwise false.
     */
    readonly required: boolean;
    /**
     * Checks if the current controls should allow input.
     * Returns true if the control allows input, otherwise false.
     */
    readonly allowInput: boolean;
    /**
     * Returns if this control could be read-only based on a condition.
     * True if the control could be read-only, otherwise false.
     */
    readonly couldBeReadOnly: boolean;
    /**
     * Returns if this control could be required based on a condition.
     * True if the control could be required, otherwise false.
     */
    readonly couldBeRequired: boolean;
    /**
     * Returns the hidden state of the calling control.
     * True if the control is hidden, otherwise false.
     */
    readonly hidden: boolean;
    /**
     * Returns the disabled state of the calling control.
     * True if the control is disabled, otherwise false.
     */
    readonly disabled: boolean;
    /**
     * Returns the masked state of the calling control.
     * True if the control is masked, otherwise false.
     * @deprecated Use `api.control.masking.isMasked` instead.
     */
    readonly maskActive: boolean;
    /**
     * Returns the state with a specified key.
     * @method
     * @param state {string} The key of the state to be returned.
     * @returns The specified state of the calling control, or undefined if no match.
     */
    get<T extends keyof ControlClientStates>(state: T): boolean | undefined;
    /**
     * Registers a function to be invoked whenever a state change event occurs.
     * This function receives an object that contains information about the change event.
     *
     * @method
     * @param handler {function} Function to be invoked when a state is changed.
     * Parameter (change: StateChange). Returns void.
     */
    onChange(handler: (change: StateChange) => void): void;
    /**
     * Re-evaluates the status of all control states.
     * @method
     */
    update(): void;
    /**
     * Cleans up any resources held by the ControlStateApi instance.
     * @ignore
     */
    destroy(): void;
}
/**
 * API methods related to object fields associated with a page.
 *
 * @category API
 */
export interface ControlPageFieldApi {
    /**
     * Sets the value of the supplied field.
     * This works only with fields for the current object with which the control is associated.
     * For example, if the control is on a parent object, you cannot set a child's field.
     * @method
     * @param value {FieldTypeToValue<Type>} New field value.
     * @param field {string} Field name.
     */
    setFieldValue<Type extends FieldType>(value: FieldTypeToValue<Type>, field: string): void;
    /**
     * Returns the value of the supplied field.
     * This works only with fields for the current object with which the control is associated.
     * For example, if the control is on a parent object, you cannot get a child's field.
     * @method
     * @template {FieldType} File type.
     * @param field {string} Field name.
     */
    getFieldValue<Type extends FieldType>(field: string): FieldTypeToValue<Type>;
    /**
     * Returns the formatted value of the supplied field.
     * This works only with fields for the current object with which the control is associated.
     * @method
     * @param field {string} Field name.
     * @returns A promise that resolves to the formatted field value, or undefined if the field is not found.
     */
    getFormattedDisplayValue(field: string): Promise<string | undefined>;
    /**
     * Returns the client field properties that are associated with the calling control.
     * @method
     * @template {FieldType} Field type.
     * @param field {string} Field name to get client field properties for.
     * @returns Configured client field properties.
     */
    getClientFieldProperties<Type extends FieldType>(field: string): FieldTypeToClientFieldProperties<Type> | undefined;
    /**
     * Returns the field restrictions that are associated with the calling control.
     * @method
     * @template {FieldType} Field type.
     * @param field {string} Field name to get restrictions for.
     * @returns Applied field restrictions.
     */
    getFieldRestrictions<Type extends FieldType>(field: string): FieldTypeToRestrictions<Type>;
}
/**
 * Methods related to the page to which a control belongs.
 * @class
 */
export interface ControlPageApiBase {
    /**
     * Methods related to files associated with the page.
     */
    readonly file: ControlFileApiBase;
    /**
     * The object ID. Returns an empty string ("") if not applicable.
     */
    readonly objectId: string;
    /**
     * The object name. Returns an empty string ("") if not applicable.
     */
    readonly objectName: string;
    /**
     * Checks if the object is external.
     */
    readonly isExternalObject: boolean;
    /**
     * Checks if the page is a Home page.
     */
    readonly isHomepage: boolean;
    /**
     * Returns the mode of the page on which the calling control resides.
     * @method
     * @returns The current PageMode.
     */
    getMode(): PageMode;
    /**
     * Methods that relate to object fields associated with the page.
     */
    readonly field: ControlPageFieldApi;
    /**
     * Registers a function to be invoked whenever a relevant change happens.
     * The handler receives an object that gives information about the change event.
     * There are two types of changes -
     *    PageDataChange when the data in the page model changes,
     *    and PageModeChange when the page mode changes.
     * @method
     * @param handler {function} Function to be invoked when there is a change.
     * Parameter (change) is of type PageDataChange or PageModeChange.
     * Returns void.
     */
    onChange(handler: (change: PageDataChange | PageModeChange) => void): void;
}
/**
 * {@link ControlPageApiBase} extension that provides more functionality.
 * @extends ControlPageApiBase
 * @category API
 */
export interface ControlPageApi extends ControlPageApiBase {
    /**
     * Methods related to the files associated with the page.
     */
    file: ControlFileApi;
    /**
     * Methods related to the hookable events associated with the page.
     */
    events: ControlPageEventsApi;
    /**
     * Returns the model of the page in which the calling control resides.
     * @method
     * @returns The current page model object.
     */
    getPageModel(): PageModel;
    /**
     * Registers a function to be invoked whenever one of the calling control's properties change.
     * @method
     * @param handler {function} Function to be invoked on property change.
     * Parameters are (category: string, property: string, currentValue: any, previousValue: any).
     * @returns A function that stops the handler from being invoked.
     */
    onPropertyChange(handler: (category: string, property: string, currentValue: any, previousValue: any) => void): () => void;
    /**
     * Returns the disabled status of the page toolbar.
     * @method
     * @returns True, if the toolbar is disabled. Otherwise false.
     */
    isToolbarDisabled(): boolean;
    /**
     * Sets the toolbar control to be disabled.
     * @param {string} actionName the toolbar action name.
     * @param {boolean} setDisabled disable the toolbar item.
     * @method
     */
    setToolbarItemDisabled(actionName: string, setDisabled: boolean): void;
    /**
     * Triggers a certain type of notification for users.
     * For example, a type EDIT_FAIL notification if a sheet has failed to be added to a workspace.
     * @method
     * @param notification {string} Message to be displayed on the notification.
     * @param type {string} Type of notification. For example LOCK, EDIT_FAIL, VERSION_MISMATCH.
     * @param [autoDismissDuration] {number} Length of time before the notification should be dismissed.
     */
    raiseNotification(notification: string, type: string, autoDismissDuration?: number): void;
    /**
     * Adds a refreshable control to the page.
     * @method
     * @param control {Control} Control to add.
     * @param refreshFn {function} Function to be called when the control is refreshed. There are no parameters. Returns void.
     * @param [options] {RefreshablePageControlOptions} Options to be added to the refreshable control.
     */
    addRefreshableControl(control: Control, refreshFn: () => void, options?: RefreshablePageControlOptions): void;
    /**
     * Removes a refreshable control from the page.
     * @method
     * @param controlToRemove {Control} Control to be removed.
     */
    removeRefreshableControl(controlToRemove: Control): void;
    /**
     * Refreshes a control when updated data is displayed.
     * By default, attempts to refresh all controls.
     * Specify categoryToRefresh or controlToRefresh to restrict what is refreshed.
     * @method
     * @param [categoryToRefresh] {(string|undefined)} Name of the category to be refreshed.
     * @param [controlToRefresh] {Control} Individual control to be refreshed.
     */
    reloadRefreshableControls(categoryToRefresh?: string, controlToRefresh?: Control): void;
    /**
     * @method
     * @returns True if any RefreshableControls have options.requiresIndex present. Otherwise, false.
     */
    hasAnyRefreshableControlRequiresIndex(): boolean;
    /**
     * Sets a page to be dirty, that is, when it has been edited and not saved.
     * @method
     */
    setPageDirty(): void;
    /**
     * Gets the dirty state of the page.
     * @method
     */
    getPageDirty(): boolean | undefined;
    /**
     * Toggle the page-level sliding panel. This panel should be used to contain information that is
     * supplementary to the document, for example attachments or workflow tasks.
     * @method
     * @param [sectionLabel] {string} Describes the section; this should be internationalized.
     * @param [content] {SlidingPanelContent} The content of the sliding panel.
     * @param [panelProperties] {SlidingPanelProperties} Properties for the panel.
     *      When providing a URL for content: the panel properties will be available on the controller's "slidingPanel" object.
     *      When providing a selector for content: the properties will be set on the element to be created.
     * @param [onClose] {function} A callback function invoked when the panel is dismissed. There are no parameters. Returns void.
     * @param [focusPreviousActiveElementOnClose] {boolean} Toggle for whether the app should apply focus to the last active element before the panel was opened.
     */
    toggleSlidingPanel<T>(sectionLabel?: string, content?: SlidingPanelContent<T>, panelProperties?: SlidingPanelProperties, onClose?: () => void, focusPreviousActiveElementOnClose?: boolean): void;
    /**
     * Checks if a page is in edit mode.
     * @method
     * @returns A boolean value that checks if a page is in edit mode. Undefined if there is no page model.
     */
    isInEditMode(): boolean | undefined;
    /**
     * Takes a page out of edit mode. Promise resolves with a boolean value to determine if the user has saved or not.
     * If the user has not saved, the user is prompted to do so.
     * @method
     * @param closeTab {boolean} Checks if the tab should close after edit mode is canceled.
     * @returns A Promise that resolves when the edit has been canceled.
     */
    cancelEdit(closeTab: boolean): Promise<{
        userSaved: boolean;
    }>;
    /**
     * Sets the page to be in edit mode. Used when clicking the Edit button.
     * @method
     * @returns A Promise that resolves when the page is put in edit mode.
     */
    edit(): Promise<any>;
    /**
     * Refreshes the attachments grid to display new attachments when a new attachment is uploaded.
     * @method
     */
    refreshAttachments(): void;
    /**
     * Reloads an instance of a page.
     * @method
     * @returns A Promise that resolves when the page is reloaded.
     */
    reloadPage(): Promise<void>;
    /**
     * Saves a page after editing.
     * @method
     * @param stopEditing {boolean} Checks if the page should leave edit mode after it is saved.
     * @param closeObject {boolean} Checks if the page should be closed after it is saved.
     * @returns A Promise that resolves when the page has been saved.
     */
    save(stopEditing: boolean, closeObject: boolean): Promise<void>;
    /**
     * Access the Page Data Masking API.
     */
    masking: MaskingPageApi;
    /**
     * Register a callback function that is invoked when the page that contains the current control is navigated back to.
     * Useful for updating homepage controls whose config sets "reuse" to true and need to update when the homepage is reloaded.
     * @method
     * @param callback {function} The function to be invoked.
     */
    onNavigationStart(callback: () => void): void;
    /**
     * Checks if the sliding panel is pinned.
     * @returns A boolean value that checks whether the sliding panel is pinned.
     */
    isSlidingPanelPinned(): boolean | undefined;
    /**
     * Gives whether a loading mask is shown for the page.
     * This loading mask is shown when the page is saving or a disposition is in progress.
     */
    isLoadingMaskShown(): boolean;
}
/**
 * Methods related to files.
 */
export interface ControlFileApiBase {
    /**
     * Returns the restrictions of the control's file category.
     * @method
     * @param [category] {string} Get restrictions for the file category name.
     * @returns The file restrictions that should be applied.
     */
    getFileRestrictions(category: string): FileRestrictions;
}
/**
 * {@link ControlFileApiBase} extension that provides more functionality.
 * @extends ControlFileApiBase
 * @category API
 */
export interface ControlFileApi extends ControlFileApiBase {
    /**
     * Opens the file upload dialog box.
     *
     * @method
     * @param {IAttachmentFormData} options Additional options to pass to the file upload dialog box.
     * @returns {Promise<SASObjectAttachedFile[]>} Promise that resolves to an array of uploaded files.
     */
    openFileUploadDialog(options: AttachmentFormData): Promise<SASObjectAttachedFile[]>;
    /**
     * Opens the image upload dialog box.
     *
     * @method
     * @param {boolean} allowMultiple Determines if multiple files can be uploaded at once.
     * @param {number} [maxSize=] Maximum size of the image to be uploaded, in bytes.
     * @returns {Promise<SASObjectAttachedFile[]>} A Promise that resolves to an array of uploaded files.
     */
    openImageUploadDialog(allowMultiple: boolean, maxSize?: number): Promise<SASObjectAttachedFile[]>;
    /**
     * Returns all saved and unsaved files associated with the current object.
     *
     * @method
     * @param {string} [category=] An optional file category to filter by.
     * @returns {Promise<SASObjectAttachedFile[]>} A Promise that resolves to an array of files.
     */
    getFiles(category?: string): Promise<SASObjectAttachedFile[]>;
    /**
     * Creates a file operation to upload a new file.
     *
     * @method
     * @param {SASUploadedFile} file The new file to upload.
     * @returns {Promise<void>} A Promise that resolves when the file operation has been created.
     */
    addFile(file: SASUploadedFile): Promise<void>;
    /**
     * Creates a file operation to update a given file.
     *
     * @method
     * @param {SASUploadedFile} updatedFile The updated file.
     * @returns {Promise<void>} A Promise that resolves when the file operation has been created.
     */
    updateFile(updatedFile: SASUploadedFile): Promise<void>;
    /**
     * Creates a file operation to remove a file with a given ID.
     *
     * @method
     * @param {string} id The ID of the file to remove.
     * @returns {Promise<void>} A Promise that resolves when the file operation has been created.
     */
    removeFile(id: string): Promise<void>;
    /**
     * Registers a function to be invoked whenever a file change event occurs.
     * This function receives an object that contains information about the change event.
     *
     * @method
     * @param {Function} handler A function to be invoked when a file change event occurs.
     */
    onChange(handler: (change: FileChange) => void): void;
}
/**
 * Equivalent to {@link PageEventsApiBase} with the exception that event hooks will be scoped to the page on which the calling control resides.
 * @extends PageEventsApiBase
 */
export type ControlPageEventsApi = PageEventsApiBase;
export interface FieldNotOnPageError {
    name: "FieldNotOnPageError";
    message: string;
    fields: string[];
}
/**
 * Represents the client states of a control.
 */
export interface ControlClientStates {
    /**
     * Indicates if the control is required.
     */
    required: boolean;
    /**
     * Indicates if the control is read-only.
     */
    readOnly: boolean;
    /**
     * Indicates if the control is hidden.
     */
    hidden: boolean;
    /**
     * Indicates if the control allows input.
     */
    allowInput: boolean;
    /**
     * Indicates if the control could potentially be read-only
     */
    couldBeReadOnly: boolean;
    /**
     * Indicates if the control could potentially be required
     */
    couldBeRequired: boolean;
    /**
     * Indicates if the control is disabled.
     */
    disabled: boolean;
    /**
     * Indicates if the control has masking active.
     * @deprecated Use `api.control.masking.isMasked` instead.
     */
    maskActive: boolean;
    /**
     * A dynamic map of additional states, where the key is the state name and the value is a boolean.
     */
    [state: string]: boolean;
}
