import { CommonModule } from '@angular/common';
import { InjectionToken, EventEmitter, Optional, Self, Inject, Input, Output, Component, ViewEncapsulation, NgModule } from '@angular/core';
import { NtUploadRef, findCategoryByFile, NtUploadResponse, NtUploadStatus, findCategoryByExtensions, NtUploadHandler, fadeOut, NtFileModule } from '@ng-tangram/components/core';
import { NtProgressModule } from '@ng-tangram/components/progress';
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_ATTACHMENT_ICONS = {
    default: 'far fa-file-alt',
    archive: 'far fa-file-archive',
    code: 'far fa-file-code',
    image: 'far fa-file-image',
    audio: 'far fa-file-audio',
    video: 'far fa-file-video',
    pdf: 'far fa-file-pdf',
    word: 'far fa-file-word',
    excel: 'far fa-file-excel',
    ppt: 'far fa-file-powerpoint',
    csv: 'far fa-file-csv',
};
const NT_ATTACHMENT_ICONS = new InjectionToken('nt-attachment-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 NtAttachmentComponent_1;
let uniqueId = 0;
class NtAttachmentRef extends NtUploadRef {
    constructor(file, id = `nt-attachment-${uniqueId++}`) {
        super(file, file.name, file.size);
        this.file = file;
        this.id = id;
        this.category = findCategoryByFile(file) || 'default';
    }
}
let NtAttachmentComponent = NtAttachmentComponent_1 = class NtAttachmentComponent extends NtFormFieldControl {
    constructor(_uploadHandler, ngControl, icons) {
        super();
        this._uploadHandler = _uploadHandler;
        this.ngControl = ngControl;
        this.icons = icons;
        this._destroy = new Subject();
        this._displayAttachmentRefs = [];
        this._attachmentRefs = [];
        this._disabled = false;
        this._readonly = false;
        this._notrigger = false;
        this._required = false;
        this._accept = '*';
        this._multiple = true;
        this._limitSize = Number.MAX_VALUE;
        this.url = '';
        this.name = '';
        this.errors = new EventEmitter();
        this._onChange = () => { };
        this._onTouched = () => { };
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        this.icons = Object.assign(Object.assign({}, DEFAULT_ATTACHMENT_ICONS), icons);
    }
    get value() { return this._attachmentRefs; }
    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); }
    set accept(value) {
        if (typeof value === 'string') {
            this._accept = value.replace(' ', '');
        }
        else {
            this._accept = value.join(',');
        }
    }
    get accept() { return this._accept; }
    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) {
            value = this._initValueCategoies(value);
            this._attachmentRefs.splice(0, this._attachmentRefs.length, ...value);
            this._displayAttachmentRefs.splice(0, this._displayAttachmentRefs.length, ...value);
        }
    }
    registerOnChange(fn) {
        this._onChange = fn;
    }
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    setDisabledState(isDisabled) {
        this._disabled = isDisabled;
    }
    _select(files) {
        const attachmentRefs = files.map(file => this._createAttachmentRef(file));
        this._displayAttachmentRefs.push(...attachmentRefs);
        this._onTouched && this._onTouched();
    }
    _remove(attachmentRef) {
        if (this.disabled) {
            return;
        }
        this._removeAttachmentRef(attachmentRef);
        this._onChange(this.value);
    }
    _createAttachmentRef(file) {
        const attachmentRef = new NtAttachmentRef(file);
        attachmentRef.subscription = this._uploadHandler
            .upload(this.url, attachmentRef)
            .pipe(takeUntil(this._destroy))
            .subscribe(event => this._resolveUploadedResult(attachmentRef, event));
        return attachmentRef;
    }
    _removeAttachmentRef(attachmentRef) {
        if (attachmentRef.subscription && !attachmentRef.subscription.closed) {
            attachmentRef.subscription.unsubscribe();
        }
        if (this._attachmentRefs.includes(attachmentRef)) {
            const index = this._attachmentRefs.indexOf(attachmentRef);
            this._attachmentRefs.splice(index, 1);
        }
        if (this._displayAttachmentRefs.includes(attachmentRef)) {
            const displayIndex = this._displayAttachmentRefs.indexOf(attachmentRef);
            this._displayAttachmentRefs.splice(displayIndex, 1);
        }
    }
    _resolveUploadedResult(attachmentRef, event) {
        if (event instanceof NtUploadResponse) {
            attachmentRef.data = event.data;
            this._attachmentRefs.push(attachmentRef);
        }
        else {
            attachmentRef.status = NtUploadStatus.ERROR;
            attachmentRef.error = event.error;
            attachmentRef.progress = 100;
            this.errors.next(event.error);
        }
        this._onChange(this.value);
    }
    _initValueCategoies(attachmentRefs) {
        attachmentRefs.forEach(item => {
            item.category = findCategoryByExtensions(item.name) || 'default';
        });
        return attachmentRefs;
    }
};
NtAttachmentComponent.ctorParameters = () => [
    { type: NtUploadHandler, decorators: [{ type: Optional }] },
    { type: NgControl, decorators: [{ type: Optional }, { type: Self }] },
    { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NT_ATTACHMENT_ICONS,] }] }
];
__decorate([
    Input()
], NtAttachmentComponent.prototype, "disabled", null);
__decorate([
    Input()
], NtAttachmentComponent.prototype, "readonly", null);
__decorate([
    Input()
], NtAttachmentComponent.prototype, "notrigger", null);
__decorate([
    Input()
], NtAttachmentComponent.prototype, "required", null);
__decorate([
    Input()
], NtAttachmentComponent.prototype, "accept", null);
__decorate([
    Input()
], NtAttachmentComponent.prototype, "multiple", null);
__decorate([
    Input()
], NtAttachmentComponent.prototype, "limitSize", null);
__decorate([
    Input()
], NtAttachmentComponent.prototype, "url", void 0);
__decorate([
    Input()
], NtAttachmentComponent.prototype, "name", void 0);
__decorate([
    Output()
], NtAttachmentComponent.prototype, "errors", void 0);
NtAttachmentComponent = NtAttachmentComponent_1 = __decorate([
    Component({
        selector: 'nt-attachment, [nt-attachment]',
        template: "<a class=\"nt-attachment-trigger\"\n  *ngIf=\"!notrigger\"\n  ntFileSelect\n  [limitSize]=\"limitSize\"\n  [multiple]=\"multiple\"\n  [disabled]=\"disabled || readonly\"\n  (select)=\"_select($event)\">\n  <ng-content></ng-content>\n</a>\n<div class=\"nt-attachment-list\">\n  <div class=\"nt-attachment-item\" *ngFor=\"let item of _displayAttachmentRefs\" [@fadeOut]>\n    <div class=\"nt-attachment-task grid-x\"\n    [class.success]=\"item.status === 2\"\n    [class.error]=\"item.status === 3\">\n      <div class=\"nt-attachment-symbol cell shrink\">\n        <span [class]=\"icons[item.category]\"></span>\n      </div>\n      <div class=\"task-info cell auto\">\n        <a class=\"task-name\" [attr.href]=\"item.link\" target=\"_blank\">{{item.name}}</a>\n        <span *ngIf=\"item.size\">{{ item.size | filesize | uppercase }}</span>\n        <span class=\"task-error\" *ngIf=\"item.error\">Error&nbsp;-&nbsp;{{item.error}}</span>\n      </div>\n      <div class=\"task-action cell shrink\"\n        *ngIf=\"!disabled && !readonly\"\n        (click)=\"_remove(item)\">\n        <span aria-hidden=\"true\">&times;</span>\n      </div>\n    </div>\n    <nt-progress class=\"nt-attachment-progress\"\n      *ngIf=\"item.status === 1\"\n      [class.success]=\"item.status === 2\"\n      [class.alert]=\"item.status === 3\"\n      [value]=\"item.progress\"\n      size=\"tiny\"\n      [@fadeOut]></nt-progress>\n  </div>\n</div>\n",
        host: {
            'class': 'nt-attachment',
            '[class.disabled]': 'disabled',
            '[class.readonly]': 'readonly'
        },
        encapsulation: ViewEncapsulation.None,
        providers: [
            { provide: NtFormFieldControl, useExisting: NtAttachmentComponent_1 }
        ],
        animations: [
            trigger('fadeOut', [
                transition('* => void', fadeOut(.3))
            ])
        ]
    }),
    __param(0, Optional()),
    __param(1, Optional()), __param(1, Self()),
    __param(2, Optional()), __param(2, Inject(NT_ATTACHMENT_ICONS))
], NtAttachmentComponent);

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

export { DEFAULT_ATTACHMENT_ICONS, NT_ATTACHMENT_ICONS, NtAttachmentComponent, NtAttachmentModule, NtAttachmentRef };
//# sourceMappingURL=attachment.js.map
