import * as i5 from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
import * as i0 from '@angular/core';
import { EventEmitter, ViewChild, Output, Input, Component, NgModule } from '@angular/core';
import * as i3 from '@angular/material/snack-bar';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import * as i2 from '@aztrix/components/overlay';
import { IMAGE_TYPES } from '@aztrix/components/property-edit';
import * as i1 from '@aztrix/environment';
import * as i4 from '@aztrix/translate';
import { TranslatePipe } from '@aztrix/translate';
import * as i6 from '@aztrix/sdk';
import base64js from 'base64-js';
import * as i7 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i8 from '@aztrix/icons';
import { IconsModule } from '@aztrix/icons';
import * as i9 from '@aztrix/components/button';
import { ButtonModule } from '@aztrix/components/button';
import * as i10 from '@aztrix/components/image-source';
import { ImageSourceModule } from '@aztrix/components/image-source';
import * as i11 from 'ngx-image-cropper';
import { ImageCropperModule } from 'ngx-image-cropper';
import * as i12 from '@aztrix/components/spinner';
import { SpinnerModule } from '@aztrix/components/spinner';

class ImageSelectComponent {
    static { this._nextId = 0; }
    constructor(_changeDetector, _urlTransformer, _overlay, _snackBar, _translate, _http, _configuration) {
        this._changeDetector = _changeDetector;
        this._urlTransformer = _urlTransformer;
        this._overlay = _overlay;
        this._snackBar = _snackBar;
        this._translate = _translate;
        this._http = _http;
        this._configuration = _configuration;
        this.aspectRatio = 5 / 3;
        this.roundCropper = false;
        this.resizeToHeight = 300;
        this.uploaded = new EventEmitter();
        this.remove = new EventEmitter();
        this.formats = IMAGE_TYPES.map((type) => `.${type}`).join(', ');
        this.loading = false;
        this.uploading = false;
        this.fileId = ImageSelectComponent._nextId++;
        this.IMAGE_TYPES = IMAGE_TYPES;
        this.acceptedTypes = IMAGE_TYPES.map((type) => `image/${type}`);
        this.accept = this.acceptedTypes.join(',');
    }
    ngOnChanges(changes) {
        if (changes.key) {
            this.clear();
        }
    }
    fileSelected(event) {
        const file = event.target.files?.[0];
        if (file) {
            this._fileSelected(file);
        }
    }
    fileDragStart(event) {
        event.preventDefault();
    }
    fileDrop(event) {
        event.preventDefault();
        if (event.dataTransfer?.items) {
            const item = event.dataTransfer.items[0];
            if (item.kind === 'file') {
                this._fileSelected(item.getAsFile());
            }
            event.dataTransfer.items.clear();
        }
        else {
            this._fileSelected(event.dataTransfer?.files[0]);
            event.dataTransfer?.clearData();
        }
    }
    upload() {
        this._uploadedImage = this._croppedImage?.base64;
        this._overlay.closeModal();
        this.uploading = true;
        const transformedUrl = this._urlTransformer.transformUrl(this.uploadLink);
        const formData = new FormData();
        const base64 = this._croppedImage?.base64?.split('base64,')[1];
        if (!base64) {
            return;
        }
        const bytes = base64js.toByteArray(base64);
        const blob = new Blob([bytes], { type: 'image/png' });
        const file = new File([blob], 'name.png');
        formData.append('file', file);
        let headers = new HttpHeaders();
        if (this._configuration.credentials) {
            const authToken = this._configuration.lookupCredential('AuthToken');
            if (authToken) {
                headers = headers.set('AuthToken', authToken);
            }
        }
        this._http
            .post(transformedUrl, formData, {
            observe: 'body',
            responseType: 'text',
            headers,
        })
            .subscribe({
            next: (key) => {
                this.uploading = false;
                this.uploaded.emit(key);
                this.clearFileInput();
                this._changeDetector.detectChanges();
            },
            error: () => {
                this.uploading = false;
                this._snackBar.open(this._translate.instant('file-edit.upload-failed'), this._translate.instant('label.close'));
                this.clearFileInput();
                this._changeDetector.detectChanges();
            },
        });
    }
    imageCropped(event) {
        this.loading = false;
        this._croppedImage = event;
    }
    loadImageFailed() {
        this.loading = false;
        this._snackBar.open(this._translate.instant('file-edit.error.invalid-file'), this._translate.instant('label.close'));
        this.clear();
    }
    clear() {
        this._uploadedImage = undefined;
        this._croppedImage = undefined;
        this.imageFile = undefined;
        this.clearFileInput();
    }
    get imageUrl() {
        if (this._uploadedImage?.includes('data:image')) {
            return this._uploadedImage;
        }
        else if (this.key) {
            return this._urlTransformer.transformUrl(`${this.downloadLink}/${this.key}`);
        }
        else {
            return undefined;
        }
    }
    clearFileInput() {
        if (this.fileInputElement) {
            this.fileInputElement.nativeElement.value = null;
        }
    }
    _fileSelected(file) {
        if (!file || !this.acceptedTypes.includes(file.type)) {
            this._snackBar.open(this._translate.instant('file-edit.error.incorrect-file-type', { types: this.formats }), this._translate.instant('label.close'));
            this.clearFileInput();
        }
        else {
            this.imageFile = file;
            this.loading = true;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageSelectComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.UrlTransformerService }, { token: i2.OverlayService }, { token: i3.MatSnackBar }, { token: i4.TranslateService }, { token: i5.HttpClient }, { token: i6.Configuration }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ImageSelectComponent, selector: "ax-image-select", inputs: { name: "name", key: "key", uploadLink: "uploadLink", downloadLink: "downloadLink", aspectRatio: "aspectRatio", roundCropper: "roundCropper", resizeToHeight: "resizeToHeight" }, outputs: { uploaded: "uploaded", remove: "remove" }, viewQueries: [{ propertyName: "fileInputElement", first: true, predicate: ["fileInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template #fileSelect let-edit>\n  <label class=\"file-button\" [attr.for]=\"'file' + fileId\">\n    <ax-icon class=\"icon\" [name]=\"edit ? 'pencil' : 'image-plus-outline'\"></ax-icon>\n  </label>\n</ng-template>\n\n<input\n  #fileInput\n  [attr.id]=\"'file' + fileId\"\n  [attr.name]=\"name\"\n  [attr.accept]=\"accept\"\n  type=\"file\"\n  (change)=\"fileSelected($event)\"\n/>\n\n<ng-template #fileDropArea>\n  <div\n    class=\"drop-area\"\n    (click)=\"fileInputElement.nativeElement.click()\"\n    (drop)=\"fileDrop($event)\"\n    (dragover)=\"fileDragStart($event)\"\n  >\n    <ax-icon class=\"icon\" name=\"image-plus-outline\"></ax-icon>\n  </div>\n</ng-template>\n\n<ng-template #view>\n  <ng-container *ngIf=\"imageUrl; else fileDropArea\">\n    <ax-image-source [source]=\"imageUrl\" [actualSize]=\"true\">\n      <ax-icon class=\"icon\" name=\"alert-circle\"></ax-icon>\n    </ax-image-source>\n\n    <div class=\"actions\">\n      <ax-button icon-button outline color=\"danger\" *ngIf=\"imageUrl\" (click)=\"remove.emit()\">\n        <ax-icon class=\"icon\" name=\"delete\"></ax-icon>\n      </ax-button>\n      <ng-container *ngTemplateOutlet=\"fileSelect; context: {$implicit: true}\"></ng-container>\n    </div>\n  </ng-container>\n</ng-template>\n\n<ng-container *ngIf=\"imageFile; else view\">\n  <div class=\"image-crop\">\n    <image-cropper\n      [imageFile]=\"imageFile\"\n      [output]=\"'base64'\"\n      [aspectRatio]=\"aspectRatio\"\n      [resizeToHeight]=\"resizeToHeight\"\n      [onlyScaleDown]=\"true\"\n      [roundCropper]=\"roundCropper\"\n      (imageCropped)=\"imageCropped($event)\"\n      (loadImageFailed)=\"loadImageFailed()\"\n    ></image-cropper>\n    <ax-spinner class=\"cropper-loading\" *ngIf=\"loading\"></ax-spinner>\n  </div>\n\n  <div class=\"actions\">\n    <ax-button icon-button outline color=\"danger\" [disabled]=\"uploading\" (click)=\"clear()\">\n      <ax-icon class=\"icon\" name=\"cancel\"></ax-icon>\n    </ax-button>\n    <ax-button icon-button filled color=\"primary\" [disabled]=\"uploading\" (click)=\"upload()\">\n      <ax-icon class=\"icon\" name=\"check\"></ax-icon>\n    </ax-button>\n  </div>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column}.actions{display:flex;justify-content:flex-end;padding-top:.5rem;gap:.5rem}input[type=file]{position:absolute;top:-200%;left:0;width:1px;height:1px;opacity:0;visibility:hidden;cursor:pointer}.file-button{background-color:var(--primary-color-500);color:var(--primary-color-500-contrast);border:1px solid transparent;font-size:.875rem;font-weight:700;position:relative;-webkit-user-select:none;user-select:none;cursor:pointer;outline:0;display:inline-flex;justify-content:center;align-items:center;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;text-transform:uppercase;width:34px;height:34px;line-height:2rem;border-radius:18px;overflow:visible;transform:translateZ(0);transition:background .4s cubic-bezier(.25,.8,.25,1),color .4s cubic-bezier(.25,.8,.25,1)}.file-button:hover{color:#fff;background-color:var(--primary-color-900)}.file-button:active{color:#fff;background-color:#4c5965}.file-button.is-disabled,.file-button:disabled,.file-button.is-disabled:hover,.file-button:disabled:hover{background-color:transparent;color:#bdc3c9;cursor:default;pointer-events:none}.image-crop{position:relative}.cropper-loading{display:flex;justify-content:center;position:absolute;top:0;left:0;height:100%;width:100%;background-color:#d7dde4}.drop-area{display:flex;justify-content:center;align-items:center;height:200px;border:dashed 2px #bdc3c9;background-color:#d7dde4;cursor:pointer}.error{color:var(--warn-color-500)}\n"], dependencies: [{ kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i8.IconComponent, selector: "ax-icon", inputs: ["name", "inline"] }, { kind: "component", type: i9.ButtonComponent, selector: "ax-button", inputs: ["url", "ariaLabel", "target"] }, { kind: "component", type: i10.ImageSourceComponent, selector: "ax-image-source", inputs: ["source", "fallbackSource", "actualSize", "alt", "round", "rounded", "border"] }, { kind: "component", type: i11.ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "cropperFrameAriaLabel", "output", "format", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "autoCrop", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "cropper", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange"] }, { kind: "component", type: i12.SpinnerComponent, selector: "ax-spinner" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageSelectComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ax-image-select', template: "<ng-template #fileSelect let-edit>\n  <label class=\"file-button\" [attr.for]=\"'file' + fileId\">\n    <ax-icon class=\"icon\" [name]=\"edit ? 'pencil' : 'image-plus-outline'\"></ax-icon>\n  </label>\n</ng-template>\n\n<input\n  #fileInput\n  [attr.id]=\"'file' + fileId\"\n  [attr.name]=\"name\"\n  [attr.accept]=\"accept\"\n  type=\"file\"\n  (change)=\"fileSelected($event)\"\n/>\n\n<ng-template #fileDropArea>\n  <div\n    class=\"drop-area\"\n    (click)=\"fileInputElement.nativeElement.click()\"\n    (drop)=\"fileDrop($event)\"\n    (dragover)=\"fileDragStart($event)\"\n  >\n    <ax-icon class=\"icon\" name=\"image-plus-outline\"></ax-icon>\n  </div>\n</ng-template>\n\n<ng-template #view>\n  <ng-container *ngIf=\"imageUrl; else fileDropArea\">\n    <ax-image-source [source]=\"imageUrl\" [actualSize]=\"true\">\n      <ax-icon class=\"icon\" name=\"alert-circle\"></ax-icon>\n    </ax-image-source>\n\n    <div class=\"actions\">\n      <ax-button icon-button outline color=\"danger\" *ngIf=\"imageUrl\" (click)=\"remove.emit()\">\n        <ax-icon class=\"icon\" name=\"delete\"></ax-icon>\n      </ax-button>\n      <ng-container *ngTemplateOutlet=\"fileSelect; context: {$implicit: true}\"></ng-container>\n    </div>\n  </ng-container>\n</ng-template>\n\n<ng-container *ngIf=\"imageFile; else view\">\n  <div class=\"image-crop\">\n    <image-cropper\n      [imageFile]=\"imageFile\"\n      [output]=\"'base64'\"\n      [aspectRatio]=\"aspectRatio\"\n      [resizeToHeight]=\"resizeToHeight\"\n      [onlyScaleDown]=\"true\"\n      [roundCropper]=\"roundCropper\"\n      (imageCropped)=\"imageCropped($event)\"\n      (loadImageFailed)=\"loadImageFailed()\"\n    ></image-cropper>\n    <ax-spinner class=\"cropper-loading\" *ngIf=\"loading\"></ax-spinner>\n  </div>\n\n  <div class=\"actions\">\n    <ax-button icon-button outline color=\"danger\" [disabled]=\"uploading\" (click)=\"clear()\">\n      <ax-icon class=\"icon\" name=\"cancel\"></ax-icon>\n    </ax-button>\n    <ax-button icon-button filled color=\"primary\" [disabled]=\"uploading\" (click)=\"upload()\">\n      <ax-icon class=\"icon\" name=\"check\"></ax-icon>\n    </ax-button>\n  </div>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column}.actions{display:flex;justify-content:flex-end;padding-top:.5rem;gap:.5rem}input[type=file]{position:absolute;top:-200%;left:0;width:1px;height:1px;opacity:0;visibility:hidden;cursor:pointer}.file-button{background-color:var(--primary-color-500);color:var(--primary-color-500-contrast);border:1px solid transparent;font-size:.875rem;font-weight:700;position:relative;-webkit-user-select:none;user-select:none;cursor:pointer;outline:0;display:inline-flex;justify-content:center;align-items:center;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;text-transform:uppercase;width:34px;height:34px;line-height:2rem;border-radius:18px;overflow:visible;transform:translateZ(0);transition:background .4s cubic-bezier(.25,.8,.25,1),color .4s cubic-bezier(.25,.8,.25,1)}.file-button:hover{color:#fff;background-color:var(--primary-color-900)}.file-button:active{color:#fff;background-color:#4c5965}.file-button.is-disabled,.file-button:disabled,.file-button.is-disabled:hover,.file-button:disabled:hover{background-color:transparent;color:#bdc3c9;cursor:default;pointer-events:none}.image-crop{position:relative}.cropper-loading{display:flex;justify-content:center;position:absolute;top:0;left:0;height:100%;width:100%;background-color:#d7dde4}.drop-area{display:flex;justify-content:center;align-items:center;height:200px;border:dashed 2px #bdc3c9;background-color:#d7dde4;cursor:pointer}.error{color:var(--warn-color-500)}\n"] }]
        }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.UrlTransformerService }, { type: i2.OverlayService }, { type: i3.MatSnackBar }, { type: i4.TranslateService }, { type: i5.HttpClient }, { type: i6.Configuration }], propDecorators: { name: [{
                type: Input
            }], key: [{
                type: Input
            }], uploadLink: [{
                type: Input
            }], downloadLink: [{
                type: Input
            }], aspectRatio: [{
                type: Input
            }], roundCropper: [{
                type: Input
            }], resizeToHeight: [{
                type: Input
            }], uploaded: [{
                type: Output
            }], remove: [{
                type: Output
            }], fileInputElement: [{
                type: ViewChild,
                args: ['fileInput']
            }] } });

class ImageSelectModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageSelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: ImageSelectModule, declarations: [ImageSelectComponent], imports: [CommonModule,
            IconsModule,
            ButtonModule,
            ImageSourceModule,
            TranslatePipe,
            ImageCropperModule,
            SpinnerModule,
            MatSnackBarModule], exports: [ImageSelectComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageSelectModule, imports: [CommonModule,
            IconsModule,
            ButtonModule,
            ImageSourceModule,
            ImageCropperModule,
            SpinnerModule,
            MatSnackBarModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageSelectModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [ImageSelectComponent],
                    imports: [
                        CommonModule,
                        IconsModule,
                        ButtonModule,
                        ImageSourceModule,
                        TranslatePipe,
                        ImageCropperModule,
                        SpinnerModule,
                        MatSnackBarModule,
                    ],
                    exports: [ImageSelectComponent],
                }]
        }] });

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

export { ImageSelectComponent, ImageSelectModule };
//# sourceMappingURL=aztrix-components-image-select.mjs.map
