// #region Imports
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { on } from '@breadstone/mosaik-elements';
import { Disableable } from '../../../../Behaviors/Disableable';
import { Themeable } from '../../../../Behaviors/Themeable';
import { Attribute } from '../../../../Decorators/AttributeDecorator';
import { Component } from '../../../../Decorators/ComponentDecorator';
import { Watch } from '../../../../Decorators/WatchDecorator';
import { CustomElement } from '../../../Abstracts/CustomElement';
import { resizeAdornerElementTemplate } from './ResizeAdornerElementTemplate';
import { resizeAdornerElementCosmopolitanStyle } from './Themes/ResizeAdornerElement.Cosmopolitan';
import { resizeAdornerElementJoyStyle } from './Themes/ResizeAdornerElement.Joy';
import { resizeAdornerElementMemphisStyle } from './Themes/ResizeAdornerElement.Memphis';
// #endregion
/**
 * Resize Adorner - An interactive UI element typically used to resize an element.
 *
 * @description
 * The resize adorner element is used to resize an element.
 *
 * @name Resize Adorner
 * @element mosaik-resize-adorner
 * @category Adorners
 *
 * @slot - The content of the resize adorner.
 *
 * @csspart resizable
 * @csspart handle top-left
 * @csspart handle top-right
 * @csspart handle bottom-left
 * @csspart handle bottom-right
 *
 * @cssprop {Color} --resize-adorner-border-color
 * @cssprop {String} --resize-adorner-border-width
 * @cssprop {String} --resize-adorner-border-radius
 * @cssprop {String} --resize-adorner-border-style
 * @cssprop {Color} --resize-adorner-thumb-background-color
 * @cssprop {String} --resize-adorner-thumb-border-radius
 *
 * @example
 * ```html
 * <mosaik-resize-adorner></mosaik-resize-adorner>
 * ```
 *
 * @public
 */
let ResizeAdornerElement = class ResizeAdornerElement extends Themeable(Disableable(CustomElement)) {
    // #region Fields
    _angle;
    _transformOrigin;
    _topLeftHandleMouseDownSubscription;
    _topRightHandleMouseDownSubscription;
    _bottomLeftHandleMouseDownSubscription;
    _bottomRightHandleMouseDownSubscription;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._angle = 0;
        this._transformOrigin = {
            x: 0,
            y: 0
        };
        this._bottomLeftHandleMouseDownSubscription = null;
        this._bottomRightHandleMouseDownSubscription = null;
        this._topLeftHandleMouseDownSubscription = null;
        this._topRightHandleMouseDownSubscription = null;
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `{@link is}` property.
     * The `{@link is}` property represents natural name of this element.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-resize-adorner';
    }
    /**
     * Gets or sets the `angle` property.
     *
     * @public
     * @attr
     */
    get angle() {
        return this._angle;
    }
    set angle(value) {
        if (this._angle !== value) {
            this._angle = value;
            this.requestUpdate('angle');
        }
    }
    /**
     * Gets or sets the `transformOrigin` property.
     *
     * @public
     * @attr
     */
    get transformOrigin() {
        return this._transformOrigin;
    }
    set transformOrigin(value) {
        if (this._transformOrigin !== value) {
            this._transformOrigin = value;
            this.requestUpdate('transformOrigin');
        }
    }
    // #endregion
    // #region Methods
    /**
     * @public
     * @override
     */
    disconnectedCallback() {
        this._topLeftHandleMouseDownSubscription?.dispose();
        this._topRightHandleMouseDownSubscription?.dispose();
        this._bottomLeftHandleMouseDownSubscription?.dispose();
        this._bottomRightHandleMouseDownSubscription?.dispose();
        super.disconnectedCallback();
    }
    /**
     * @protected
     * @override
     */
    onApplyTemplate() {
        const tlHandle = this.getTemplatePart('handle top-left');
        const trHandle = this.getTemplatePart('handle top-right');
        const blHandle = this.getTemplatePart('handle bottom-left');
        const brHandle = this.getTemplatePart('handle bottom-right');
        this._topLeftHandleMouseDownSubscription = on(tlHandle, 'mousedown', (x) => this.onHandle(x, 'top-left'));
        this._topRightHandleMouseDownSubscription = on(trHandle, 'mousedown', (x) => this.onHandle(x, 'top-right'));
        this._bottomLeftHandleMouseDownSubscription = on(blHandle, 'mousedown', (x) => this.onHandle(x, 'bottom-left'));
        this._bottomRightHandleMouseDownSubscription = on(brHandle, 'mousedown', (x) => this.onHandle(x, 'bottom-right'));
    }
    /**
     * @protected
     */
    onAnglePropertyChanged(prev, next) {
        this.updateTransforms();
    }
    /**
     * @protected
     */
    onTransformOriginPropertyChanged(prev, next) {
        this.updateTransforms();
    }
    /**
     * @protected
     */
    onDisabledPropertyChanged(prev, next) {
        if (next) {
            this._topLeftHandleMouseDownSubscription?.dispose();
            this._topRightHandleMouseDownSubscription?.dispose();
            this._bottomLeftHandleMouseDownSubscription?.dispose();
            this._bottomRightHandleMouseDownSubscription?.dispose();
        }
        else {
            this.onApplyTemplate();
        }
    }
    /**
     * @protected
     * @template
     */
    onHandle(event, direction) {
        event.preventDefault();
        const onMouseMove = (e) => this.onDragResize(e, direction);
        const onMouseUp = () => {
            window.removeEventListener('mousemove', onMouseMove);
            window.removeEventListener('mouseup', onMouseUp);
        };
        window.addEventListener('mousemove', onMouseMove);
        window.addEventListener('mouseup', onMouseUp);
    }
    /**
     * @private
     */
    updateTransforms() {
        const transform = `rotate(${this._angle}deg)`;
        this.style.transform = transform;
        this.style.transformOrigin = `${this.transformOrigin.x}px ${this.transformOrigin.y}px`;
    }
    /**
     * @private
     */
    onDragResize(event, direction) {
        event.preventDefault();
        const element = this.getTemplatePart('resizable');
        const rect = element.getBoundingClientRect();
        let newWidth = rect.width;
        let newHeight = rect.height;
        switch (direction) {
            case 'top-left':
                newWidth -= event.movementX;
                newHeight -= event.movementY;
                break;
            case 'top-right':
                newWidth += event.movementX;
                newHeight -= event.movementY;
                break;
            case 'bottom-left':
                newWidth -= event.movementX;
                newHeight += event.movementY;
                break;
            case 'bottom-right':
                newWidth += event.movementX;
                newHeight += event.movementY;
                break;
            default:
                break;
        }
        element.style.width = `${newWidth}px`;
        element.style.height = `${newHeight}px`;
    }
};
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], ResizeAdornerElement.prototype, "angle", null);
__decorate([
    Attribute({
        type: {
            x: Number,
            y: Number
        }
    }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], ResizeAdornerElement.prototype, "transformOrigin", null);
__decorate([
    Watch('angle'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Number, Number]),
    __metadata("design:returntype", void 0)
], ResizeAdornerElement.prototype, "onAnglePropertyChanged", null);
__decorate([
    Watch('transformOrigin'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], ResizeAdornerElement.prototype, "onTransformOriginPropertyChanged", null);
__decorate([
    Watch('disabled'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Boolean, Boolean]),
    __metadata("design:returntype", void 0)
], ResizeAdornerElement.prototype, "onDisabledPropertyChanged", null);
ResizeAdornerElement = __decorate([
    Component({
        selector: 'mosaik-resize-adorner',
        template: resizeAdornerElementTemplate,
        themes: {
            joy: resizeAdornerElementJoyStyle,
            memphis: resizeAdornerElementMemphisStyle,
            cosmopolitan: resizeAdornerElementCosmopolitanStyle
        },
        imports: []
    }),
    __metadata("design:paramtypes", [])
], ResizeAdornerElement);
export { ResizeAdornerElement };
//# sourceMappingURL=ResizeAdornerElement.js.map