import * as i0 from '@angular/core';
import { Directive, inject, NgZone, DestroyRef, Renderer2, input, output, computed, afterNextRender, NgModule } from '@angular/core';
import { coerceCssPixelValue } from '@angular/cdk/coercion';
import { DOCUMENT } from '@angular/common';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { kbqInjectNativeElement } from '@koobiq/components/core';
import { fromEvent } from 'rxjs';

/**
 * Directive (container) sets whether the element is resizable.
 *
 * @example
 *
 * ```html
 * <div kbqResizable>
 *     <div [kbqResizer]="[-1, 0]"></div>
 * </div>
 * ```
 */
class KbqResizable {
    constructor() {
        /**
         * @docs-private
         */
        this.element = kbqInjectNativeElement();
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqResizable, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqResizable, isStandalone: true, selector: "[kbqResizable]", host: { classAttribute: "kbq-resizable" }, exportAs: ["kbqResizable"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqResizable, decorators: [{
            type: Directive,
            args: [{
                    standalone: true,
                    selector: '[kbqResizable]',
                    exportAs: 'kbqResizable',
                    host: {
                        class: 'kbq-resizable'
                    }
                }]
        }] });
/**
 * Directive which defines element resizing direction.
 */
class KbqResizer {
    constructor() {
        this.element = kbqInjectNativeElement();
        this.resizable = inject(KbqResizable);
        this.zone = inject(NgZone);
        this.document = inject(DOCUMENT);
        this.destroyRef = inject(DestroyRef);
        this.renderer = inject(Renderer2);
        this.x = NaN;
        this.y = NaN;
        this.width = 0;
        this.height = 0;
        /**
         * Direction of element resizing.
         */
        this.direction = input.required({ alias: 'kbqResizer' });
        /**
         * Emits the new size of the element after resizing.
         */
        this.sizeChange = output();
        /**
         * @docs-private
         */
        this.cursor = computed(() => {
            const [x, y] = this.direction();
            if (x === 0 && y === 0)
                return 'default';
            if (!x)
                return 'ns-resize';
            if (!y)
                return 'ew-resize';
            if (x * y > 0)
                return 'nwse-resize';
            return 'nesw-resize';
        });
        afterNextRender(() => {
            this.zone.runOutsideAngular(() => {
                fromEvent(this.element, 'pointerdown')
                    .pipe(takeUntilDestroyed(this.destroyRef))
                    .subscribe((event) => this.handleElementPointerDown(event));
                fromEvent(this.document, 'pointermove')
                    .pipe(takeUntilDestroyed(this.destroyRef))
                    .subscribe((event) => this.handleDocumentPointerMove(event));
                fromEvent(this.document, 'pointerup')
                    .pipe(takeUntilDestroyed(this.destroyRef))
                    .subscribe((event) => this.handleDocumentPointerUp(event));
            });
        });
    }
    handleElementPointerDown(event) {
        event.preventDefault();
        this.x = event.x;
        this.y = event.y;
        const { clientWidth, clientHeight } = this.resizable.element;
        this.width = clientWidth;
        this.height = clientHeight;
    }
    handleDocumentPointerMove(event) {
        if (!event.buttons)
            return this.handleDocumentPointerUp(event);
        this.updateSize(event);
    }
    handleDocumentPointerUp(_event) {
        this.x = NaN;
    }
    updateSize({ x, y }) {
        if (Number.isNaN(this.x))
            return;
        const [directionX, directionY] = this.direction();
        const width = this.width + directionX * (x - this.x);
        const height = this.height + directionY * (y - this.y);
        if (directionX)
            this.renderer.setStyle(this.resizable.element, 'width', coerceCssPixelValue(width));
        if (directionY)
            this.renderer.setStyle(this.resizable.element, 'height', coerceCssPixelValue(height));
        this.sizeChange.emit({ width, height });
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqResizer, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: KbqResizer, isStandalone: true, selector: "[kbqResizer]", inputs: { direction: { classPropertyName: "direction", publicName: "kbqResizer", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { sizeChange: "sizeChange" }, host: { properties: { "style.cursor": "cursor()" }, classAttribute: "kbq-resizer" }, exportAs: ["kbqResizer"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqResizer, decorators: [{
            type: Directive,
            args: [{
                    standalone: true,
                    selector: '[kbqResizer]',
                    exportAs: 'kbqResizer',
                    host: {
                        class: 'kbq-resizer',
                        '[style.cursor]': 'cursor()'
                    }
                }]
        }], ctorParameters: () => [] });

const COMPONENTS = [KbqResizable, KbqResizer];
class KbqResizerModule {
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqResizerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: KbqResizerModule, imports: [KbqResizable, KbqResizer], exports: [KbqResizable, KbqResizer] }); }
    /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqResizerModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqResizerModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: COMPONENTS,
                    exports: COMPONENTS
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { KbqResizable, KbqResizer, KbqResizerModule };
//# sourceMappingURL=koobiq-components-resizer.mjs.map
