import { CommonModule } from '@angular/common';
import { InjectionToken, EventEmitter, Inject, Optional, Self, Input, Output, Component, ViewEncapsulation, NgModule } from '@angular/core';
import { findCategoryByFile, NtUploadRef, NtUploadResponse, NtUploadStatus, findCategoryByExtensions, NtUploadHandler, NT_UPLOAD_HANDLER, 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';

var 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',
};
var NT_ATTACHMENT_ICONS = new InjectionToken('nt-attachment-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;
};
var uniqueId = 0;
var NtAttachmentRef = (function (_super) {
    __extends(NtAttachmentRef, _super);
    function NtAttachmentRef(file, id) {
        if (id === void 0) { id = "nt-attachment-" + uniqueId++; }
        var _this = _super.call(this, file, file.name, file.size) || this;
        _this.file = file;
        _this.id = id;
        _this.category = findCategoryByFile(file) || 'default';
        return _this;
    }
    return NtAttachmentRef;
}(NtUploadRef));
var NtAttachmentComponent = (function (_super) {
    __extends(NtAttachmentComponent, _super);
    function NtAttachmentComponent(_uploadHandler, ngControl, icons) {
        var _this = _super.call(this) || this;
        _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 = function () { };
        _this._onTouched = function () { };
        if (_this.ngControl) {
            _this.ngControl.valueAccessor = _this;
        }
        _this.icons = __assign(__assign({}, DEFAULT_ATTACHMENT_ICONS), icons);
        return _this;
    }
    NtAttachmentComponent_1 = NtAttachmentComponent;
    Object.defineProperty(NtAttachmentComponent.prototype, "value", {
        get: function () { return this._attachmentRefs; },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtAttachmentComponent.prototype, "disabled", {
        get: function () { return this._disabled; },
        set: function (value) { this._disabled = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtAttachmentComponent.prototype, "readonly", {
        get: function () { return this._readonly; },
        set: function (value) { this._readonly = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtAttachmentComponent.prototype, "notrigger", {
        get: function () { return this._notrigger; },
        set: function (value) { this._notrigger = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtAttachmentComponent.prototype, "required", {
        get: function () { return this._required; },
        set: function (value) { this._required = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtAttachmentComponent.prototype, "accept", {
        get: function () { return this._accept; },
        set: function (value) {
            if (typeof value === 'string') {
                this._accept = value.replace(' ', '');
            }
            else {
                this._accept = value.join(',');
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtAttachmentComponent.prototype, "multiple", {
        get: function () { return this._multiple; },
        set: function (value) { this._multiple = coerceBooleanProperty(value); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NtAttachmentComponent.prototype, "limitSize", {
        get: function () { return this._limitSize; },
        set: function (value) { this._limitSize = coerceNumberProperty(value, 5); },
        enumerable: true,
        configurable: true
    });
    NtAttachmentComponent.prototype.ngOnInit = function () { };
    NtAttachmentComponent.prototype.ngOnDestroy = function () {
        this._destroy.next();
        this._destroy.complete();
        this.errors.complete();
    };
    NtAttachmentComponent.prototype.writeValue = function (value) {
        var _a, _b;
        if (value) {
            value = this._initValueCategoies(value);
            (_a = this._attachmentRefs).splice.apply(_a, __spread([0, this._attachmentRefs.length], value));
            (_b = this._displayAttachmentRefs).splice.apply(_b, __spread([0, this._displayAttachmentRefs.length], value));
        }
    };
    NtAttachmentComponent.prototype.registerOnChange = function (fn) {
        this._onChange = fn;
    };
    NtAttachmentComponent.prototype.registerOnTouched = function (fn) {
        this._onTouched = fn;
    };
    NtAttachmentComponent.prototype.setDisabledState = function (isDisabled) {
        this._disabled = isDisabled;
    };
    NtAttachmentComponent.prototype._select = function (files) {
        var _a;
        var _this = this;
        var attachmentRefs = files.map(function (file) { return _this._createAttachmentRef(file); });
        (_a = this._displayAttachmentRefs).push.apply(_a, __spread(attachmentRefs));
        this._onTouched && this._onTouched();
    };
    NtAttachmentComponent.prototype._remove = function (attachmentRef) {
        if (this.disabled) {
            return;
        }
        this._removeAttachmentRef(attachmentRef);
        this._onChange(this.value);
    };
    NtAttachmentComponent.prototype._createAttachmentRef = function (file) {
        var _this = this;
        var attachmentRef = new NtAttachmentRef(file);
        attachmentRef.subscription = this._uploadHandler
            .upload(this.url, attachmentRef)
            .pipe(takeUntil(this._destroy))
            .subscribe(function (event) { return _this._resolveUploadedResult(attachmentRef, event); });
        return attachmentRef;
    };
    NtAttachmentComponent.prototype._removeAttachmentRef = function (attachmentRef) {
        if (attachmentRef.subscription && !attachmentRef.subscription.closed) {
            attachmentRef.subscription.unsubscribe();
        }
        if (this._attachmentRefs.includes(attachmentRef)) {
            var index = this._attachmentRefs.indexOf(attachmentRef);
            this._attachmentRefs.splice(index, 1);
        }
        if (this._displayAttachmentRefs.includes(attachmentRef)) {
            var displayIndex = this._displayAttachmentRefs.indexOf(attachmentRef);
            this._displayAttachmentRefs.splice(displayIndex, 1);
        }
    };
    NtAttachmentComponent.prototype._resolveUploadedResult = function (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);
    };
    NtAttachmentComponent.prototype._initValueCategoies = function (attachmentRefs) {
        attachmentRefs.forEach(function (item) {
            item.category = findCategoryByExtensions(item.name) || 'default';
        });
        return attachmentRefs;
    };
    var NtAttachmentComponent_1;
    NtAttachmentComponent.ctorParameters = function () { return [
        { type: NtUploadHandler, decorators: [{ type: Inject, args: [NT_UPLOAD_HANDLER,] }] },
        { 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, Inject(NT_UPLOAD_HANDLER)),
        __param(1, Optional()), __param(1, Self()),
        __param(2, Optional()), __param(2, Inject(NT_ATTACHMENT_ICONS))
    ], NtAttachmentComponent);
    return NtAttachmentComponent;
}(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 NtAttachmentModule = (function () {
    function NtAttachmentModule() {
    }
    NtAttachmentModule = __decorate$1([
        NgModule({
            imports: [
                CommonModule,
                NtFileModule,
                NtProgressModule
            ],
            exports: [
                NtFileModule,
                NtAttachmentComponent
            ],
            declarations: [
                NtAttachmentComponent
            ]
        })
    ], NtAttachmentModule);
    return NtAttachmentModule;
}());

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