import { CommonModule } from '@angular/common';
import { InjectionToken, EventEmitter, Optional, Self, Inject, Input, ViewChild, Output, Component, ViewEncapsulation, NgModule } from '@angular/core';
import { NtUploadRef, NtUploadResponse, NtUploadStatus, NtUploadHandler, fadeOut, fadeIn, NtFileModule } from '@ng-tangram/components/core';
import { NtModal, NtModalModule } from '@ng-tangram/components/modal';
import { NtProgressModule } from '@ng-tangram/components/progress';
import loadImage from 'blueimp-load-image';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { trigger, transition } from '@angular/animations';
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
import { NgControl } from '@angular/forms';
import { NtFormFieldControl } from '@ng-tangram/components/forms';

const DEFAULT_PICTURE_ICONS = {
    add: 'fa fa-plus',
    preview: 'fa fa-search',
    remove: 'fa fa-trash-alt'
};
const NT_PICTURE_ICONS = new InjectionToken('nt-picture-icons');

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 __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var NtPictureComponent_1;
function zipImage(file, option = { maxWidth: 1080, orientation: true, canvas: true }) {
    return new Promise((resolve, reject) => {
        loadImage(file, (canvas) => {
            if (canvas.toBlob) {
                canvas.toBlob((blob) => {
                    let thumbnail = canvas.toDataURL('image/png');
                    blob.lastModifiedDate = new Date();
                    blob.lastModified = blob.lastModifiedDate.getTime();
                    resolve({ thumbnail, blob });
                });
            }
            else {
                reject('HTMLCanvasElement toBlob function is undefined');
            }
        }, option);
    });
}
let uniqueId = 0;
const NT_PICTURE_ACCEPTS = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/bmp'];
class NtPictureRef extends NtUploadRef {
    constructor(file, id = `nt-picture-${uniqueId++}`) {
        super(file, file.name, file.size);
        this.file = file;
        this.id = id;
    }
}
let NtPictureComponent = NtPictureComponent_1 = class NtPictureComponent extends NtFormFieldControl {
    constructor(_modal, _uploadHandler, ngControl, icons) {
        super();
        this._modal = _modal;
        this._uploadHandler = _uploadHandler;
        this.ngControl = ngControl;
        this.icons = icons;
        this._destroy = new Subject();
        this._accept = NT_PICTURE_ACCEPTS.join(',');
        this._displayPictureRefs = [];
        this._pictureRefs = [];
        this._disabled = false;
        this._readonly = false;
        this._notrigger = false;
        this._required = false;
        this._multiple = true;
        this._limitSize = Number.MAX_VALUE;
        this.url = '';
        this.name = '';
        this.shape = '';
        this.errors = new EventEmitter();
        this._onChange = () => { };
        this._onTouched = () => { };
        console.log(_uploadHandler);
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        this.icons = Object.assign(Object.assign({}, DEFAULT_PICTURE_ICONS), icons);
    }
    get value() { return this._pictureRefs; }
    get disabled() { return this._disabled; }
    set disabled(value) { this._disabled = coerceBooleanProperty(value); }
    get readonly() { return this._readonly; }
    set readonly(value) { this._readonly = coerceBooleanProperty(value); }
    get notrigger() { return this._notrigger; }
    set notrigger(value) { this._notrigger = coerceBooleanProperty(value); }
    get required() { return this._required; }
    set required(value) { this._required = coerceBooleanProperty(value); }
    get accept() { return this._accept; }
    set accept(value) {
        if (typeof value === 'string') {
            if (value === '*') {
                this._accept = NT_PICTURE_ACCEPTS.join(',');
            }
            else {
                this._accept = value.replace(' ', '');
            }
        }
        else {
            this._accept = value.join(',');
        }
    }
    get multiple() { return this._multiple; }
    set multiple(value) { this._multiple = coerceBooleanProperty(value); }
    get limitSize() { return this._limitSize; }
    set limitSize(value) { this._limitSize = coerceNumberProperty(value, 5); }
    ngOnInit() { }
    ngOnDestroy() {
        this._destroy.next();
        this._destroy.complete();
        this.errors.complete();
    }
    writeValue(value) {
        if (value) {
            this._pictureRefs.splice(0, this._pictureRefs.length, ...value);
            this._displayPictureRefs.splice(0, this._displayPictureRefs.length, ...value);
        }
    }
    registerOnChange(fn) {
        this._onChange = fn;
    }
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    setDisabledState(isDisabled) {
        this._disabled = isDisabled;
    }
    preview(pictureRef) {
        this._modal.open(this.previewTemplate, {
            data: pictureRef,
            centerVertically: true,
            maxWidth: '90vw',
            maxHeight: '90vh',
            width: 'auto',
            transparent: true
        });
    }
    _select(files) {
        const pictureRefs = files.map(file => this._createPictureRef(file));
        this._displayPictureRefs.push(...pictureRefs);
        this._onTouched && this._onTouched();
    }
    _remove(pictureRef) {
        if (this.disabled) {
            return;
        }
        this._removePictureRef(pictureRef);
        this._onChange(this.value);
    }
    _createPictureRef(file) {
        const pictureRef = new NtPictureRef(file);
        zipImage(file).then(data => pictureRef.thumbnail = data.thumbnail);
        pictureRef.subscription = this._uploadHandler
            .upload(this.url, pictureRef)
            .pipe(takeUntil(this._destroy))
            .subscribe(event => this._resolveUploadedResult(pictureRef, event));
        return pictureRef;
    }
    _removePictureRef(pictureRef) {
        if (pictureRef.subscription && !pictureRef.subscription.closed) {
            pictureRef.subscription.unsubscribe();
        }
        if (this._pictureRefs.includes(pictureRef)) {
            const index = this._pictureRefs.indexOf(pictureRef);
            this._pictureRefs.splice(index, 1);
        }
        if (this._displayPictureRefs.includes(pictureRef)) {
            const displayIndex = this._displayPictureRefs.indexOf(pictureRef);
            this._displayPictureRefs.splice(displayIndex, 1);
        }
    }
    _resolveUploadedResult(pictureRef, event) {
        if (event instanceof NtUploadResponse) {
            pictureRef.data = event.data;
            this._pictureRefs.push(pictureRef);
        }
        else {
            pictureRef.status = NtUploadStatus.ERROR;
            pictureRef.error = event.error;
            pictureRef.progress = 100;
            this.errors.next(event.error);
        }
        this._onChange(this.value);
    }
};
NtPictureComponent.ctorParameters = () => [
    { type: NtModal },
    { type: NtUploadHandler, decorators: [{ type: Optional }] },
    { type: NgControl, decorators: [{ type: Optional }, { type: Self }] },
    { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NT_PICTURE_ICONS,] }] }
];
__decorate([
    Input()
], NtPictureComponent.prototype, "disabled", null);
__decorate([
    Input()
], NtPictureComponent.prototype, "readonly", null);
__decorate([
    Input()
], NtPictureComponent.prototype, "notrigger", null);
__decorate([
    Input()
], NtPictureComponent.prototype, "required", null);
__decorate([
    Input()
], NtPictureComponent.prototype, "accept", null);
__decorate([
    Input()
], NtPictureComponent.prototype, "multiple", null);
__decorate([
    Input()
], NtPictureComponent.prototype, "limitSize", null);
__decorate([
    Input()
], NtPictureComponent.prototype, "url", void 0);
__decorate([
    Input()
], NtPictureComponent.prototype, "name", void 0);
__decorate([
    Input()
], NtPictureComponent.prototype, "shape", void 0);
__decorate([
    ViewChild('previewTemplate', { static: true })
], NtPictureComponent.prototype, "previewTemplate", void 0);
__decorate([
    Output()
], NtPictureComponent.prototype, "errors", void 0);
NtPictureComponent = NtPictureComponent_1 = __decorate([
    Component({
        selector: 'nt-picture',
        template: "<div class=\"nt-picture-item {{ shape }}\"\n  *ngFor=\"let item of _displayPictureRefs\"\n  [style.backgroundImage]=\"item.thumbnail ? 'url(' + item.thumbnail + ')' : 'unset'\"\n  [class.nt-upload-error]=\"item.status === 3\"\n  [class.nt-upload-success]=\"item.status === 2\">\n  <div class=\"nt-picture-action\" *ngIf=\"item.status !== 0 && item.status !== 1\">\n    <span class=\"nt-picture-symbol {{ icons.preview }}\" (click)=\"preview(item)\"></span>\n    <span *ngIf=\"!readonly && !disabled\" class=\"nt-picture-symbol {{ icons.remove }}\" (click)=\"_remove(item)\"></span>\n  </div>\n  <div class=\"nt-picture-progress\" *ngIf=\"item.status === 1\" [@fadeOut]>\n    <nt-progress *ngIf=\"item.status === 1\" [value]=\"item.progress\" size=\"tiny\" color=\"success\"></nt-progress>\n  </div>\n</div>\n<div class=\"nt-picture-add {{ shape }}\"\n  *ngIf=\"!notrigger\"\n  ntFileSelect\n  [accept]=\"accept\"\n  [limitSize]=\"limitSize\"\n  [multiple]=\"multiple\"\n  [disabled]=\"disabled || readonly\"\n  (select)=\"_select($event)\">\n  <span class=\"nt-picture-symbol {{ icons.add }}\"></span>\n</div>\n<ng-template #previewTemplate let-data>\n  <div class=\"nt-picture-preview\">\n    <img [src]=\"data.link || data.thumbnail\">\n  </div>\n</ng-template>\n",
        host: {
            'class': 'nt-picture',
            '[class.disabled]': 'disabled',
            '[class.readonly]': 'readonly'
        },
        encapsulation: ViewEncapsulation.None,
        providers: [
            { provide: NtFormFieldControl, useExisting: NtPictureComponent_1 }
        ],
        animations: [
            trigger('fade', [
                transition('* => void', fadeOut(.3)),
                transition('void => *', fadeIn(.3))
            ]),
            trigger('fadeOut', [
                transition('* => void', fadeOut(.3))
            ])
        ]
    }),
    __param(1, Optional()),
    __param(2, Optional()), __param(2, Self()),
    __param(3, Optional()), __param(3, Inject(NT_PICTURE_ICONS))
], NtPictureComponent);

var __decorate$1 = (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;
};
let NtPictureModule = class NtPictureModule {
};
NtPictureModule = __decorate$1([
    NgModule({
        imports: [
            CommonModule,
            NtFileModule,
            NtModalModule,
            NtProgressModule
        ],
        exports: [
            NtFileModule,
            NtPictureComponent
        ],
        declarations: [NtPictureComponent]
    })
], NtPictureModule);

export { DEFAULT_PICTURE_ICONS, NT_PICTURE_ACCEPTS, NT_PICTURE_ICONS, NtPictureComponent, NtPictureModule, NtPictureRef, zipImage };
//# sourceMappingURL=picture.js.map
