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';

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

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
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 __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spread = (this && this.__spread) || function () {
    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
    return ar;
};
function zipImage(file, option) {
    if (option === void 0) { option = { maxWidth: 1080, orientation: true, canvas: true }; }
    return new Promise(function (resolve, reject) {
        loadImage(file, function (canvas) {
            if (canvas.toBlob) {
                canvas.toBlob(function (blob) {
                    var thumbnail = canvas.toDataURL('image/png');
                    blob.lastModifiedDate = new Date();
                    blob.lastModified = blob.lastModifiedDate.getTime();
                    resolve({ thumbnail: thumbnail, blob: blob });
                });
            }
            else {
                reject('HTMLCanvasElement toBlob function is undefined');
            }
        }, option);
    });
}
var uniqueId = 0;
var NT_PICTURE_ACCEPTS = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/bmp'];
var NtPictureRef = (function (_super) {
    __extends(NtPictureRef, _super);
    function NtPictureRef(file, id) {
        if (id === void 0) { id = "nt-picture-" + uniqueId++; }
        var _this = _super.call(this, file, file.name, file.size) || this;
        _this.file = file;
        _this.id = id;
        return _this;
    }
    return NtPictureRef;
}(NtUploadRef));
var NtPictureComponent = (function (_super) {
    __extends(NtPictureComponent, _super);
    function NtPictureComponent(_modal, _uploadHandler, ngControl, icons) {
        var _this = _super.call(this) || this;
        _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 = function () { };
        _this._onTouched = function () { };
        console.log(_uploadHandler);
        if (_this.ngControl) {
            _this.ngControl.valueAccessor = _this;
        }
        _this.icons = __assign(__assign({}, DEFAULT_PICTURE_ICONS), icons);
        return _this;
    }
    NtPictureComponent_1 = NtPictureComponent;
    Object.defineProperty(NtPictureComponent.prototype, "value", {
        get: function () { return this._pictureRefs; },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtPictureComponent.prototype, "disabled", {
        get: function () { return this._disabled; },
        set: function (value) { this._disabled = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtPictureComponent.prototype, "readonly", {
        get: function () { return this._readonly; },
        set: function (value) { this._readonly = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtPictureComponent.prototype, "notrigger", {
        get: function () { return this._notrigger; },
        set: function (value) { this._notrigger = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtPictureComponent.prototype, "required", {
        get: function () { return this._required; },
        set: function (value) { this._required = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtPictureComponent.prototype, "accept", {
        get: function () { return this._accept; },
        set: function (value) {
            if (typeof value === 'string') {
                if (value === '*') {
                    this._accept = NT_PICTURE_ACCEPTS.join(',');
                }
                else {
                    this._accept = value.replace(' ', '');
                }
            }
            else {
                this._accept = value.join(',');
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtPictureComponent.prototype, "multiple", {
        get: function () { return this._multiple; },
        set: function (value) { this._multiple = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtPictureComponent.prototype, "limitSize", {
        get: function () { return this._limitSize; },
        set: function (value) { this._limitSize = coerceNumberProperty(value, 5); },
        enumerable: true,
        configurable: true
    });
    NtPictureComponent.prototype.ngOnInit = function () { };
    NtPictureComponent.prototype.ngOnDestroy = function () {
        this._destroy.next();
        this._destroy.complete();
        this.errors.complete();
    };
    NtPictureComponent.prototype.writeValue = function (value) {
        var _a, _b;
        if (value) {
            (_a = this._pictureRefs).splice.apply(_a, __spread([0, this._pictureRefs.length], value));
            (_b = this._displayPictureRefs).splice.apply(_b, __spread([0, this._displayPictureRefs.length], value));
        }
    };
    NtPictureComponent.prototype.registerOnChange = function (fn) {
        this._onChange = fn;
    };
    NtPictureComponent.prototype.registerOnTouched = function (fn) {
        this._onTouched = fn;
    };
    NtPictureComponent.prototype.setDisabledState = function (isDisabled) {
        this._disabled = isDisabled;
    };
    NtPictureComponent.prototype.preview = function (pictureRef) {
        this._modal.open(this.previewTemplate, {
            data: pictureRef,
            centerVertically: true,
            maxWidth: '90vw',
            maxHeight: '90vh',
            width: 'auto',
            transparent: true
        });
    };
    NtPictureComponent.prototype._select = function (files) {
        var _a;
        var _this = this;
        var pictureRefs = files.map(function (file) { return _this._createPictureRef(file); });
        (_a = this._displayPictureRefs).push.apply(_a, __spread(pictureRefs));
        this._onTouched && this._onTouched();
    };
    NtPictureComponent.prototype._remove = function (pictureRef) {
        if (this.disabled) {
            return;
        }
        this._removePictureRef(pictureRef);
        this._onChange(this.value);
    };
    NtPictureComponent.prototype._createPictureRef = function (file) {
        var _this = this;
        var pictureRef = new NtPictureRef(file);
        zipImage(file).then(function (data) { return pictureRef.thumbnail = data.thumbnail; });
        pictureRef.subscription = this._uploadHandler
            .upload(this.url, pictureRef)
            .pipe(takeUntil(this._destroy))
            .subscribe(function (event) { return _this._resolveUploadedResult(pictureRef, event); });
        return pictureRef;
    };
    NtPictureComponent.prototype._removePictureRef = function (pictureRef) {
        if (pictureRef.subscription && !pictureRef.subscription.closed) {
            pictureRef.subscription.unsubscribe();
        }
        if (this._pictureRefs.includes(pictureRef)) {
            var index = this._pictureRefs.indexOf(pictureRef);
            this._pictureRefs.splice(index, 1);
        }
        if (this._displayPictureRefs.includes(pictureRef)) {
            var displayIndex = this._displayPictureRefs.indexOf(pictureRef);
            this._displayPictureRefs.splice(displayIndex, 1);
        }
    };
    NtPictureComponent.prototype._resolveUploadedResult = function (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);
    };
    var NtPictureComponent_1;
    NtPictureComponent.ctorParameters = function () { return [
        { 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);
    return NtPictureComponent;
}(NtFormFieldControl));

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

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