"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MapGuideMapProviderContext = exports.isMapGuideProviderState = void 0;
var tslib_1 = require("tslib");
var client_1 = require("../../api/client");
var session_keep_alive_1 = require("../session-keep-alive");
var common_1 = require("../../api/common");
var WKT_1 = tslib_1.__importDefault(require("ol/format/WKT"));
var Polygon_1 = require("ol/geom/Polygon");
var map_1 = require("../../actions/map");
var View_1 = tslib_1.__importDefault(require("ol/View"));
var lodash_debounce_1 = tslib_1.__importDefault(require("lodash.debounce"));
var viewer_state_1 = require("../../utils/viewer-state");
var array_1 = require("../../utils/array");
var mg_layer_set_group_1 = require("../../api/mg-layer-set-group");
var feature_1 = require("../tooltips/feature");
var logger_1 = require("../../utils/logger");
var site_version_1 = require("../../utils/site-version");
var constants_1 = require("../../constants");
var error_1 = require("../../api/error");
var base_1 = require("./base");
var assert_1 = require("../../utils/assert");
var string_1 = require("../../utils/string");
var url_1 = require("../../utils/url");
var actions_1 = require("../../constants/actions");
var deArrayify_1 = require("../../api/builders/deArrayify");
var hooks_1 = require("../../containers/hooks");
var hooks_mapguide_1 = require("../../containers/hooks-mapguide");
var context_1 = require("./context");
var utfgrid_1 = require("../tooltips/utfgrid");
var Tile_1 = tslib_1.__importDefault(require("ol/layer/Tile"));
var UTFGrid_1 = tslib_1.__importDefault(require("ol/source/UTFGrid"));
var hooks_generic_1 = require("../../containers/hooks-generic");
var type_guards_1 = require("../../utils/type-guards");
function isMapGuideProviderState(arg) {
    return typeof (arg.agentUri) == 'string'
        && typeof (arg.agentKind) == 'string';
}
exports.isMapGuideProviderState = isMapGuideProviderState;
function useMapGuideViewerState() {
    var activeTool = (0, hooks_1.useViewerActiveTool)();
    var view = (0, hooks_1.useActiveMapView)();
    var viewRotation = (0, hooks_1.useViewerViewRotation)();
    var viewRotationEnabled = (0, hooks_1.useViewerViewRotationEnabled)();
    var mapName = (0, hooks_1.useActiveMapName)();
    var locale = (0, hooks_1.useViewerLocale)();
    var externalBaseLayers = (0, hooks_1.useActiveMapExternalBaseLayers)();
    var cancelDigitizationKey = (0, hooks_1.useConfiguredCancelDigitizationKey)();
    var undoLastPointKey = (0, hooks_1.useConfiguredUndoLastPointKey)();
    var layers = (0, hooks_1.useActiveMapLayers)();
    var initialExternalLayers = (0, hooks_1.useActiveMapInitialExternalLayers)();
    var dispatch = (0, context_1.useReduxDispatch)();
    var busyWorkers = (0, hooks_1.useViewerBusyCount)();
    var appSettings = (0, hooks_1.useCustomAppSettings)();
    // ============== Generic ============== //
    var subject = (0, hooks_generic_1.useActiveMapSubjectLayer)();
    // ============== MapGuide-specific ================== //
    var stateless = (0, hooks_1.useViewerIsStateless)();
    var imageFormat = (0, hooks_1.useViewerImageFormat)();
    var agentUri = (0, hooks_1.useConfiguredAgentUri)();
    var agentKind = (0, hooks_1.useConfiguredAgentKind)();
    var map = (0, hooks_mapguide_1.useActiveMapState)();
    var pointSelectionBuffer = (0, hooks_1.useViewerPointSelectionBuffer)();
    var featureTooltipsEnabled = (0, hooks_1.useViewerFeatureTooltipsEnabled)();
    var manualFeatureTooltips = (0, hooks_1.useConfiguredManualFeatureTooltips)();
    var sessionId = (0, hooks_mapguide_1.useActiveMapSessionId)();
    var selectionColor = (0, hooks_1.useViewerSelectionColor)();
    var selectionImageFormat = (0, hooks_1.useViewerSelectionImageFormat)();
    var selectableLayerNames = (0, hooks_mapguide_1.useActiveMapSelectableLayerNames)();
    var layerTransparency = (0, hooks_mapguide_1.useActiveMapLayerTransparency)();
    var showGroups = (0, hooks_mapguide_1.useActiveMapShowGroups)();
    var hideGroups = (0, hooks_mapguide_1.useActiveMapHideGroups)();
    var showLayers = (0, hooks_mapguide_1.useActiveMapShowLayers)();
    var hideLayers = (0, hooks_mapguide_1.useActiveMapHideLayers)();
    var activeSelectedFeature = (0, hooks_mapguide_1.useActiveMapActiveSelectedFeature)();
    var activeSelectedFeatureColor = (0, hooks_1.useViewerActiveFeatureSelectionColor)();
    var selection = (0, hooks_1.useActiveMapSelectionSet)();
    var bgColor;
    if (map) {
        bgColor = "#".concat(map.BackgroundColor.substring(2));
    }
    var activeSelectedFeatureXml;
    if (activeSelectedFeature && selection && selection.FeatureSet) {
        activeSelectedFeatureXml = (0, deArrayify_1.getActiveSelectedFeatureXml)(selection.FeatureSet, activeSelectedFeature);
    }
    var theMap = map !== null && map !== void 0 ? map : subject;
    var isReady = false;
    // Regardless of inferred readiness, the map/subject must be set
    if (!theMap) {
        isReady = false;
        theMap = {};
    }
    else {
        if (subject && layerTransparency) {
            isReady = true;
        }
        else if (agentUri && theMap && layerTransparency) {
            if (!stateless) {
                if ((0, type_guards_1.isRuntimeMap)(theMap) && sessionId) {
                    isReady = true;
                }
            }
            else {
                isReady = true;
            }
        }
    }
    var nextState = {
        stateless: stateless,
        activeTool: activeTool,
        busyWorkers: busyWorkers,
        view: view,
        viewRotation: viewRotation,
        viewRotationEnabled: viewRotationEnabled,
        mapName: mapName,
        locale: locale,
        externalBaseLayers: externalBaseLayers,
        cancelDigitizationKey: cancelDigitizationKey,
        undoLastPointKey: undoLastPointKey,
        initialExternalLayers: initialExternalLayers,
        appSettings: appSettings !== null && appSettings !== void 0 ? appSettings : {},
        // ========== IMapProviderStateExtras ========== //
        isReady: isReady,
        bgColor: bgColor,
        layers: layers,
        // =========== MapGuide-specific ============== //
        imageFormat: imageFormat,
        agentUri: agentUri,
        agentKind: agentKind,
        map: theMap,
        pointSelectionBuffer: pointSelectionBuffer,
        featureTooltipsEnabled: featureTooltipsEnabled,
        manualFeatureTooltips: manualFeatureTooltips,
        sessionId: sessionId,
        selectionColor: selectionColor,
        selectionImageFormat: selectionImageFormat,
        selectableLayerNames: selectableLayerNames,
        layerTransparency: layerTransparency,
        showGroups: showGroups !== null && showGroups !== void 0 ? showGroups : [],
        hideGroups: hideGroups !== null && hideGroups !== void 0 ? hideGroups : [],
        showLayers: showLayers !== null && showLayers !== void 0 ? showLayers : [],
        hideLayers: hideLayers !== null && hideLayers !== void 0 ? hideLayers : [],
        activeSelectedFeatureXml: activeSelectedFeatureXml !== null && activeSelectedFeatureXml !== void 0 ? activeSelectedFeatureXml : string_1.STR_EMPTY,
        activeSelectedFeatureColor: activeSelectedFeatureColor,
        selection: selection
    };
    return nextState;
}
var MapGuideMapProviderContext = /** @class */ (function (_super) {
    tslib_1.__extends(MapGuideMapProviderContext, _super);
    // ============================================================= //
    function MapGuideMapProviderContext(mockMode) {
        if (mockMode === void 0) { mockMode = undefined; }
        var _this = _super.call(this) || this;
        _this.mockMode = mockMode;
        _this.onOpenTooltipLink = function (url) {
            var _a;
            var fixedUrl = url;
            if (_this._state.mapName && _this._state.sessionId) {
                fixedUrl = (0, url_1.ensureParameters)(url, _this._state.mapName, _this._state.sessionId, _this._state.locale);
            }
            (_a = _this._comp) === null || _a === void 0 ? void 0 : _a.onDispatch({
                type: actions_1.ActionType.TASK_INVOKE_URL,
                payload: {
                    url: fixedUrl
                }
            });
        };
        _this._wktFormat = new WKT_1.default();
        _this.refreshOnStateChange = (0, lodash_debounce_1.default)(_this._refreshOnStateChange.bind(_this), 500);
        return _this;
    }
    /**
     * @override
     */
    MapGuideMapProviderContext.prototype.getHookFunction = function () {
        return useMapGuideViewerState;
    };
    MapGuideMapProviderContext.prototype.setMockMode = function (mode) {
        this.mockMode = mode;
    };
    /**
     * @override
     */
    MapGuideMapProviderContext.prototype.hideAllPopups = function () {
        var _a;
        _super.prototype.hideAllPopups.call(this);
        (_a = this._featureTooltip) === null || _a === void 0 ? void 0 : _a.setEnabled(false);
    };
    /**
     *
     * @override
     * @protected
     * @returns {(MapGuideMockMode | undefined)}
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.getMockMode = function () { return this.mockMode; };
    MapGuideMapProviderContext.prototype.getInitialProviderState = function () {
        return {
            stateless: false,
            imageFormat: "PNG8",
            agentUri: undefined,
            agentKind: "mapagent",
            map: {},
            pointSelectionBuffer: 2,
            featureTooltipsEnabled: true,
            manualFeatureTooltips: false,
            sessionId: undefined,
            selectionColor: "0000FF",
            selectionImageFormat: "PNG8",
            selectableLayerNames: [],
            layerTransparency: {},
            appSettings: {},
            showGroups: [],
            hideGroups: [],
            showLayers: [],
            hideLayers: [],
            activeSelectedFeatureXml: string_1.STR_EMPTY,
            activeSelectedFeatureColor: "FF0000",
            selection: null
        };
    };
    MapGuideMapProviderContext.prototype.getProviderName = function () { return "MapGuide"; };
    /**
     * @override
     * @returns {(IMapGuideViewerSupport | undefined)}
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.mapguideSupport = function () {
        return this;
    };
    //#region IMapGuideViewerSupport
    MapGuideMapProviderContext.prototype.getSelection = function () {
        return this._state.selection;
    };
    MapGuideMapProviderContext.prototype.getSelectionXml = function (selection, layerIds) {
        return (0, deArrayify_1.buildSelectionXml)(selection, layerIds);
    };
    MapGuideMapProviderContext.prototype.getSessionId = function () {
        return this._state.sessionId;
    };
    MapGuideMapProviderContext.prototype.setFeatureTooltipEnabled = function (enabled) {
        var _a;
        (_a = this._comp) === null || _a === void 0 ? void 0 : _a.onDispatch((0, map_1.setFeatureTooltipsEnabled)(enabled));
    };
    //#endregion
    //#region IMapViewerContextCallback
    MapGuideMapProviderContext.prototype.onSessionExpired = function () {
    };
    MapGuideMapProviderContext.prototype.onProviderMapClick = function (px) {
        var _a;
        if (this._state.mapName && this._state.sessionId) {
            if (this._state.manualFeatureTooltips && this._state.featureTooltipsEnabled) {
                this.queryFeatureTooltip(px);
            }
            else if (this._state.activeTool === common_1.ActiveMapTool.Select) {
                var ptBuffer = (_a = this._state.pointSelectionBuffer) !== null && _a !== void 0 ? _a : 2;
                var box = this.getPointSelectionBox(px, ptBuffer);
                var geom = (0, Polygon_1.fromExtent)(box);
                var options = this.buildDefaultQueryOptions(geom);
                options.maxfeatures = 1;
                this.sendSelectionQuery(options);
            }
        }
    };
    //#endregion
    //#region Map Context
    /**
     * @override
     * @protected
     * @param {GenericEvent} e
     * @returns
     * @memberof BaseMapProviderContext
     */
    MapGuideMapProviderContext.prototype.onMouseMove = function (e) {
        var _a, _b;
        if (this._comp) {
            this.handleMouseTooltipMouseMove(e);
            if (this._state.activeTool == common_1.ActiveMapTool.Select) {
                this.handleHighlightHover(e);
            }
            if (this._comp.isContextMenuOpen()) {
                return;
            }
            if (!this._state.manualFeatureTooltips) {
                this.handleFeatureTooltipMouseMove(e);
            }
            if (this._utfGridTooltip) {
                this._utfGridTooltip.onMouseMove(e);
            }
            if (this._state.mapName) {
                (_b = (_a = this._comp).onDispatch) === null || _b === void 0 ? void 0 : _b.call(_a, (0, map_1.setMouseCoordinates)(this._state.mapName, e.coordinate));
            }
        }
    };
    MapGuideMapProviderContext.prototype.queryFeatureTooltip = function (pixel) {
        if (!this._state.stateless && this._featureTooltip && this._featureTooltip.isEnabled()) {
            this._featureTooltip.raiseQueryFromPoint(pixel);
        }
    };
    MapGuideMapProviderContext.prototype.handleFeatureTooltipMouseMove = function (e) {
        if (!this._state.stateless && this._featureTooltip && this._featureTooltip.isEnabled()) {
            this._featureTooltip.onMouseMove(e);
        }
    };
    MapGuideMapProviderContext.prototype.enableFeatureTooltips = function (enabled) {
        var _a;
        (_a = this._featureTooltip) === null || _a === void 0 ? void 0 : _a.setEnabled(enabled);
    };
    MapGuideMapProviderContext.prototype.refreshMapInternal = function (name, mode) {
        if (mode === void 0) { mode = common_1.RefreshMode.LayersOnly | common_1.RefreshMode.SelectionOnly; }
        var layerSet = this.getLayerSetGroup(name);
        layerSet === null || layerSet === void 0 ? void 0 : layerSet.refreshMap(mode);
    };
    MapGuideMapProviderContext.prototype.showSelectedFeature = function (mapExtent, size, map, selectionColor, featureXml) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var sv, layerSet, r, dataUri, e_1;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        sv = (0, site_version_1.getSiteVersion)(map);
                        // This operation requires v4.0.0 QUERYMAPFEATURES, so bail if this ain't the right version
                        if (!(0, site_version_1.canUseQueryMapFeaturesV4)(sv)) {
                            return [2 /*return*/];
                        }
                        layerSet = this.getLayerSetGroup(map.Name);
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 5, , 6]);
                        if (!featureXml) return [3 /*break*/, 3];
                        return [4 /*yield*/, this._client.queryMapFeatures_v4({
                                mapname: map.Name,
                                session: map.SessionId,
                                selectionformat: "PNG",
                                featurefilter: featureXml,
                                selectioncolor: selectionColor,
                                requestdata: 2,
                                layerattributefilter: 0,
                                persist: 0 //IMPORTANT: This is a transient selection
                            })];
                    case 2:
                        r = _a.sent();
                        if (r.InlineSelectionImage) {
                            dataUri = "data:".concat(r.InlineSelectionImage.MimeType, ";base64,").concat(r.InlineSelectionImage.Content);
                            layerSet === null || layerSet === void 0 ? void 0 : layerSet.showActiveSelectedFeature(mapExtent, size, dataUri);
                        }
                        else {
                            layerSet === null || layerSet === void 0 ? void 0 : layerSet.showActiveSelectedFeature(mapExtent, common_1.BLANK_SIZE, constants_1.BLANK_GIF_DATA_URI);
                        }
                        return [3 /*break*/, 4];
                    case 3:
                        layerSet === null || layerSet === void 0 ? void 0 : layerSet.showActiveSelectedFeature(mapExtent, common_1.BLANK_SIZE, constants_1.BLANK_GIF_DATA_URI);
                        _a.label = 4;
                    case 4: return [3 /*break*/, 6];
                    case 5:
                        e_1 = _a.sent();
                        layerSet === null || layerSet === void 0 ? void 0 : layerSet.showActiveSelectedFeature(mapExtent, common_1.BLANK_SIZE, constants_1.BLANK_GIF_DATA_URI);
                        return [3 /*break*/, 6];
                    case 6: return [2 /*return*/];
                }
            });
        });
    };
    //#endregion
    /**
     * DO NOT CALL DIRECTLY, call this.refreshOnStateChange() instead, which is a throttled version
     * of this method
     * @private
     */
    MapGuideMapProviderContext.prototype._refreshOnStateChange = function (mapName, showGroups, showLayers, hideGroups, hideLayers) {
        if (showGroups || showLayers || hideGroups || hideLayers) {
            //this.refreshOnStateChange(map, showGroups, showLayers, hideGroups, hideLayers);
            var layerSet = this.getLayerSetGroup(mapName);
            if (layerSet instanceof mg_layer_set_group_1.MgLayerSetGroup) {
                layerSet.setMapGuideMocking(this.getMockMode());
                layerSet.update(showGroups, showLayers, hideGroups, hideLayers);
            }
        }
    };
    /**
     * @override
     * @protected
     * @param {GenericEvent} e
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.onImageError = function (e) {
        var _this = this;
        var _a;
        (_a = this._keepAlive) === null || _a === void 0 ? void 0 : _a.lastTry().catch(function (err) {
            if ((0, error_1.isSessionExpiredError)(err)) {
                _this.onSessionExpired();
            }
        });
    };
    MapGuideMapProviderContext.prototype.getSelectableLayers = function () {
        var _a;
        return (_a = this._state.selectableLayerNames) !== null && _a !== void 0 ? _a : [];
    };
    MapGuideMapProviderContext.prototype.buildDefaultQueryOptions = function (geom, reqQueryFeatures /* Attributes */) {
        if (reqQueryFeatures === void 0) { reqQueryFeatures = 1; }
        (0, assert_1.assertIsDefined)(this._state.sessionId);
        (0, assert_1.assertIsDefined)(this._state.mapName);
        var names = this.getSelectableLayers();
        var wkt;
        if (typeof geom === 'string') {
            wkt = geom;
        }
        else {
            wkt = this._wktFormat.writeGeometry(geom);
        }
        return {
            mapname: this._state.mapName,
            session: this._state.sessionId,
            geometry: wkt,
            requestdata: reqQueryFeatures,
            layernames: names.length > 0 ? names.join(",") : undefined,
            persist: 1
        };
    };
    /**
     * @virtual
     * @protected
     * @param {Polygon} geom
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.selectFeaturesByExtent = function (geom) {
        if (!this._state.mapName || !this._comp || !this._state.sessionId || !this._state.selectionColor) {
            return;
        }
        this.sendSelectionQuery(this.buildDefaultQueryOptions(geom));
    };
    /**
     * @override
     * @protected
     */
    MapGuideMapProviderContext.prototype.initLayerSet = function (nextState) {
        var _this = this;
        var mapName = nextState.mapName;
        (0, assert_1.assertIsDefined)(mapName);
        (0, assert_1.assertIsDefined)(this._state.map);
        var layerSet = new mg_layer_set_group_1.MgLayerSetGroup(nextState, {
            getImageLoaders: function () { return _super.prototype.getImageSourceLoaders.call(_this, mapName); },
            getTileLoaders: function () { return _super.prototype.getTileSourceLoaders.call(_this, mapName); },
            getBaseTileLoaders: function () { return _super.prototype.getBaseTileSourceLoaders.call(_this, mapName); },
            getMockMode: function () { return _this.getMockMode(); },
            incrementBusyWorker: function () { return _this.incrementBusyWorker(); },
            decrementBusyWorker: function () { return _this.decrementBusyWorker(); },
            addImageLoading: function () { var _a; return (_a = _this._comp) === null || _a === void 0 ? void 0 : _a.addImageLoading(); },
            addImageLoaded: function () { var _a; return (_a = _this._comp) === null || _a === void 0 ? void 0 : _a.addImageLoaded(); },
            onImageError: function (e) { return _this.onImageError(e); },
            onSessionExpired: function () { return _this.onSessionExpired(); },
            getSelectableLayers: function () { return _this.getSelectableLayers(); },
            getClient: function () { return _this._client; },
            isContextMenuOpen: function () { var _a, _b; return (_b = (_a = _this._comp) === null || _a === void 0 ? void 0 : _a.isContextMenuOpen()) !== null && _b !== void 0 ? _b : false; },
            getAgentUri: function () { return _this._state.agentUri; },
            getAgentKind: function () { return _this._state.agentKind; },
            getMapName: function () { return _this._state.mapName; },
            getSessionId: function () { return _this._state.sessionId; },
            getLocale: function () { return _this._state.locale; },
            isFeatureTooltipEnabled: function () { return _this.isFeatureTooltipEnabled(); },
            getPointSelectionBox: function (pt) { return _this.getPointSelectionBox(pt, _this._state.pointSelectionBuffer); },
            openTooltipLink: function (url) { return _this.onOpenTooltipLink(url); },
            addFeatureToHighlight: function (feat, bAppend) { return _this.addFeatureToHighlight(feat, bAppend); }
        });
        this._layerSetGroups[mapName] = layerSet;
        layerSet.update(nextState.showGroups, nextState.showLayers, nextState.hideGroups, nextState.hideLayers);
        return layerSet;
    };
    /**
     * @override
     * @readonly
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.isMouseOverTooltip = function () { var _a, _b; return ((_a = this._featureTooltip) === null || _a === void 0 ? void 0 : _a.isMouseOver) == true || ((_b = this._selectTooltip) === null || _b === void 0 ? void 0 : _b.isMouseOver) == true; };
    /**
     * @override
     */
    MapGuideMapProviderContext.prototype.detachFromComponent = function () {
        var _a, _b;
        (_a = this._keepAlive) === null || _a === void 0 ? void 0 : _a.dispose();
        this._keepAlive = undefined;
        (_b = this._featureTooltip) === null || _b === void 0 ? void 0 : _b.dispose();
        this._featureTooltip = undefined;
        _super.prototype.detachFromComponent.call(this);
    };
    /**
     * @override
     * @param {HTMLElement} el
     * @param {IViewerComponent} comp
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.attachToComponent = function (el, comp) {
        var _this = this;
        var _a, _b, _c, _d;
        _super.prototype.attachToComponent.call(this, el, comp);
        var bCheckSession = (_a = (this._state.map && (0, type_guards_1.isRuntimeMap)(this._state.map))) !== null && _a !== void 0 ? _a : false;
        this._keepAlive = new session_keep_alive_1.SessionKeepAlive(function () { return _this._state.sessionId; }, this._client, this.onSessionExpired.bind(this), bCheckSession);
        var utfGridLayer = (0, base_1.recursiveFindLayer)(this._map.getLayers(), function (oll) {
            if (oll instanceof Tile_1.default) {
                var source = oll.getSource();
                if (source instanceof UTFGrid_1.default) {
                    return true;
                }
            }
            return false;
        });
        if (utfGridLayer) {
            var source = utfGridLayer.getSource();
            this._utfGridTooltip = new utfgrid_1.UTFGridTrackingTooltip(this._map, source, (_c = (_b = this._comp) === null || _b === void 0 ? void 0 : _b.isContextMenuOpen) !== null && _c !== void 0 ? _c : (function () { return false; }));
        }
        var bEnable = (_d = (this._state.map && (0, type_guards_1.isRuntimeMap)(this._state.map))) !== null && _d !== void 0 ? _d : false;
        if (bEnable) {
            this._featureTooltip = new feature_1.FeatureQueryTooltip(this._map, {
                incrementBusyWorker: function () { return _this.incrementBusyWorker(); },
                decrementBusyWorker: function () { return _this.decrementBusyWorker(); },
                onSessionExpired: function () { return _this.onSessionExpired(); },
                getAgentUri: function () { return _this._state.agentUri; },
                getAgentKind: function () { return _this._state.agentKind; },
                getMapName: function () { return _this._state.mapName; },
                getSessionId: function () { return _this._state.sessionId; },
                getLocale: function () { return _this._state.locale; },
                getPointSelectionBox: function (pt) { return _this.getPointSelectionBox(pt, _this._state.pointSelectionBuffer); },
                openTooltipLink: function (url) { return _this.onOpenTooltipLink(url); }
            });
            this._featureTooltip.setEnabled(this._state.featureTooltipsEnabled);
        }
    };
    /**
     * @override
     * @param {RefreshMode} [mode=RefreshMode.LayersOnly | RefreshMode.SelectionOnly]
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.refreshMap = function (mode) {
        if (mode === void 0) { mode = common_1.RefreshMode.LayersOnly | common_1.RefreshMode.SelectionOnly; }
        (0, assert_1.assertIsDefined)(this._state.mapName);
        this.refreshMapInternal(this._state.mapName, mode);
    };
    /**
     * @override
     * @protected
     * @param {MgLayerSetGroup} layerSetGroup
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.onBeforeAttachingLayerSetGroup = function (layerSetGroup) {
        layerSetGroup.setMapGuideMocking(this.getMockMode());
    };
    /**
     *
     * @virtual
     * @param {IMapGuideProviderState} nextState
     * @memberof MapGuideMapProviderContext
     */
    MapGuideMapProviderContext.prototype.setProviderState = function (nextState) {
        var _this = this;
        // If viewer not mounted yet, just accept the next state and bail
        if (!this._comp || !this._map) {
            if (nextState.agentUri) {
                this._client = new client_1.Client(nextState.agentUri, nextState.agentKind);
            }
            this._state = nextState;
            return;
        }
        //
        // React (no pun intended) to prop changes
        //
        if (nextState.imageFormat != this._state.imageFormat) {
            (0, logger_1.warn)("Unsupported change of props: imageFormat");
        }
        if (nextState.agentUri && nextState.agentUri != this._state.agentUri) {
            (0, logger_1.warn)("Unsupported change of props: agentUri");
            this._client = new client_1.Client(nextState.agentUri, nextState.agentKind);
        }
        if (nextState.agentUri && nextState.agentKind != this._state.agentKind) {
            (0, logger_1.warn)("Unsupported change of props: agentKind");
            this._client = new client_1.Client(nextState.agentUri, nextState.agentKind);
        }
        var bChangedView = false;
        //map
        if (nextState.mapName != this._state.mapName && this._map && this._ovMap) {
            this.hideAllPopups();
            var oldLayerSet = this.getLayerSetGroup(this._state.mapName);
            var newLayerSet = this.ensureAndGetLayerSetGroup(nextState);
            //Clear any stray hover highlighted features as part of switch
            oldLayerSet === null || oldLayerSet === void 0 ? void 0 : oldLayerSet.clearHighlightedFeatures();
            newLayerSet.clearHighlightedFeatures();
            oldLayerSet === null || oldLayerSet === void 0 ? void 0 : oldLayerSet.detach(this._map, this._ovMap);
            newLayerSet.setMapGuideMocking(this.getMockMode());
            newLayerSet.attach(this._map, this._ovMap);
            //This would happen if we switch to a map we haven't visited yet
            if (!nextState.view) {
                newLayerSet.fitViewToExtent();
                bChangedView = true;
            }
            else {
                var layerSet = this.getLayerSetGroup(nextState.mapName);
                if (layerSet) {
                    this.applyView(layerSet, nextState.view);
                }
            }
        }
        //selectionColor
        if (nextState.selectionColor && nextState.selectionColor != this._state.selectionColor) {
            var layerSet = this.getLayerSetGroup(nextState.mapName);
            layerSet === null || layerSet === void 0 ? void 0 : layerSet.updateSelectionColor(nextState.selectionColor);
        }
        //featureTooltipsEnabled
        if (nextState.featureTooltipsEnabled != this._state.featureTooltipsEnabled) {
            this.enableFeatureTooltips(nextState.featureTooltipsEnabled);
        }
        //externalBaseLayers
        if (nextState.externalBaseLayers != null &&
            nextState.externalBaseLayers.length > 0) {
            var layerSet = this.getLayerSetGroup(nextState.mapName);
            layerSet === null || layerSet === void 0 ? void 0 : layerSet.updateExternalBaseLayers(nextState.externalBaseLayers);
        }
        //Layer transparency
        if (nextState.layerTransparency && (0, viewer_state_1.layerTransparencyChanged)(nextState.layerTransparency, this._state.layerTransparency)) {
            var layerSet = this.getLayerSetGroup(nextState.mapName);
            layerSet === null || layerSet === void 0 ? void 0 : layerSet.updateTransparency(nextState.layerTransparency);
        }
        //Layer/Group visibility
        if (nextState.mapName && ((0, array_1.areArraysDifferent)(nextState.showGroups, this._state.showGroups) ||
            (0, array_1.areArraysDifferent)(nextState.hideGroups, this._state.hideGroups) ||
            (0, array_1.areArraysDifferent)(nextState.showLayers, this._state.showLayers) ||
            (0, array_1.areArraysDifferent)(nextState.hideLayers, this._state.hideLayers))) {
            this.refreshOnStateChange(nextState.mapName, nextState.showGroups, nextState.showLayers, nextState.hideGroups, nextState.hideLayers);
        }
        //view
        var bViewChanged = false;
        if (!(0, viewer_state_1.areViewsCloseToEqual)(nextState.view, this._state.view)) {
            var vw = nextState.view;
            if (vw != null && !bChangedView) {
                var layerSet = this.ensureAndGetLayerSetGroup(nextState);
                this.applyView(layerSet, vw);
                bViewChanged = true;
            }
            else {
                (0, logger_1.debug)("Skipping zoomToView as next/current views are close enough or target view is null");
            }
        }
        //overviewMapElement
        if (nextState.overviewMapElementSelector) {
            this.updateOverviewMapElement(nextState.overviewMapElementSelector);
        }
        //viewRotation
        if (this._state.viewRotation != nextState.viewRotation) {
            this.getOLView().setRotation(nextState.viewRotation);
        }
        //viewRotationEnabled
        if (this._state.viewRotationEnabled != nextState.viewRotationEnabled) {
            if (this._map) {
                var view = this.getOLView();
                var newView = new View_1.default({
                    enableRotation: nextState.viewRotationEnabled,
                    rotation: nextState.viewRotation,
                    center: view.getCenter(),
                    resolution: view.getResolution(),
                    resolutions: view.getResolutions(),
                    minResolution: view.getMinResolution(),
                    maxResolution: view.getMaxResolution(),
                    maxZoom: view.getMaxZoom(),
                    minZoom: view.getMinZoom(),
                    //constrainRotation: view.constrainRotation(),
                    projection: view.getProjection(),
                    zoom: view.getZoom()
                });
                this._map.setView(newView);
            }
        }
        //activeSelectedFeatureXml
        var bDiffSelectionXml = this._state.activeSelectedFeatureXml != nextState.activeSelectedFeatureXml;
        var bRefreshActiveFeatureSelection = !(0, string_1.strIsNullOrEmpty)(nextState.activeSelectedFeatureXml) && bViewChanged;
        if (bDiffSelectionXml || bRefreshActiveFeatureSelection) {
            if (this._map && nextState.map) {
                var ms_1 = this._map.getSize();
                if (ms_1 && (0, type_guards_1.isRuntimeMap)(nextState.map)) {
                    var nmap_1 = nextState.map;
                    // We don't want to request for an updated feature selection while there are still rendering operations in progress
                    // otherwise we may request a feature selection for a map whose internal view has been changed by the in-progress rendering
                    // operation
                    var checkReady_1 = function () {
                        if (_this._busyWorkers == 0) {
                            //console.log("Ready to request updated feature selection");
                            var view = _this.getOLView();
                            var me = view.calculateExtent(ms_1);
                            var size = { w: ms_1[0], h: ms_1[1] };
                            _this.showSelectedFeature(me, size, nmap_1, nextState.activeSelectedFeatureColor, nextState.activeSelectedFeatureXml);
                        }
                        else {
                            //console.log("Still busy. Hold off on request for updated feature selection");
                            window.setTimeout(checkReady_1, 100);
                        }
                    };
                    checkReady_1();
                }
            }
        }
        this._state = nextState;
    };
    MapGuideMapProviderContext.prototype.setSelectionXml = function (xml, queryOpts, success, failure) {
        var _this = this;
        var _a;
        if (!this._state.mapName || !this._comp || !this._state.sessionId || !this._state.selectionColor) {
            return;
        }
        //NOTE: A quirk of QUERYMAPFEATURES is that when passing in selection XML (instead of geometry),
        //you must set the layerattributefilter to the full bit mask otherwise certain features in the
        //selection XML will not be rendered because they may not pass the layer attribute filter
        var reqQueryFeatures = 1; //Attributes
        this.incrementBusyWorker();
        var mapName = this._state.mapName;
        var qOrig = {
            mapname: mapName,
            session: this._state.sessionId,
            persist: 1,
            featurefilter: xml,
            selectioncolor: this._state.selectionColor,
            selectionformat: (_a = this._state.selectionImageFormat) !== null && _a !== void 0 ? _a : "PNG8",
            maxfeatures: -1,
            requestdata: reqQueryFeatures
        };
        var queryOptions = tslib_1.__assign(tslib_1.__assign({}, qOrig), queryOpts);
        var action = (0, map_1.queryMapFeatures)(mapName, {
            options: queryOptions,
            callback: function (res) {
                _this.decrementBusyWorker();
                if (success) {
                    success(res);
                }
            },
            errBack: function (err) {
                _this.decrementBusyWorker();
                if (failure) {
                    failure(err);
                }
            }
        });
        this._comp.onDispatch(action);
    };
    MapGuideMapProviderContext.prototype.clearSelection = function () {
        this.setSelectionXml("");
    };
    MapGuideMapProviderContext.prototype.selectByGeometry = function (geom, selectionMethod) {
        var options = this.buildDefaultQueryOptions(geom);
        if (selectionMethod) {
            options.selectionvariant = selectionMethod;
        }
        this.sendSelectionQuery(options);
    };
    MapGuideMapProviderContext.prototype.queryMapFeatures = function (options, success, failure) {
        this.sendSelectionQuery(options, success, failure);
    };
    MapGuideMapProviderContext.prototype.isFeatureTooltipEnabled = function () {
        var _a;
        return ((_a = this._featureTooltip) === null || _a === void 0 ? void 0 : _a.isEnabled()) == true;
    };
    // ================= MapGuide-specific =================== //
    MapGuideMapProviderContext.prototype.sendSelectionQuery = function (queryOpts, success, failure) {
        var _this = this;
        var _a, _b;
        if (!this._state.mapName || !this._comp || !this._state.sessionId || !this._state.selectionColor || (queryOpts != null && ((_a = queryOpts.layernames) !== null && _a !== void 0 ? _a : []).length == 0)) {
            return;
        }
        this.incrementBusyWorker();
        var mapName = this._state.mapName;
        var qOrig = {
            mapname: mapName,
            session: this._state.sessionId,
            persist: 1,
            selectionvariant: "INTERSECTS",
            selectioncolor: this._state.selectionColor,
            selectionformat: (_b = this._state.selectionImageFormat) !== null && _b !== void 0 ? _b : "PNG8",
            maxfeatures: -1
        };
        var queryOptions = tslib_1.__assign(tslib_1.__assign({}, qOrig), queryOpts);
        var action = (0, map_1.queryMapFeatures)(mapName, {
            options: queryOptions,
            callback: function (res) {
                _this.decrementBusyWorker();
                if (success) {
                    success(res);
                }
            },
            errBack: function (err) {
                _this.decrementBusyWorker();
                if (failure) {
                    failure(err);
                }
            },
            append: this._comp.isShiftKeyDown()
        });
        this._comp.onDispatch(action);
    };
    return MapGuideMapProviderContext;
}(base_1.BaseMapProviderContext));
exports.MapGuideMapProviderContext = MapGuideMapProviderContext;
//# sourceMappingURL=mapguide.js.map