"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultViewerInitCommand = void 0;
var tslib_1 = require("tslib");
var common_1 = require("../api/common");
var i18n_1 = require("../api/i18n");
var string_1 = require("../utils/string");
var client_1 = require("../api/client");
var init_1 = require("./init");
var request_builder_1 = require("../api/request-builder");
var logger_1 = require("../utils/logger");
var error_1 = require("../api/error");
var projections_1 = require("../api/registry/projections");
var proj4_1 = require("ol/proj/proj4");
var proj4_2 = tslib_1.__importDefault(require("proj4"));
var init_command_1 = require("./init-command");
var command_spec_1 = require("../api/registry/command-spec");
var session_store_1 = require("../api/session-store");
var constants_1 = require("../constants");
var command_1 = require("../api/registry/command");
var url_1 = require("../utils/url");
var assert_1 = require("../utils/assert");
var lazy_1 = require("../api/lazy");
var type_guards_1 = require("../utils/type-guards");
var units_1 = require("../utils/units");
var scoped_id_1 = require("../utils/scoped-id");
var site_version_1 = require("../utils/site-version");
var TYPE_SUBJECT = "SubjectLayer";
var TYPE_EXTERNAL = "External";
var scopedId = new scoped_id_1.ScopedId();
/**
 * Default viewer init commmand
 *
 * @since 0.14
 */
var DefaultViewerInitCommand = /** @class */ (function (_super) {
    tslib_1.__extends(DefaultViewerInitCommand, _super);
    function DefaultViewerInitCommand(dispatch) {
        return _super.call(this, dispatch) || this;
    }
    DefaultViewerInitCommand.prototype.attachClient = function (client) {
        this.client = client;
    };
    DefaultViewerInitCommand.prototype.isArbitraryCoordSys = function (subject) {
        if (subject) {
            if ((0, type_guards_1.isRuntimeMap)(subject)) {
                var arbCs = (0, units_1.tryParseArbitraryCs)(subject.CoordinateSystem.MentorCode);
                return arbCs != null;
            }
        }
        return false;
    };
    /**
     * @override
     * @protected
     * @param {Dictionary<RuntimeMap>} mapsByName
     * @memberof MgViewerInitCommand
     */
    DefaultViewerInitCommand.prototype.establishInitialMapNameAndSession = function (mapsByName) {
        var firstMapName = "";
        var firstSessionId = "";
        for (var mapName in mapsByName) {
            if (!firstMapName && !firstSessionId) {
                var map = mapsByName[mapName];
                if ((0, type_guards_1.isRuntimeMap)(map)) {
                    firstMapName = map.Name;
                    firstSessionId = map.SessionId;
                    break;
                }
            }
        }
        return [firstMapName, firstSessionId];
    };
    DefaultViewerInitCommand.prototype.getDesiredTargetMapName = function (mapDef) {
        var lastSlash = mapDef.lastIndexOf("/");
        var lastDot = mapDef.lastIndexOf(".");
        if (lastSlash >= 0 && lastDot >= 0 && lastDot > lastSlash) {
            return "".concat(mapDef.substring(lastSlash + 1, lastDot));
        }
        else {
            return "Map_".concat(scopedId.next());
        }
    };
    DefaultViewerInitCommand.prototype.initFromWebLayoutAsync = function (webLayout, session, sessionWasReused) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var _b, mapsByName, warnings, _c, locale, featureTooltipsEnabled, externalBaseLayers, cmdsByKey, mainToolbar, taskBar, contextMenu, config, initialView, maps, _d, firstMapName, firstSessionId, mapName, map, menus, tb;
            var _this = this;
            return tslib_1.__generator(this, function (_e) {
                switch (_e.label) {
                    case 0: return [4 /*yield*/, this.createRuntimeMapsAsync(session, webLayout, false, function (wl) { return [{ name: _this.getDesiredTargetMapName(wl.Map.ResourceId), mapDef: wl.Map.ResourceId, metadata: {} }]; }, function () { return []; }, sessionWasReused)];
                    case 1:
                        _b = _e.sent(), mapsByName = _b[0], warnings = _b[1];
                        _c = this.options, locale = _c.locale, featureTooltipsEnabled = _c.featureTooltipsEnabled, externalBaseLayers = _c.externalBaseLayers;
                        cmdsByKey = (0, command_spec_1.parseCommandsInWebLayout)(webLayout, command_1.registerCommand);
                        mainToolbar = (webLayout.ToolBar.Visible
                            ? (0, command_spec_1.convertWebLayoutUIItems)(webLayout.ToolBar.Button, cmdsByKey, locale)
                            : []);
                        taskBar = (webLayout.TaskPane.TaskBar.Visible
                            ? (0, command_spec_1.convertWebLayoutUIItems)(webLayout.TaskPane.TaskBar.MenuButton, cmdsByKey, locale, false)
                            : []);
                        contextMenu = (webLayout.ContextMenu.Visible
                            ? (0, command_spec_1.convertWebLayoutUIItems)(webLayout.ContextMenu.MenuItem, cmdsByKey, locale, false)
                            : []);
                        config = {};
                        if (webLayout.SelectionColor != null) {
                            config.selectionColor = webLayout.SelectionColor;
                        }
                        if (webLayout.MapImageFormat != null) {
                            config.imageFormat = webLayout.MapImageFormat;
                        }
                        if (webLayout.SelectionImageFormat != null) {
                            config.selectionImageFormat = webLayout.SelectionImageFormat;
                        }
                        if (webLayout.PointSelectionBuffer != null) {
                            config.pointSelectionBuffer = webLayout.PointSelectionBuffer;
                        }
                        initialView = null;
                        if (webLayout.Map.InitialView != null) {
                            initialView = {
                                x: webLayout.Map.InitialView.CenterX,
                                y: webLayout.Map.InitialView.CenterY,
                                scale: webLayout.Map.InitialView.Scale
                            };
                        }
                        if (webLayout.Title != "") {
                            document.title = webLayout.Title || document.title;
                        }
                        maps = {};
                        _d = this.establishInitialMapNameAndSession(mapsByName), firstMapName = _d[0], firstSessionId = _d[1];
                        for (mapName in mapsByName) {
                            map = mapsByName[mapName];
                            maps[mapName] = {
                                mapGroupId: mapName,
                                map: map,
                                externalBaseLayers: (_a = this.options.externalBaseLayers) !== null && _a !== void 0 ? _a : [],
                                initialView: initialView
                            };
                        }
                        menus = {};
                        menus[constants_1.WEBLAYOUT_TOOLBAR] = {
                            items: mainToolbar
                        };
                        menus[constants_1.WEBLAYOUT_TASKMENU] = {
                            items: taskBar
                        };
                        menus[constants_1.WEBLAYOUT_CONTEXTMENU] = {
                            items: contextMenu
                        };
                        tb = (0, command_spec_1.prepareSubMenus)(menus)[0];
                        return [2 /*return*/, {
                                activeMapName: firstMapName,
                                featureTooltipsEnabled: featureTooltipsEnabled,
                                initialUrl: (0, url_1.ensureParameters)(webLayout.TaskPane.InitialTask || "server/TaskPane.html", firstMapName, firstSessionId, locale),
                                initialTaskPaneWidth: webLayout.TaskPane.Width,
                                initialInfoPaneWidth: webLayout.InformationPane.Width,
                                maps: maps,
                                locale: locale,
                                config: config,
                                capabilities: {
                                    hasTaskPane: webLayout.TaskPane.Visible,
                                    hasTaskBar: webLayout.TaskPane.TaskBar.Visible,
                                    hasStatusBar: webLayout.StatusBar.Visible,
                                    hasNavigator: webLayout.ZoomControl.Visible,
                                    hasSelectionPanel: webLayout.InformationPane.Visible && webLayout.InformationPane.PropertiesVisible,
                                    hasLegend: webLayout.InformationPane.Visible && webLayout.InformationPane.LegendVisible,
                                    hasToolbar: webLayout.ToolBar.Visible,
                                    hasViewSize: webLayout.StatusBar.Visible
                                },
                                toolbars: tb,
                                warnings: warnings,
                                initialActiveTool: common_1.ActiveMapTool.Pan
                            }];
                }
            });
        });
    };
    DefaultViewerInitCommand.prototype.createRuntimeMap = function (options, siteVersion) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var map, sv;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        (0, assert_1.assertIsDefined)(this.client);
                        return [4 /*yield*/, siteVersion.getValueAsync()];
                    case 1:
                        sv = _a.sent();
                        if (!(0, site_version_1.canUseQueryMapFeaturesV4)((0, site_version_1.parseSiteVersion)(sv.Version))) return [3 /*break*/, 3];
                        return [4 /*yield*/, this.client.createRuntimeMap_v4(options)];
                    case 2:
                        map = _a.sent();
                        return [3 /*break*/, 5];
                    case 3: return [4 /*yield*/, this.client.createRuntimeMap(options)];
                    case 4:
                        map = _a.sent();
                        _a.label = 5;
                    case 5: return [2 /*return*/, map];
                }
            });
        });
    };
    DefaultViewerInitCommand.prototype.describeRuntimeMap = function (options, siteVersion) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var map, sv;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        (0, assert_1.assertIsDefined)(this.client);
                        return [4 /*yield*/, siteVersion.getValueAsync()];
                    case 1:
                        sv = _a.sent();
                        if (!(0, site_version_1.canUseQueryMapFeaturesV4)((0, site_version_1.parseSiteVersion)(sv.Version))) return [3 /*break*/, 3];
                        return [4 /*yield*/, this.client.describeRuntimeMap_v4(options)];
                    case 2:
                        map = _a.sent();
                        return [3 /*break*/, 5];
                    case 3: return [4 /*yield*/, this.client.describeRuntimeMap(options)];
                    case 4:
                        map = _a.sent();
                        _a.label = 5;
                    case 5: return [2 /*return*/, map];
                }
            });
        });
    };
    DefaultViewerInitCommand.prototype.tryDescribeRuntimeMapAsync = function (mapName, session, mapDef, siteVersion) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var map, _a, e_1, map, _b;
            var _c, _d;
            return tslib_1.__generator(this, function (_e) {
                switch (_e.label) {
                    case 0:
                        (0, assert_1.assertIsDefined)(this.client);
                        _e.label = 1;
                    case 1:
                        _e.trys.push([1, 4, , 8]);
                        _a = this.describeRuntimeMap;
                        _c = {
                            mapname: mapName,
                            requestedFeatures: request_builder_1.RuntimeMapFeatureFlags.LayerFeatureSources | request_builder_1.RuntimeMapFeatureFlags.LayerIcons | request_builder_1.RuntimeMapFeatureFlags.LayersAndGroups
                        };
                        return [4 /*yield*/, session.getValueAsync()];
                    case 2: return [4 /*yield*/, _a.apply(this, [(_c.session = _e.sent(),
                                _c), siteVersion])];
                    case 3:
                        map = _e.sent();
                        return [2 /*return*/, map];
                    case 4:
                        e_1 = _e.sent();
                        if (!(e_1.message === "MgResourceNotFoundException")) return [3 /*break*/, 7];
                        _b = this.createRuntimeMap;
                        _d = {
                            mapDefinition: mapDef,
                            requestedFeatures: request_builder_1.RuntimeMapFeatureFlags.LayerFeatureSources | request_builder_1.RuntimeMapFeatureFlags.LayerIcons | request_builder_1.RuntimeMapFeatureFlags.LayersAndGroups
                        };
                        return [4 /*yield*/, session.getValueAsync()];
                    case 5: return [4 /*yield*/, _b.apply(this, [(_d.session = _e.sent(),
                                _d.targetMapName = mapName,
                                _d), siteVersion])];
                    case 6:
                        map = _e.sent();
                        return [2 /*return*/, map];
                    case 7: throw e_1;
                    case 8: return [2 /*return*/];
                }
            });
        });
    };
    DefaultViewerInitCommand.prototype.createRuntimeMapsAsync = function (session, res, isStateless, mapDefSelector, projectionSelector, sessionWasReused) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var mapDefs, mapPromises, warnings, locale, subjectLayers, fetchEpsgs, siteVersion, _i, mapDefs_1, m, siteVer, proj, _b, _1, epsg, _c, mapDefs_2, m, _d, _e, _f, maps, _g, maps_1, m, epsg, mapDef, arbCs, extraEpsgs, _h, extraEpsgs_1, e, epsgs, mapsByName, _j, maps_2, map, _k, mapDefs_3, gs;
            var _l;
            var _this = this;
            return tslib_1.__generator(this, function (_m) {
                switch (_m.label) {
                    case 0:
                        mapDefs = mapDefSelector(res);
                        mapPromises = [];
                        warnings = [];
                        locale = this.options.locale;
                        subjectLayers = {};
                        fetchEpsgs = [];
                        siteVersion = new lazy_1.AsyncLazy(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                            var sv;
                            return tslib_1.__generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        (0, assert_1.assertIsDefined)(this.client);
                                        return [4 /*yield*/, this.client.getSiteVersion()];
                                    case 1:
                                        sv = _a.sent();
                                        return [2 /*return*/, sv];
                                }
                            });
                        }); });
                        if (!isStateless) return [3 /*break*/, 6];
                        _i = 0, mapDefs_1 = mapDefs;
                        _m.label = 1;
                    case 1:
                        if (!(_i < mapDefs_1.length)) return [3 /*break*/, 5];
                        m = mapDefs_1[_i];
                        if (!(0, init_command_1.isMapDefinition)(m)) return [3 /*break*/, 3];
                        return [4 /*yield*/, siteVersion.getValueAsync()];
                    case 2:
                        siteVer = _m.sent();
                        (0, assert_1.assertIsDefined)(this.client);
                        mapPromises.push(this.describeRuntimeMapStateless(this.client, siteVer.Version, m));
                        return [3 /*break*/, 4];
                    case 3:
                        proj = (_a = m.meta) === null || _a === void 0 ? void 0 : _a.projection;
                        if (!(0, string_1.strIsNullOrEmpty)(proj)) {
                            _b = proj.split(':'), _1 = _b[0], epsg = _b[1];
                            if (!proj4_2.default.defs["EPSG:".concat(epsg)]) {
                                fetchEpsgs.push({ epsg: epsg, mapDef: m.name });
                            }
                        }
                        _m.label = 4;
                    case 4:
                        _i++;
                        return [3 /*break*/, 1];
                    case 5: return [3 /*break*/, 11];
                    case 6:
                        _c = 0, mapDefs_2 = mapDefs;
                        _m.label = 7;
                    case 7:
                        if (!(_c < mapDefs_2.length)) return [3 /*break*/, 11];
                        m = mapDefs_2[_c];
                        if (!(0, init_command_1.isMapDefinition)(m)) return [3 /*break*/, 10];
                        if (!sessionWasReused) return [3 /*break*/, 8];
                        //FIXME: If the map state we're recovering has a selection, we need to re-init the selection client-side
                        (0, logger_1.info)("Session ID re-used. Attempting recovery of map state of: ".concat(m.name));
                        mapPromises.push(this.tryDescribeRuntimeMapAsync(m.name, session, m.mapDef, siteVersion));
                        return [3 /*break*/, 10];
                    case 8:
                        (0, logger_1.info)("Creating runtime map state (".concat(m.name, ") for: ").concat(m.mapDef));
                        (0, assert_1.assertIsDefined)(this.client);
                        _e = (_d = mapPromises).push;
                        _f = this.createRuntimeMap;
                        _l = {
                            mapDefinition: m.mapDef,
                            requestedFeatures: request_builder_1.RuntimeMapFeatureFlags.LayerFeatureSources | request_builder_1.RuntimeMapFeatureFlags.LayerIcons | request_builder_1.RuntimeMapFeatureFlags.LayersAndGroups
                        };
                        return [4 /*yield*/, session.getValueAsync()];
                    case 9:
                        _e.apply(_d, [_f.apply(this, [(_l.session = _m.sent(),
                                    _l.targetMapName = m.name,
                                    _l), siteVersion])]);
                        _m.label = 10;
                    case 10:
                        _c++;
                        return [3 /*break*/, 7];
                    case 11: return [4 /*yield*/, Promise.all(mapPromises)];
                    case 12:
                        maps = _m.sent();
                        //All must be non-zero
                        for (_g = 0, maps_1 = maps; _g < maps_1.length; _g++) {
                            m = maps_1[_g];
                            epsg = m.CoordinateSystem.EpsgCode;
                            mapDef = m.MapDefinition;
                            arbCs = (0, units_1.tryParseArbitraryCs)(m.CoordinateSystem.MentorCode);
                            if (!arbCs) {
                                if (epsg == "0") {
                                    throw new error_1.MgError((0, i18n_1.tr)("INIT_ERROR_UNSUPPORTED_COORD_SYS", locale || i18n_1.DEFAULT_LOCALE, { mapDefinition: mapDef }));
                                }
                                //Must be registered to proj4js if not 4326 or 3857
                                if (!proj4_2.default.defs["EPSG:".concat(epsg)]) {
                                    fetchEpsgs.push({ epsg: epsg, mapDef: mapDef });
                                }
                            }
                        }
                        extraEpsgs = projectionSelector(res);
                        for (_h = 0, extraEpsgs_1 = extraEpsgs; _h < extraEpsgs_1.length; _h++) {
                            e = extraEpsgs_1[_h];
                            if (!proj4_2.default.defs["EPSG:".concat(e)]) {
                                fetchEpsgs.push({ epsg: e, mapDef: "" });
                            }
                        }
                        return [4 /*yield*/, Promise.all(fetchEpsgs.filter(function (fe) { return !(0, string_1.strIsNullOrEmpty)(fe.epsg); }).map(function (f) { return (0, projections_1.resolveProjectionFromEpsgIoAsync)(f.epsg, locale, f.mapDef); }))];
                    case 13:
                        epsgs = _m.sent();
                        //Previously, we register proj4 with OpenLayers on the bootstrap phase way before this init
                        //process is started. This no longer works for OL6 where it doesn't seem to pick up the extra
                        //projections we've registered with proj4 after linking proj4 to OpenLayers. So that registration
                        //step has been relocated here, after all the custom projections have been fetched and registered
                        //with proj4
                        (0, logger_1.debug)("Register proj4 with OpenLayers");
                        (0, proj4_1.register)(proj4_2.default);
                        mapsByName = {};
                        for (_j = 0, maps_2 = maps; _j < maps_2.length; _j++) {
                            map = maps_2[_j];
                            mapsByName[map.Name] = map;
                        }
                        for (_k = 0, mapDefs_3 = mapDefs; _k < mapDefs_3.length; _k++) {
                            gs = mapDefs_3[_k];
                            if (!(0, init_command_1.isMapDefinition)(gs)) {
                                mapsByName[gs.name] = gs;
                            }
                        }
                        return [2 /*return*/, [mapsByName, warnings]];
                }
            });
        });
    };
    DefaultViewerInitCommand.prototype.describeRuntimeMapStateless = function (client, siteVersion, m) {
        var _a, _b, _c;
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var name, mapDef, metadata, mdf, rt, groups, layers, tsd, sTileWidth, sTileHeight, _i, _d, bg, _e, _f, lyr, _g, _h, grp, _j, _k, lyr;
            return tslib_1.__generator(this, function (_l) {
                switch (_l.label) {
                    case 0:
                        name = m.name, mapDef = m.mapDef, metadata = m.metadata;
                        return [4 /*yield*/, ((_a = this.client) === null || _a === void 0 ? void 0 : _a.getResource(mapDef, { username: "Anonymous" }))];
                    case 1:
                        mdf = _l.sent();
                        if (!mdf)
                            throw new Error("Failed to fetch map def");
                        rt = {
                            SessionId: "",
                            Extents: {
                                LowerLeftCoordinate: {
                                    X: mdf.Extents.MinX,
                                    Y: mdf.Extents.MinY
                                },
                                UpperRightCoordinate: {
                                    X: mdf.Extents.MaxX,
                                    Y: mdf.Extents.MaxY
                                }
                            },
                            SiteVersion: siteVersion,
                            Name: name,
                            DisplayDpi: 96,
                            BackgroundColor: mdf.BackgroundColor,
                            MapDefinition: mapDef,
                            CoordinateSystem: {
                                // We are assuming the app def specifies this data in each <Map> entry as extension properties
                                // beginning with "Meta_" (eg. Meta_MentorCode, Meta_EpsgCode, etc)
                                MentorCode: metadata.MentorCode,
                                EpsgCode: metadata.EpsgCode,
                                MetersPerUnit: metadata.MetersPerUnit,
                                Wkt: mdf.CoordinateSystem
                            },
                            IconMimeType: "image/png",
                        };
                        groups = [];
                        layers = [];
                        if (!mdf.TileSetSource) return [3 /*break*/, 3];
                        rt.TileSetDefinition = mdf.TileSetSource.ResourceId;
                        return [4 /*yield*/, client.getResource(mdf.TileSetSource.ResourceId)];
                    case 2:
                        tsd = _l.sent();
                        if (tsd.TileStoreParameters.TileProvider == "Default") {
                            sTileWidth = (_b = tsd.TileStoreParameters.Parameter.find(function (p) { return p.Name == "TileWidth"; })) === null || _b === void 0 ? void 0 : _b.Value;
                            sTileHeight = (_c = tsd.TileStoreParameters.Parameter.find(function (p) { return p.Name == "TileHeight"; })) === null || _c === void 0 ? void 0 : _c.Value;
                            if (!(0, string_1.strIsNullOrEmpty)(sTileWidth) && !(0, string_1.strIsNullOrEmpty)(sTileHeight)) {
                                rt.TileWidth = parseInt(sTileWidth, 10);
                                rt.TileHeight = parseInt(sTileHeight, 10);
                            }
                        }
                        else if (tsd.TileStoreParameters.TileProvider == "XYZ") {
                            rt.TileHeight = 256;
                            rt.TileHeight = 256;
                        }
                        for (_i = 0, _d = tsd.BaseMapLayerGroup; _i < _d.length; _i++) {
                            bg = _d[_i];
                            groups.push({
                                Name: bg.Name,
                                DisplayInLegend: bg.ShowInLegend,
                                LegendLabel: bg.LegendLabel,
                                ObjectId: bg.Name,
                                ExpandInLegend: bg.ExpandInLegend,
                                Visible: bg.Visible,
                                ActuallyVisible: bg.Visible,
                                Type: 3 /* BaseMapFromTileSet */
                            });
                            for (_e = 0, _f = bg.BaseMapLayer; _e < _f.length; _e++) {
                                lyr = _f[_e];
                                layers.push({
                                    Name: lyr.Name,
                                    DisplayInLegend: lyr.ShowInLegend,
                                    // We don't have stateless QUERYMAPFEATURES (yet), so there is no point actually respecting this flag
                                    Selectable: false,
                                    LegendLabel: lyr.LegendLabel,
                                    ExpandInLegend: lyr.ExpandInLegend,
                                    Visible: true,
                                    ParentId: bg.Name,
                                    ActuallyVisible: true,
                                    LayerDefinition: lyr.ResourceId,
                                    ObjectId: lyr.Name,
                                    Type: 2 /* BaseMap */
                                });
                            }
                        }
                        _l.label = 3;
                    case 3:
                        for (_g = 0, _h = mdf.MapLayerGroup; _g < _h.length; _g++) {
                            grp = _h[_g];
                            groups.push({
                                Name: grp.Name,
                                DisplayInLegend: grp.ShowInLegend,
                                LegendLabel: grp.LegendLabel,
                                ObjectId: grp.Name,
                                ExpandInLegend: grp.ExpandInLegend,
                                Visible: grp.Visible,
                                ActuallyVisible: grp.Visible,
                                Type: 1 /* Normal */
                            });
                        }
                        for (_j = 0, _k = mdf.MapLayer; _j < _k.length; _j++) {
                            lyr = _k[_j];
                            layers.push({
                                Name: lyr.Name,
                                DisplayInLegend: lyr.ShowInLegend,
                                // We don't have stateless QUERYMAPFEATURES (yet), so there is no point actually respecting this flag
                                Selectable: false,
                                LegendLabel: lyr.LegendLabel,
                                ExpandInLegend: lyr.ExpandInLegend,
                                Visible: true,
                                ParentId: lyr.Group,
                                ActuallyVisible: true,
                                LayerDefinition: lyr.ResourceId,
                                ObjectId: lyr.Name,
                                Type: 1 /* Dynamic */
                            });
                        }
                        rt.Group = groups;
                        rt.Layer = layers;
                        return [2 /*return*/, rt];
                }
            });
        });
    };
    /**
     * @override
     * @protected
     * @param {ApplicationDefinition} appDef
     * @param {Dictionary<SubjectLayerType>} mapsByName
     * @param {*} config
     * @param {string[]} warnings
     * @returns {Dictionary<MapInfo>}
     * @memberof MgViewerInitCommand
     */
    DefaultViewerInitCommand.prototype.setupMaps = function (appDef, mapsByName, config, warnings, locale) {
        var dict = {};
        if (appDef.MapSet) {
            for (var _i = 0, _a = appDef.MapSet.MapGroup; _i < _a.length; _i++) {
                var mGroup = _a[_i];
                var mapName = void 0;
                //Setup external layers
                var initExternalLayers = [];
                var externalBaseLayers = [];
                var subject = void 0;
                //Need to do this in 2 passes. 1st pass to try and get the MG map
                for (var _b = 0, _c = mGroup.Map; _b < _c.length; _b++) {
                    var map = _c[_b];
                    if (map.Type === "MapGuide") {
                        //TODO: Based on the schema, different MG map groups could have different
                        //settings here and our redux tree should reflect that. Currently the first one "wins"
                        if (!config.selectionColor && map.Extension.SelectionColor != null) {
                            config.selectionColor = map.Extension.SelectionColor;
                        }
                        if (!config.imageFormat && map.Extension.ImageFormat != null) {
                            config.imageFormat = map.Extension.ImageFormat;
                        }
                        if (!config.selectionImageFormat && map.Extension.SelectionFormat != null) {
                            config.selectionImageFormat = map.Extension.SelectionFormat;
                        }
                        //NOTE: Although non-sensical, if the same map definition exists across multiple
                        //MapGroups, we might be matching the wrong one. We just assume such non-sensical
                        //AppDefs won't exist
                        for (var name_1 in mapsByName) {
                            var mapDef = mapsByName[name_1];
                            if ((0, type_guards_1.isRuntimeMap)(mapDef) && mapDef.MapDefinition == map.Extension.ResourceId) {
                                mapName = name_1;
                                subject = mapDef;
                                break;
                            }
                        }
                    }
                }
                var isArbitrary = this.isArbitraryCoordSys(subject);
                //2nd pass to process non-MG maps
                for (var _d = 0, _e = mGroup.Map; _d < _e.length; _d++) {
                    var map = _e[_d];
                    if (map.Type == "MapGuide") {
                        continue;
                    }
                    if (map.Type == TYPE_SUBJECT) {
                        mapName = mGroup["@id"];
                    }
                    else {
                        if (isArbitrary) {
                            warnings.push((0, i18n_1.tr)("INIT_WARNING_ARBITRARY_COORDSYS_INCOMPATIBLE_LAYER", locale, { mapId: mGroup["@id"], type: map.Type }));
                        }
                        else {
                            if (map.Type == TYPE_EXTERNAL) {
                                initExternalLayers.push((0, init_command_1.buildSubjectLayerDefn)(map.Extension.layer_name, map));
                            }
                            else {
                                (0, init_1.processLayerInMapGroup)(map, warnings, config, appDef, externalBaseLayers);
                            }
                        }
                    }
                }
                if (isArbitrary) {
                    //Check for incompatible widgets
                    for (var _f = 0, _g = appDef.WidgetSet; _f < _g.length; _f++) {
                        var wset = _g[_f];
                        for (var _h = 0, _j = wset.Widget; _h < _j.length; _h++) {
                            var widget = _j[_h];
                            switch (widget.Type) {
                                case "CoordinateTracker":
                                    warnings.push((0, i18n_1.tr)("INIT_WARNING_ARBITRARY_COORDSYS_UNSUPPORTED_WIDGET", locale, { mapId: mGroup["@id"], widget: widget.Type }));
                                    break;
                            }
                        }
                    }
                }
                (0, init_1.applyInitialBaseLayerVisibility)(externalBaseLayers);
                //Setup initial view
                var initialView = void 0;
                if (mGroup.InitialView) {
                    initialView = {
                        x: mGroup.InitialView.CenterX,
                        y: mGroup.InitialView.CenterY,
                        scale: mGroup.InitialView.Scale
                    };
                }
                if (mapName) {
                    dict[mapName] = {
                        mapGroupId: mGroup["@id"],
                        map: mapsByName[mapName],
                        initialView: initialView,
                        externalBaseLayers: externalBaseLayers,
                        initialExternalLayers: initExternalLayers
                    };
                }
            }
        }
        return dict;
    };
    DefaultViewerInitCommand.prototype.initFromAppDefAsync = function (appDef, session, sessionWasReused) {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var _i, _c, pd, k, v, epsg, projStr, _d, mapsByName, warnings;
            var _this = this;
            return tslib_1.__generator(this, function (_e) {
                switch (_e.label) {
                    case 0:
                        if (Array.isArray((_b = (_a = appDef.Extension) === null || _a === void 0 ? void 0 : _a.CustomProjections) === null || _b === void 0 ? void 0 : _b.Projection)) {
                            for (_i = 0, _c = appDef.Extension.CustomProjections.Projection; _i < _c.length; _i++) {
                                pd = _c[_i];
                                k = void 0, v = void 0;
                                if (typeof (pd.epsg) === 'string' && typeof (pd.text) === 'string') { // appdef json form
                                    k = pd.epsg;
                                    v = pd.text;
                                }
                                else { // appdef xml translated form
                                    epsg = pd["@epsg"][0];
                                    projStr = pd["#text"][0];
                                    k = epsg;
                                    v = projStr;
                                }
                                if (!(0, string_1.strIsNullOrEmpty)(k) && !(0, string_1.strIsNullOrEmpty)(v)) {
                                    proj4_2.default.defs("EPSG:".concat(k), v);
                                    (0, logger_1.debug)("Registered proj4 defn from appdef for EPSG:".concat(k), v);
                                }
                            }
                            (0, proj4_1.register)(proj4_2.default);
                        }
                        return [4 /*yield*/, this.createRuntimeMapsAsync(session, appDef, (0, init_command_1.isStateless)(appDef), function (fl) { return (0, init_command_1.getMapDefinitionsFromFlexLayout)(fl); }, function (fl) { return _this.getExtraProjectionsFromFlexLayout(fl); }, sessionWasReused)];
                    case 1:
                        _d = _e.sent(), mapsByName = _d[0], warnings = _d[1];
                        return [4 /*yield*/, this.initFromAppDefCoreAsync(appDef, this.options, mapsByName, warnings)];
                    case 2: return [2 /*return*/, _e.sent()];
                }
            });
        });
    };
    DefaultViewerInitCommand.prototype.sessionAcquiredAsync = function (session, sessionWasReused) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var _a, resourceId, locale, cl, fl, e_2, wl, _b, _c, _d, fl, _e, _f, _g, fl, cl, fl;
            var _h, _j;
            return tslib_1.__generator(this, function (_k) {
                switch (_k.label) {
                    case 0:
                        _a = this.options, resourceId = _a.resourceId, locale = _a.locale;
                        if (!!resourceId) return [3 /*break*/, 6];
                        cl = new client_1.Client("", "mapagent");
                        _k.label = 1;
                    case 1:
                        _k.trys.push([1, 4, , 5]);
                        return [4 /*yield*/, cl.get("appdef.json")];
                    case 2:
                        fl = _k.sent();
                        return [4 /*yield*/, this.initFromAppDefAsync(fl, session, sessionWasReused)];
                    case 3: return [2 /*return*/, _k.sent()];
                    case 4:
                        e_2 = _k.sent();
                        throw new error_1.MgError((0, i18n_1.tr)("INIT_ERROR_MISSING_RESOURCE_PARAM", locale));
                    case 5: return [3 /*break*/, 25];
                    case 6:
                        if (!(typeof (resourceId) == 'string')) return [3 /*break*/, 22];
                        if (!(0, string_1.strEndsWith)(resourceId, "WebLayout")) return [3 /*break*/, 10];
                        (0, assert_1.assertIsDefined)(this.client);
                        _c = (_b = this.client).getResource;
                        _d = [resourceId];
                        _h = {};
                        return [4 /*yield*/, session.getValueAsync()];
                    case 7: return [4 /*yield*/, _c.apply(_b, _d.concat([(_h.SESSION = _k.sent(), _h)]))];
                    case 8:
                        wl = _k.sent();
                        return [4 /*yield*/, this.initFromWebLayoutAsync(wl, session, sessionWasReused)];
                    case 9: return [2 /*return*/, _k.sent()];
                    case 10:
                        if (!(0, string_1.strEndsWith)(resourceId, "ApplicationDefinition")) return [3 /*break*/, 14];
                        (0, assert_1.assertIsDefined)(this.client);
                        _f = (_e = this.client).getResource;
                        _g = [resourceId];
                        _j = {};
                        return [4 /*yield*/, session.getValueAsync()];
                    case 11: return [4 /*yield*/, _f.apply(_e, _g.concat([(_j.SESSION = _k.sent(), _j)]))];
                    case 12:
                        fl = _k.sent();
                        return [4 /*yield*/, this.initFromAppDefAsync(fl, session, sessionWasReused)];
                    case 13: return [2 /*return*/, _k.sent()];
                    case 14:
                        if (!(0, string_1.isResourceId)(resourceId)) return [3 /*break*/, 15];
                        throw new error_1.MgError((0, i18n_1.tr)("INIT_ERROR_UNKNOWN_RESOURCE_TYPE", locale, { resourceId: resourceId }));
                    case 15:
                        fl = void 0;
                        if (!!this.client) return [3 /*break*/, 17];
                        cl = new client_1.Client("", "mapagent");
                        return [4 /*yield*/, cl.get(resourceId)];
                    case 16:
                        fl = _k.sent();
                        return [3 /*break*/, 19];
                    case 17: return [4 /*yield*/, this.client.get(resourceId)];
                    case 18:
                        fl = _k.sent();
                        _k.label = 19;
                    case 19: return [4 /*yield*/, this.initFromAppDefAsync(fl, session, sessionWasReused)];
                    case 20: return [2 /*return*/, _k.sent()];
                    case 21: return [3 /*break*/, 25];
                    case 22: return [4 /*yield*/, resourceId()];
                    case 23:
                        fl = _k.sent();
                        return [4 /*yield*/, this.initFromAppDefAsync(fl, session, sessionWasReused)];
                    case 24: return [2 /*return*/, _k.sent()];
                    case 25: return [2 /*return*/];
                }
            });
        });
    };
    DefaultViewerInitCommand.prototype.runAsync = function (options) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var sessionWasReused, session, payload, initSelections, _a, _b, _i, mapName, sset, e_3;
            var _this = this;
            return tslib_1.__generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        this.options = options;
                        return [4 /*yield*/, this.initLocaleAsync(this.options)];
                    case 1:
                        _c.sent();
                        sessionWasReused = false;
                        if (!this.options.session) {
                            session = new lazy_1.AsyncLazy(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                                var sid;
                                return tslib_1.__generator(this, function (_a) {
                                    switch (_a.label) {
                                        case 0:
                                            (0, assert_1.assertIsDefined)(this.client);
                                            return [4 /*yield*/, this.client.createSession("Anonymous", "")];
                                        case 1:
                                            sid = _a.sent();
                                            return [2 /*return*/, sid];
                                    }
                                });
                            }); });
                        }
                        else {
                            (0, logger_1.info)("Re-using session: ".concat(this.options.session));
                            sessionWasReused = true;
                            session = new lazy_1.AsyncLazy(function () { return Promise.resolve(_this.options.session); });
                        }
                        return [4 /*yield*/, this.sessionAcquiredAsync(session, sessionWasReused)];
                    case 2:
                        payload = _c.sent();
                        if (!sessionWasReused) return [3 /*break*/, 10];
                        initSelections = {};
                        _a = [];
                        for (_b in payload.maps)
                            _a.push(_b);
                        _i = 0;
                        _c.label = 3;
                    case 3:
                        if (!(_i < _a.length)) return [3 /*break*/, 6];
                        mapName = _a[_i];
                        return [4 /*yield*/, (0, session_store_1.retrieveSelectionSetFromLocalStorage)(session, mapName)];
                    case 4:
                        sset = _c.sent();
                        if (sset) {
                            initSelections[mapName] = sset;
                        }
                        _c.label = 5;
                    case 5:
                        _i++;
                        return [3 /*break*/, 3];
                    case 6:
                        payload.initialSelections = initSelections;
                        _c.label = 7;
                    case 7:
                        _c.trys.push([7, 9, , 10]);
                        //In the interest of being a responsible citizen, clean up all selection-related stuff from
                        //session store
                        return [4 /*yield*/, (0, session_store_1.clearSessionStore)()];
                    case 8:
                        //In the interest of being a responsible citizen, clean up all selection-related stuff from
                        //session store
                        _c.sent();
                        return [3 /*break*/, 10];
                    case 9:
                        e_3 = _c.sent();
                        return [3 /*break*/, 10];
                    case 10: return [2 /*return*/, payload];
                }
            });
        });
    };
    return DefaultViewerInitCommand;
}(init_command_1.ViewerInitCommand));
exports.DefaultViewerInitCommand = DefaultViewerInitCommand;
//# sourceMappingURL=init-mapguide.js.map