import Modifier from 'ember-modifier';
import type { ArgsFor, PositionalArgs, NamedArgs } from 'ember-modifier';
import type EmberSortableService from '../services/ember-sortable-internal-state.ts';
import type Owner from '@ember/owner';
import type { Group } from '../services/ember-sortable-internal-state.ts';
import type SortableGroupModifier from './sortable-group.ts';
import type { TDirection } from './sortable-group.ts';
export interface MoveDirection {
    left: boolean;
    right: boolean;
    top: boolean;
    bottom: boolean;
}
export interface FakeEvent {
    pageX: number;
    pageY: number;
    clientX: number;
    clientY: number;
}
export interface SortableItemModifierSignature<T> {
    Args: {
        Named: {
            model: T;
            groupName?: string;
            disabled?: boolean;
            updateInterval?: number;
            spacing?: number;
            isDraggingDisabled?: boolean;
            handle?: string;
            distance?: number;
            disableCheckScrollBounds?: boolean;
            onDragStart?: (item: T) => void;
            onDragStop?: (item: T) => void;
        };
    };
    Element: HTMLElement;
}
/**
 * Modifier to mark an element as an item to be reordered
 *
 * @param {Object} model The model that this item will represent
 * @param {boolean} [disabled=false] Set to true to make this item not sortable
 * @param {Function}  [onDragStart] An optional callback for when dragging starts.
 * @param {Function}  [onDragStop] An optional callback for when dragging stops.
 *
 * @module drag-drop/draggable-group
 * @example
 *    <ol {{sortable-group onChange=this.update a11yAnnouncementConfig=this.myA11yConfig}}>
 *      {{#each model.items as |item|}}
 *        <li {{sortable-item model=item}}>
 *          {{item.name}}
 *          <span class="handle" {{sortable-handle}}>&varr;</span>
 *        </li>
 *      {{/each}}
 *    </ol>
 */
export default class SortableItemModifier<T> extends Modifier<SortableItemModifierSignature<T>> {
    className: string;
    sortableService: EmberSortableService<T>;
    startEvent?: FakeEvent | Event;
    _sortableGroup?: Group<T>;
    _x?: number;
    _y?: number;
    _dragOriginX?: number;
    _dragOriginY?: number;
    _pageX?: number;
    _pageY?: number;
    /**
     * The SortableGroupModifier this item belongs to. Assigned by the group
     * when it inspects all the items in the list
     *
     * @type SortableGroupModifier
     */
    get sortableGroup(): SortableGroupModifier<T>;
    get model(): T;
    get direction(): TDirection;
    get groupDisabled(): boolean;
    /**
     * This is the group name used to keep groups separate if there are more than one on the screen at a time.
     * If no group is assigned a default is used
     *
     * @default "_EmberSortableGroup"
     * @returns {string}
     */
    get groupName(): string;
    /**
     The frequency with which the group is informed
     that an update is required.
     @property updateInterval
     @type Number
     @default 125
     */
    get updateInterval(): number;
    /**
     Additional spacing between active item and the rest of the elements.
     @property spacing
     @type Number
     @default 0[px]
     */
    get spacing(): number;
    /**
     Removes the ability for the current item to be sorted
     @property disabled
     @type  boolean
     @default false
     */
    get isDisabled(): boolean;
    /**
     Selector for the element to use as handle.
     1. By default, we will hook it the yielded sortable-handle.
     2. If you don't use the sortable-handle, the entire element will be used as the handle.
     3. In very rare situations, if you want to use a handle, but not the sortable-handle,
     you can override this class with your own handle's selector. This behavior will be
     synonymous with v1
     @property handle
     @type String
     @default "[data-sortable-handle]"
     */
    get handle(): string;
    handleElement?: HTMLElement | null;
    /**
     * Tolerance, in pixels, for when sorting should start.
     * If specified, sorting will not start until after mouse
     * is dragged beyond distance. Can be used to allow for clicks
     * on elements within a handle.
     *
     * @property distance
     * @type Integer
     * @default 0
     */
    get distance(): number;
    /**
     * True if the item is currently being dragged.
     *
     * @property isDragging
     * @type boolean
     * @default false
     * @protected
     */
    _isDragging: boolean;
    get isDragging(): boolean;
    set isDragging(value: boolean);
    /**
     * Gives info in which direction the element will be moved
     *
     * @property moveDirection
     * @type Object
     */
    get moveDirection(): MoveDirection;
    /**
     Action that fires when the item starts being dragged.
     @property onDragStart
     @type Function
     @param {Object} item model
     @default null
     */
    get onDragStart(): (item: T) => void;
    /**
     Action that fires when the item stops being dragged.
     @property onDragStop
     @type Function
     @param {Object} item model
     @default null
     */
    get onDragStop(): (item: T) => void;
    /**
     True if the item is currently dropping.
     @property isDropping
     @type Boolean
     @default false
     */
    _isDropping: boolean;
    get isDropping(): boolean;
    set isDropping(value: boolean);
    /**
     True if the item was dropped during the interaction
     @property wasDropped
     @type Boolean
     @default false
     */
    wasDropped: boolean;
    /**
     @property isBusy
     @type Boolean
     */
    get isBusy(): boolean;
    /**
     @property disableCheckScrollBounds
     */
    get disableCheckScrollBounds(): boolean;
    /**
     @method mouseDown
     */
    mouseDown(event: MouseEvent): void;
    keyDown(event: Event): void;
    /**
     @method touchStart
     */
    touchStart(event: TouchEvent): void;
    /**
     @method freeze
     */
    freeze(): void;
    /**
     @method reset
     */
    reset(): void;
    /**
     @method thaw
     */
    thaw(): void;
    _prepareDragListener: () => void;
    _cancelStartDragListener: () => void;
    /**
     * Setup event listeners for drag and drop
     *
     * @method _primeDrag
     * @param {Event} startEvent JS Event object
     * @private
     */
    _primeDrag(startEvent: Event): void;
    /**
     * Prepares for the drag event
     *
     * @method _prepareDrag
     * @param {Event} startEvent JS Event object
     * @param {Event} event JS Event object
     * @private
     */
    _prepareDrag(startEvent: MouseEvent, event: MouseEvent): void;
    /**
     * Start dragging & setup more event listeners
     *
     * @method _startDrag
     * @param {Event} event JS Event object
     * @private
     */
    _startDrag(event: MouseEvent | TouchEvent): void;
    /**
     The maximum scroll speed when dragging element.
     @property maxScrollSpeed
     @default 20
     */
    maxScrollSpeed: number;
    _scrollOnEdges(drag: (event: FakeEvent | Event) => void): void;
    /**
     @method _makeDragHandler
     @param {Event} startEvent
     @return {Function}
     @private
     */
    _makeDragHandler(startEvent: FakeEvent | Event): (event: FakeEvent | Event) => void;
    /**
     @method _scheduleApplyPosition
     @private
     */
    _scheduleApplyPosition(): void;
    /**
     @method _applyPosition
     @private
     */
    _applyPosition(): void;
    /**
     @method _drag
     @private
     */
    _drag(dimensionX: number, dimensionY: number): void;
    /**
     @method _drop
     @private
     */
    _drop(): void;
    /**
     @method _preventClick
     @private
     */
    _preventClick(): void;
    /**
     @method _preventClickHandler
     @private
     */
    _preventClickHandler(e: Event): void;
    /**
     @method _waitForTransition
     @private
     @return Promise
     */
    _waitForTransition(): Promise<unknown>;
    /**
     @method _waitForTransitions
     @private
     @return Promise
     */
    _waitForAllTransitions(): Promise<unknown>;
    /**
     @method _complete
     @private
     */
    _complete(): void;
    get isAnimated(): boolean | undefined;
    /**
     The current transition duration in milliseconds.
     @property transitionDuration
     @type Number
     */
    get transitionDuration(): number;
    /**
     Horizontal position of the item.
     @property x
     @type Number
     */
    get x(): number;
    set x(value: number);
    /**
     Vertical position of the item relative to its offset parent.
     @property y
     @type Number
     */
    get y(): number;
    set y(value: number);
    /**
     Width of the item.
     @property height
     @type Number
     */
    get width(): number;
    /**
     Height of the item including margins.
     @property height
     @type Number
     */
    get height(): number;
    addEventListener(): void;
    removeEventListener(): void;
    setupHandleElement(disabled?: boolean): void;
    element: HTMLElement;
    didSetup: boolean;
    named: NamedArgs<SortableItemModifierSignature<T>>;
    /**
     * tracks if event listeners have been registered. Registering event handlers is unnecessary if item is disabled.
     */
    listenersRegistered: boolean;
    constructor(owner: Owner, args: ArgsFor<SortableItemModifierSignature<T>>);
    modify(element: HTMLElement, _positional: PositionalArgs<SortableItemModifierSignature<T>>, named: NamedArgs<SortableItemModifierSignature<T>>): void;
}
