"use strict";
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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.RegistryItem = void 0;
var uuid_1 = require("uuid");
var custom_1 = require("../../custom");
var lodash_1 = require("../../shared/lodash");
var interface_1 = require("../../interface");
var ibsheet_1 = require("../../ibsheet");
var ibchart_1 = require("../../ibchart");
var ibmap_1 = require("../../ibmap");
var utils_1 = require("../utils");
var interface_2 = require("./interface");
var url_1 = require("./url");
var async_load_1 = require("./async-load");
var async_unload_1 = require("./async-unload");
var async_test_1 = require("./async-test");
var for_ibsheet_1 = require("../for-ibsheet");
var for_ibchart_1 = require("../for-ibchart");
var for_ibmap_1 = require("../for-ibmap");
var RegistryItem = (function (_super) {
    __extends(RegistryItem, _super);
    function RegistryItem(data) {
        var _this = _super.call(this) || this;
        _this._loaded = false;
        _this._urlOptions = {};
        _this._evtOptions = {};
        _this.error = null;
        _this.toString = function () {
            return _this.alias;
        };
        data = (0, utils_1.castRegistryItemData)(data);
        _this._updateUrls = [];
        _this.name = (0, lodash_1.get)(data, 'name');
        _this.update(data, false);
        if ((0, lodash_1.isNil)(_this.urls)) {
            throw new Error('required "url" or "urls" property');
        }
        if ((0, lodash_1.isNil)(_this.name)) {
            var firstUrl = (0, lodash_1.get)(_this.urls, 0);
            var name_1 = (0, lodash_1.get)(firstUrl, 'basename');
            if ((0, lodash_1.isNil)(name_1) || !name_1.length) {
                throw new Error("required name property, not found from url: ".concat(firstUrl.value));
            }
            _this.name = name_1;
        }
        _this.version = (0, lodash_1.get)(data, 'version', null);
        _this._id = (0, uuid_1.v1)();
        return _this;
    }
    Object.defineProperty(RegistryItem.prototype, "id", {
        get: function () {
            return this._id;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "name", {
        get: function () {
            return this._name;
        },
        set: function (value) {
            if ((0, lodash_1.isEmpty)(value))
                return;
            this._name = (0, lodash_1.trim)(value).toLowerCase();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "version", {
        get: function () {
            return this._version;
        },
        set: function (value) {
            this._version = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "hasVersion", {
        get: function () {
            return !(0, lodash_1.isNil)(this.version);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "alias", {
        get: function () {
            return (0, utils_1.castRegistryAlias)({
                name: this.name,
                version: this.version,
            });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "urls", {
        get: function () {
            return this._urls;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "updateUrls", {
        get: function () {
            return this._updateUrls;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "isResolveUpdateUrls", {
        get: function () {
            if (!this.changed)
                return true;
            return this._isResolveUpdateUrls;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "raw", {
        get: function () {
            var raw = {
                id: this.id,
                urls: this.urls.map(function (url) { return url.value; }),
                name: this.name,
                version: this.version,
                alias: this.alias,
                loaded: this.loaded,
            };
            if (!(0, lodash_1.isNil)(this.error)) {
                (0, lodash_1.set)(raw, 'error', this.error);
            }
            return raw;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "loaded", {
        get: function () {
            return this._loaded;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(RegistryItem.prototype, "changed", {
        get: function () {
            return !!this._updateUrls.length;
        },
        enumerable: false,
        configurable: true
    });
    RegistryItem.prototype._customEventHandle = function (name) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        var fn = this.getEventOption(name);
        if ((0, lodash_1.isNil)(fn))
            return;
        fn.apply(this, args);
    };
    RegistryItem.prototype._createUrls = function (data, isUpdate) {
        var _this = this;
        if (isUpdate === void 0) { isUpdate = false; }
        var targetOpts = (0, lodash_1.pick)(data, [
            'baseUrl',
            'url',
            'type',
            'target',
            'urls',
            'corefile',
            'theme',
            'plugins',
            'locale',
            'locales',
            'license',
            'highcharts',
            'dependentUrls',
        ]);
        if ((0, lodash_1.isEmpty)(targetOpts)) {
            return;
        }
        var bIBSheet = (0, ibsheet_1.isIBSheet)(this.name);
        var bIBChart = (0, ibchart_1.isIBChart)(this.name);
        var bIBMap = (0, ibmap_1.isIBMap)(this.name);
        var options = (0, lodash_1.defaultsDeep)(targetOpts, this._urlOptions);
        this._urlOptions = options;
        var hasUrl = (0, lodash_1.has)(options, 'url');
        var hasUrls = (0, lodash_1.has)(options, 'urls');
        if (hasUrl && hasUrls) {
            console.warn('ignore "url" property, cannot be used with the "urls"');
        }
        var urls;
        if (!bIBSheet && !bIBChart && !bIBMap) {
            urls = (0, lodash_1.get)(options, 'urls', (0, lodash_1.pick)(options, ['url', 'target', 'type']));
        }
        else {
            if (bIBSheet) {
                if (!isUpdate) {
                    urls = (0, for_ibsheet_1.defaultsIBSheetUrls)(data);
                }
                else {
                    urls = (0, for_ibsheet_1.updateIBSheetUrls)(this.urls, data);
                }
            }
            else if (bIBChart) {
                if (!isUpdate) {
                    urls = (0, for_ibchart_1.defaultsIBChartUrls)(data);
                }
                else {
                    urls = (0, for_ibchart_1.updateIBChartUrls)(this.urls, data);
                }
            }
            else if (bIBMap) {
                if (!isUpdate) {
                    urls = (0, for_ibmap_1.defaultsIBMapUrls)(data);
                }
                else {
                    urls = (0, for_ibmap_1.updateIBMapUrls)(this.urls, data);
                }
            }
        }
        if ((0, lodash_1.isEmpty)(urls))
            return;
        var baseUrl = (0, lodash_1.get)(options, 'baseUrl');
        var aResult = (0, lodash_1.castArray)(urls).map(function (data) {
            data = (0, utils_1.castRegistryItemData)(data);
            var url = data.url;
            if (!(0, lodash_1.isNil)(baseUrl) && !/^\w+:\/\//.test(url)) {
                (0, lodash_1.set)(data, 'url', [(0, lodash_1.trim)(baseUrl).replace(/\/$/, ''), (0, lodash_1.trim)(url).replace(/^\//, '')].join('/'));
            }
            var uItem = new url_1.RegistryItemURL(data);
            var basename = uItem.basename;
            if (/^ibsheet-[\w]+$/.test(basename)) {
                uItem.dependencies = ['ibsheet'];
            }
            var IBSHEET_GLOBAL = ibsheet_1.IBSheet8GlobalInstance.name;
            var validateIBSheet8CommonPlugins = function () {
                var suffix = basename.replace(/^ibsheet-/, '');
                var sPath = "".concat(IBSHEET_GLOBAL, ".Plugins.PluginVers.ib").concat(suffix);
                return !(0, lodash_1.isNil)((0, lodash_1.get)(window, sPath));
            };
            switch (basename) {
                case 'ibsheet':
                case 'ibchart':
                case 'ibmap':
                    uItem.validate = _this.getEventOption('validate', null);
                    break;
                case 'ibsheet-excel':
                    uItem.validate = function () {
                        if (validateIBSheet8CommonPlugins())
                            return true;
                        return !(0, lodash_1.isNil)((0, lodash_1.get)(window, "".concat(IBSHEET_GLOBAL, ".down2Excel")));
                    };
                    break;
                case 'ibsheet-common':
                case 'ibsheet-dialog':
                    uItem.validate = validateIBSheet8CommonPlugins;
                    break;
            }
            return uItem;
        });
        return aResult;
    };
    RegistryItem.prototype._setUrls = function (data, isUpdate) {
        if (isUpdate === void 0) { isUpdate = false; }
        var urls = this._createUrls(data, isUpdate);
        if ((0, lodash_1.isNil)(urls))
            return;
        if (isUpdate) {
            this._updateUrls = urls;
            return;
        }
        this._urls = urls;
    };
    RegistryItem.prototype._setEventOptions = function (data) {
        var targetOpts = (0, lodash_1.pick)(data, [
            interface_2.RegItemEventName.VALIDATE,
            interface_2.RegItemEventName.LOAD,
            interface_2.RegItemEventName.UNLOAD,
            interface_2.RegItemEventName.DEPENDENT_URLS,
        ]);
        if ((0, lodash_1.isEmpty)(targetOpts)) {
            return;
        }
        this._evtOptions = (0, lodash_1.defaultsDeep)(targetOpts, this._evtOptions);
    };
    RegistryItem.prototype._asyncImportUrls = function (eventData, options) {
        var _this = this;
        async_load_1.asyncImportItemUrls
            .call(this, options)
            .then(function () {
            async_test_1.asyncItemTest
                .call(_this, options)
                .then(function () {
                _this._loaded = true;
                _this.emit(interface_1.LoaderEventName.LOADED, eventData);
            })
                .catch(function () {
                _this.emit(interface_1.LoaderEventName.LOAD_FAILED, eventData);
            });
        })
            .catch(function (err) {
            _this.emit(interface_1.LoaderEventName.LOAD_REJECT, (0, lodash_1.assignIn)(eventData, err));
        });
    };
    RegistryItem.prototype.getEventOption = function (name, def) {
        return (0, lodash_1.get)(this._evtOptions, name, def);
    };
    RegistryItem.prototype.hasEventOption = function (name) {
        return !(0, lodash_1.isNil)((0, lodash_1.get)(this._evtOptions, name));
    };
    RegistryItem.prototype.setEventOption = function (name, value) {
        (0, lodash_1.set)(this._evtOptions, name, value);
    };
    RegistryItem.prototype.resolveUpdateUrls = function (callback) {
        if (this.isResolveUpdateUrls)
            return;
        this._isResolveUpdateUrls = true;
        this.once(interface_1.LoaderEventName.LOADED, callback);
    };
    RegistryItem.prototype.clearUpdateUrls = function () {
        if (!this.changed)
            return;
        this._urls = this._updateUrls.slice();
        this._updateUrls = [];
        this._isResolveUpdateUrls = false;
    };
    RegistryItem.prototype.update = function (data, isUpdate) {
        var _this = this;
        if (isUpdate === void 0) { isUpdate = true; }
        if ((0, lodash_1.isNil)(data))
            return;
        data = (0, utils_1.castRegistryItemData)(data);
        this._setUrls(data, isUpdate);
        this._setEventOptions(data);
        this._urls = (0, lodash_1.sortBy)(this._urls, function (url) {
            var nOrder;
            var type = url.type, value = url.value;
            var corefile = (0, lodash_1.get)(_this._urlOptions, 'corefile', 'ibsheet.js');
            if (type === 'css') {
                nOrder = 1;
            }
            else if ((0, ibsheet_1.isIBSheet)(_this.name)) {
                if ((0, lodash_1.includes)(value, 'ibleaders.js'))
                    nOrder = 3;
                else if ((0, lodash_1.includes)(value, 'locale/'))
                    nOrder = 4;
                else if ((0, lodash_1.includes)(value, corefile))
                    nOrder = 5;
                else
                    nOrder = 6;
            }
            else {
                nOrder = 2;
            }
            return nOrder;
        });
    };
    RegistryItem.prototype.test = function () {
        var aResult = this.urls.map(function (uItem) {
            var validate = uItem.validate;
            if ((0, lodash_1.isNil)(validate))
                return true;
            return validate.call(window);
        });
        return (0, lodash_1.every)(aResult);
    };
    RegistryItem.prototype.load = function (options) {
        var eventData = { target: this };
        this.clearUpdateUrls();
        try {
            this._customEventHandle('load', {
                type: interface_1.LoaderEventName.LOADED,
                target: this,
            });
        }
        catch (err) {
            throw new Error(err);
        }
        this.emit(interface_1.LoaderEventName.LOAD, eventData);
        this._asyncImportUrls(eventData, options);
        return this;
    };
    RegistryItem.prototype.unload = function (options) {
        var _this = this;
        var eventData = { target: this };
        this.emit(interface_1.LoaderEventName.UNLOAD, eventData);
        try {
            this._customEventHandle('unload', {
                type: interface_1.LoaderEventName.UNLOAD,
                target: this,
            });
        }
        catch (err) {
            throw new Error(err);
        }
        async_unload_1.asyncRemoveItemUrls
            .call(this, options)
            .then(function () {
            _this._loaded = false;
            _this.emit(interface_1.LoaderEventName.UNLOADED, eventData);
        })
            .catch(function (err) {
            _this.emit(interface_1.LoaderEventName.UNLOAD_FAILED, (0, lodash_1.assignIn)(eventData, {
                error: err,
            }));
        });
        return this;
    };
    return RegistryItem;
}(custom_1.CustomEventEmitter));
exports.RegistryItem = RegistryItem;
exports.default = RegistryItem;
//# sourceMappingURL=item.js.map