import { FdLanguageKeyIdentifier } from '@fundamental-ngx/i18n';
import * as i0 from '@angular/core';
import { AfterViewInit, OnInit, OnDestroy, OnChanges, EventEmitter, QueryList, ElementRef, ChangeDetectorRef, SimpleChanges } from '@angular/core';
import { CarouselDirective, CarouselItemDirective, CarouselConfig, PanEndOutput } from '@fundamental-ngx/core/carousel';
import { Nullable } from '@fundamental-ngx/cdk/utils';
import { ControlValueAccessor } from '@angular/forms';
import { DatetimeAdapter } from '@fundamental-ngx/core/datetime';
import { ContentDensityObserver } from '@fundamental-ngx/core/content-density';

interface TimeColumnConfig {
    decreaseLabel: FdLanguageKeyIdentifier;
    increaseLabel: FdLanguageKeyIdentifier;
    label: FdLanguageKeyIdentifier;
    fullLabel: FdLanguageKeyIdentifier;
    navigationInstruction: FdLanguageKeyIdentifier;
}

declare class SelectableViewItem<T> {
    /** Value of the item */
    value: T;
    /** Label of the item */
    label: string;
    /** Index of the item */
    index?: number;
}
declare const enum Meridian {
    AM = "AM",
    PM = "PM"
}

interface TimeColumnItemOutput<T> {
    value: T;
    after?: boolean;
}
declare class TimeColumnComponent<K extends number, T extends SelectableViewItem<K> = SelectableViewItem<K>> implements AfterViewInit, OnInit, OnDestroy, OnChanges {
    private _changeDetRef;
    private _elmRef;
    /** items in row */
    rows: T[];
    /**
     * @Input When set to false, hides the buttons that increment
     * and decrement the corresponding columns.
     */
    spinners: boolean;
    /** Currently chosen, centered time column item */
    set activeValue(activeItem: Nullable<T>);
    get activeValue(): Nullable<T>;
    /** Defines if column is active, it has impact on behavior and visual  */
    set active(value: boolean);
    get active(): boolean;
    /** Whether time column is meridian */
    meridian: boolean;
    /** Id of column, initiated with some default value */
    id: string;
    /** I18n and labels */
    timeConfig: Nullable<TimeColumnConfig>;
    /** I18n and labels */
    columnTranslationsPreset: 'seconds' | 'minutes' | 'hours' | 'period';
    /**
     * Offset for carousel directive, active item is always the first one.
     * In case of having more items in carousel than 1, middle element should be active
     */
    set offset(value: number);
    get offset(): number;
    /**
     * Quantity of the elements to be shown at the same time in column
     */
    set elementsAtOnce(value: number);
    /** Event emitted, when active item is changed, by carousel */
    activeValueChange: EventEmitter<TimeColumnItemOutput<T>>;
    /** Event emitted, when certain column is activated */
    activeStateChange: EventEmitter<void>;
    /** @hidden */
    carousel: CarouselDirective;
    /** @hidden */
    items: QueryList<CarouselItemDirective<T>>;
    /** @hidden */
    indicator: ElementRef;
    /** @hidden */
    wrapperHeight: number;
    /**
     * Time to wait in milliseconds after the last keydown before
     * focusing or selecting option based on numeric/alpha keys.
     * @hidden
     */
    typeaheadDebounceInterval: number;
    /** @hidden */
    config: CarouselConfig;
    /** @hidden */
    internalTranslationConfig: TimeColumnConfig | null;
    /** @hidden */
    get currentIndicatorId(): string;
    /** @hidden */
    get currentIndicatorValueId(): string;
    /** @hidden */
    private _elementsAtOnce$;
    /** @hidden */
    private _offset$;
    /** @hidden */
    private _active;
    /** @hidden */
    private _queryKeyDownEvent;
    /** @hidden */
    private _activeValue;
    /** @hidden */
    private _activeCarouselItem;
    /** @hidden */
    private _isDragging;
    /** @hidden */
    private _viewInit$;
    /** @hidden */
    private _resize$;
    /** @hidden */
    private _subscriptions;
    /** @hidden
     * logs numeric key inputs to set time using keyboard input.
     */
    private _keyLog;
    /** @hidden
     * Timeout variable used to set timeout for subsequent numeric key input to set time.
     */
    private _numericInputTimeout;
    /** @hidden */
    constructor(_changeDetRef: ChangeDetectorRef, _elmRef: ElementRef);
    /** @hidden */
    onItemClick(): void;
    /** @hidden */
    keyDownHandler(event: KeyboardEvent): void;
    /** @hidden */
    mouseScrollHandler(event: WheelEvent): void;
    /** @hidden */
    ngOnInit(): void;
    /** @hidden */
    ngAfterViewInit(): void;
    /** @hidde */
    ngOnChanges(changes: SimpleChanges): void;
    /** @hidden */
    ngOnDestroy(): void;
    /** @hidden */
    spinnerButtonKeyupHandle(event: KeyboardEvent, upButton?: boolean): void;
    /** @hidden */
    setValueOfActive(): void;
    /** It prevents from accidentally change the item by click event */
    handleDrag(isDragging: boolean): void;
    /** Method that handles active item change */
    activeChangedHandle(output: PanEndOutput): void;
    /** Method that changes active item and triggers carousel scroll */
    pick(item: CarouselItemDirective<T>, index: number): void;
    /** Method triggered by keyboard, or increment button */
    scrollUp(event?: MouseEvent): void;
    /** Method triggered by keyboard, or decrement button */
    scrollDown(): void;
    /** Focus on column */
    focus(): void;
    /**
     * Create id for column item
     * @param index column item index
     * @returns column item id
     * @hidden
     */
    _createColumnItemIdByIndex(index: number): string;
    /**
     * On focus callback
     * @hidden
     */
    _onFocusIndicator(): void;
    /** @hidden
     * handles alphabetical key inputs to set period.
     */
    private _alphaKeyInputHandler;
    /** @hidden
     * handles numeric key inputs to set time.
     */
    private _numericKeyInputHandler;
    /** @hidden
     * set the time for given item value. used by _numericKeyInputHandler.
     */
    private _pickTimeOnValue;
    /**
     * Method triggered by keyboard, or decrement button
     * Args:
     * item => picked carousel item, that should be centered
     * smooth => defines if transition time should be included in transform
     * emitEvent => defines if EventEmitter should be triggered by this change, set to false, when changed from outside
     * after => Defines if value was incremented/decremented, needed for hours to trigger AM/PM change
     * @hidden
     */
    private _pickTime;
    /**
     * Returns item with passed value
     * @hidden
     */
    private _getItem;
    /** @hidden */
    private _triggerCarousel;
    /**
     * Focus current indicator, which allows to handle keydown events inside column
     * @hidden
     */
    private _focusIndicator;
    /** @hidden */
    private _getValue;
    /** @hidden */
    private _setUpQuerySubscription;
    /** @hidden */
    private _setUpCarouselConfiguration;
    /** @hidden */
    private _setUpInitialValue;
    /** @hidden */
    private _updateInternalTranslationConfig;
    static ɵfac: i0.ɵɵFactoryDeclaration<TimeColumnComponent<any, any>, never>;
    static ɵcmp: i0.ɵɵComponentDeclaration<TimeColumnComponent<any, any>, "fd-time-column", never, { "rows": { "alias": "rows"; "required": false; }; "spinners": { "alias": "spinners"; "required": false; }; "activeValue": { "alias": "activeValue"; "required": false; }; "active": { "alias": "active"; "required": false; }; "meridian": { "alias": "meridian"; "required": false; }; "id": { "alias": "id"; "required": false; }; "timeConfig": { "alias": "timeConfig"; "required": false; }; "columnTranslationsPreset": { "alias": "columnTranslationsPreset"; "required": false; }; "offset": { "alias": "offset"; "required": false; }; "elementsAtOnce": { "alias": "elementsAtOnce"; "required": false; }; }, { "activeValueChange": "activeValueChange"; "activeStateChange": "activeStateChange"; }, never, never, true, never>;
}

type FdTimeActiveView = 'hour' | 'minute' | 'second' | 'meridian';
type HourViewItem = SelectableViewItem<number>;
type MinuteViewItem = SelectableViewItem<number>;
type SecondViewItem = SelectableViewItem<number>;
type MeridianViewItem = SelectableViewItem<Meridian>;
declare class TimeComponent<D> implements OnInit, OnChanges, AfterViewInit, ControlValueAccessor {
    private _changeDetectorRef;
    private _elementRef;
    private _dateTimeAdapter;
    readonly _contentDensityObserver: ContentDensityObserver;
    /**
     * @Input When set to false, uses the 24 hour clock (hours ranging from 0 to 23)
     * and does not display a period control.
     */
    meridian: boolean;
    /**
     *  @Input When set to false, does not set the input field to invalid state on invalid entry.
     */
    validate: boolean;
    /**
     * @Input when set to true, time inputs won't allow to have 1 digit
     * for example 9 will become 09
     * but 12 will be kept as 12.
     */
    keepTwoDigits: boolean;
    /**
     * @Input Disables the component.
     */
    disabled: boolean;
    /**
     * @Input When set to false, hides the input for seconds.
     */
    displaySeconds: boolean;
    /** @Input When set to false, hides the input for minutes. */
    displayMinutes: boolean;
    /**
     * When set to false, hides the input for hours
     */
    displayHours: boolean;
    /** @Input Defines if time component should be used in tablet mode */
    tablet: boolean;
    /** @Input Defines quantity of the elements, that are visible at the same time. Should be odd number */
    elementsAtOnce: number;
    /**
     * @Input An object that contains datetime representation
     */
    time: D;
    /** @Input Whether to show spinner buttons */
    spinnerButtons: boolean;
    /** @hidden */
    columns: QueryList<TimeColumnComponent<number, SelectableViewItem<number>>>;
    /**
     * The interval between selectable minutes (e.g., 1 for every minute, 5 for 5-minute intervals, 15 for 15-minute intervals).
     * Defaults to 1 (every minute).
     */
    readonly minuteStep: i0.InputSignal<number>;
    /** Active column view to iterate with */
    activeView: FdTimeActiveView;
    /**
     * @hidden
     * container for [0 - 23] hours
     */
    protected hourViewItems: HourViewItem[];
    /**
     * @hidden
     * reference to currently selected hourViewItems element
     */
    protected activeHourViewItem?: HourViewItem;
    /**
     * @hidden
     * container for [0 - 59] minutes
     */
    protected minuteViewItems: MinuteViewItem[];
    /**
     * @hidden
     * reference to currently selected minuteViewItems element
     */
    protected activeMinuteViewItem?: MinuteViewItem;
    /**
     * @hidden
     * container for [0 - 59] seconds
     */
    protected secondViewItems: SecondViewItem[];
    /**
     * @hidden
     * reference to currently selected secondViewItems element
     */
    protected activeSecondViewItem?: SecondViewItem;
    /**
     * @hidden
     * container for [am, pm] meridian values
     */
    protected meridianViewItems: MeridianViewItem[];
    /**
     * @hidden
     * reference to currently selected meridianViewItems element
     */
    protected activeMeridianViewItem?: MeridianViewItem;
    /** Offset computed signal */
    protected readonly offset: i0.Signal<number>;
    /** Offset for minutes column, adjusted for minuteStep */
    protected readonly minuteOffset: i0.Signal<number>;
    /** @hidden */
    private readonly _rtlService;
    /** @hidden */
    constructor(_changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef, _dateTimeAdapter: DatetimeAdapter<D>, _contentDensityObserver: ContentDensityObserver);
    /** @hidden */
    ngOnInit(): void;
    /** @hidden
     * Reacts only when there is meridian, time, or minuteStep input change
     */
    ngOnChanges(changes: SimpleChanges): void;
    /** @hidden */
    ngAfterViewInit(): void;
    /** @hidden */
    onChange: (value: D) => void;
    /** @hidden */
    onTouched: () => void;
    /** @hidden */
    registerOnChange(fn: (time: D) => void): void;
    /** @hidden */
    registerOnTouched(fn: any): void;
    /** @hidden */
    setDisabledState(isDisabled: boolean): void;
    /** @hidden */
    refreshColumns(): void;
    /**
     * @hidden
     * Handles meridian change.
     * This implicitly changes hours by +/- 12
     */
    handleMeridianChange(meridian: Meridian): void;
    /** @hidden */
    handleSecondChange(second: number): void;
    /** @hidden */
    handleMinuteChange(minute: number): void;
    /**
     * @hidden
     * Handles changes of displayed hour value from template.
     */
    handleHourChange(hour: number): void;
    /** @hidden */
    handleNextColumnFocus(column: FdTimeActiveView): void;
    /** @hidden */
    handlePreviousColumnFocus(column: FdTimeActiveView): void;
    /** @hidden */
    handleKeyDownEvent(event: KeyboardEvent): void;
    /** @hidden */
    writeValue(time: D): void;
    /** @hidden */
    changeActive(view: FdTimeActiveView): void;
    /** @hidden */
    isActive(view: FdTimeActiveView): boolean;
    /** @hidden */
    focusActiveColumn(): void;
    /** @hidden */
    protected _focusOut(event: FocusEvent): void;
    /**
     * Get visible time columns
     * @returns visible columns list @see {FdTimeActiveView[]}
     */
    private _getVisibleColumns;
    /**
     * Get visible columns taking into account RTL
     * @returns visible columns list @see {FdTimeActiveView[]}
     */
    private _getVisibleColumnsWithRtl;
    /** @hidden */
    private _setUpViewGrid;
    /** @hidden */
    private _setUpActiveViewItems;
    /** @hidden */
    private _constructHourViewItems;
    /** @hidden */
    private _constructMinuteViewItems;
    /** @hidden */
    private _constructSecondViewItems;
    /** @hidden */
    private _constructMeridianViewItems;
    /** @hidden */
    private _calculateActiveHourViewItem;
    /** @hidden */
    private _calculateActiveMinuteViewItem;
    /** @hidden */
    private _calculateActiveSecondViewItem;
    /** @hidden */
    private _calculateActiveMeridianViewItem;
    /**
     * @hidden
     * Model hours (0 - 23)
     */
    private _getModelHour;
    /**
     * @hidden
     * Model minutes (0 - 59)
     */
    private _getModelMinute;
    /**
     * @hidden
     * Model seconds (0 - 59)
     */
    private _getModelSecond;
    /**
     * @hidden
     * Get meridian period based on a given hours
     */
    private _getDayPeriodByHour;
    /** @hidden */
    private _isPm;
    /**
     * @hidden
     * @returns default time 00:00:00
     */
    private _getDefaultValue;
    static ɵfac: i0.ɵɵFactoryDeclaration<TimeComponent<any>, [null, null, { optional: true; }, null]>;
    static ɵcmp: i0.ɵɵComponentDeclaration<TimeComponent<any>, "fd-time", never, { "meridian": { "alias": "meridian"; "required": false; }; "validate": { "alias": "validate"; "required": false; }; "keepTwoDigits": { "alias": "keepTwoDigits"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "displaySeconds": { "alias": "displaySeconds"; "required": false; }; "displayMinutes": { "alias": "displayMinutes"; "required": false; }; "displayHours": { "alias": "displayHours"; "required": false; }; "tablet": { "alias": "tablet"; "required": false; }; "elementsAtOnce": { "alias": "elementsAtOnce"; "required": false; }; "time": { "alias": "time"; "required": false; }; "spinnerButtons": { "alias": "spinnerButtons"; "required": false; }; "minuteStep": { "alias": "minuteStep"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
}

/**
 * @deprecated
 * Use direct imports of `TimeComponent`, `TimeColumnComponent`
 */
declare class TimeModule {
    static ɵfac: i0.ɵɵFactoryDeclaration<TimeModule, never>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<TimeModule, never, [typeof TimeComponent, typeof TimeColumnComponent], [typeof TimeComponent, typeof TimeColumnComponent]>;
    static ɵinj: i0.ɵɵInjectorDeclaration<TimeModule>;
}

export { TimeColumnComponent, TimeComponent, TimeModule };
export type { FdTimeActiveView, TimeColumnConfig, TimeColumnItemOutput };
