"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Map = void 0;
var tslib_1 = require("tslib");
var l7_1 = require("@antv/l7");
var event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter"));
var util_1 = require("@antv/util");
var tooltip_1 = require("../../component/tooltip");
var legend_1 = require("../../component/legend");
var utils_1 = require("../../utils");
var types_1 = require("../../types");
var layer_group_1 = require("../layer/layer-group");
var constants_1 = require("./constants");
var register_1 = require("./register");
var theme_1 = require("../../theme");
var util_2 = require("../../theme/util");
var DEFAULT_OPTIONS = {
    map: { type: types_1.BaseMapType.Amap },
    logo: true,
};
var Map = /** @class */ (function (_super) {
    tslib_1.__extends(Map, _super);
    function Map(options) {
        var _this = _super.call(this) || this;
        /**
         * 是否初始化成功
         */
        _this.inited = false;
        /**
         * 是否场景加载完成
         */
        _this.sceneLoaded = false;
        /**
         * 是否所有图层加载完成
         */
        _this.layersLoaded = false;
        /**
         * 是否场景与所有图层加载完成
         */
        _this.loaded = false;
        /**
         * 图层组
         */
        _this.layerGroup = new layer_group_1.LayerGroup();
        _this.options = (0, utils_1.deepAssign)({}, _this.getDefaultOptions(), options);
        _this.lastOptions = _this.options;
        return _this;
    }
    /**
     * 获取默认配置
     */
    Map.prototype.getDefaultOptions = function () {
        return Map.DefaultOptions;
    };
    /**
     * 创建 DOM 容器
     */
    Map.prototype.createContainer = function (container) {
        var _a = this.options, width = _a.width, height = _a.height;
        var dom = typeof container === 'string' ? document.getElementById(container) : container;
        dom.style.position || (dom.style.position = 'relative');
        if (width) {
            dom.style.width || (dom.style.width = "".concat(width, "px"));
        }
        if (height) {
            dom.style.height || (dom.style.height = "".concat(height, "px"));
        }
        return dom;
    };
    /**
     * 注册主题
     */
    Map.prototype.createTheme = function () {
        var theme = (0, util_1.isObject)(this.options.theme)
            ? (0, utils_1.deepAssign)({}, (0, theme_1.getTheme)('default'), (0, util_2.createTheme)(this.options.theme))
            : (0, theme_1.getTheme)(this.options.theme);
        return theme;
    };
    /**
     * 创建 map 容器
     */
    Map.prototype.createMap = function () {
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        var mapConfig = this.options.map ? this.options.map : DEFAULT_OPTIONS.map;
        var type = mapConfig.type, config = tslib_1.__rest(mapConfig, ["type"]);
        var options = Object.assign({ style: this.theme['mapStyle'] }, config);
        return type === types_1.BaseMapType.Amap
            ? new l7_1.GaodeMap(options)
            : type === types_1.BaseMapType.AmapV1
                ? new l7_1.GaodeMapV1(options)
                : type === types_1.BaseMapType.AmapV2
                    ? new l7_1.GaodeMapV2(options)
                    : type === types_1.BaseMapType.Mapbox
                        ? new l7_1.Mapbox(options)
                        : new l7_1.Map(options);
    };
    /**
     * 创建 scene 实例
     */
    Map.prototype.createScene = function () {
        var _a = this.options, logo = _a.logo, antialias = _a.antialias, preserveDrawingBuffer = _a.preserveDrawingBuffer;
        var logoConfig = (0, util_1.isBoolean)(logo)
            ? { logoVisible: logo }
            : { logoVisible: logo === null || logo === void 0 ? void 0 : logo.visible, logoPosition: logo === null || logo === void 0 ? void 0 : logo.position };
        var sceneConfig = Object.assign({
            // animate,
            // fitBoundsOptions,
            // pickBufferScale,
            // enableMultiPassRenderer,
            // passes,
            antialias: antialias,
            preserveDrawingBuffer: preserveDrawingBuffer,
        }, logoConfig);
        var map = this.createMap();
        var scene = new l7_1.Scene(tslib_1.__assign({ id: this.container, map: map }, sceneConfig));
        return scene;
    };
    /**
     * 注册静态资源
     */
    Map.prototype.registerResources = function () {
        var _this = this;
        if (register_1.IMAGES_CACHE.size) {
            register_1.IMAGES_CACHE.forEach(function (img, id) {
                !_this.scene.hasImage(id) && _this.scene.addImage(id, img);
            });
        }
        if (register_1.FONT_FACE_CACHE.size) {
            register_1.FONT_FACE_CACHE.forEach(function (fontPath, fontFamily) {
                _this.scene.addFontFace(fontFamily, fontPath);
            });
        }
        if (register_1.ICON_FONT_CACHE.size) {
            register_1.ICON_FONT_CACHE.forEach(function (name, fontUnicode) {
                _this.scene.addIconFont(fontUnicode, name);
            });
        }
    };
    /**
     * 更新: 更新配置且重新渲染
     */
    Map.prototype.update = function (options) {
        this.updateOption(options);
        if (options.map && !(0, util_1.isEqual)(this.lastOptions.map, this.options.map)) {
            this.updateMap(options.map);
        }
        this.render();
        this.emit('update');
    };
    /**
     * 更新: 更新配置
     */
    Map.prototype.updateOption = function (options) {
        this.lastOptions = this.options;
        this.options = (0, utils_1.deepAssign)({}, this.options, options);
    };
    /**
     * 更新: 地图底图配置
     */
    Map.prototype.updateMap = function (updateMapConfig) {
        var _a;
        if (!this.scene)
            return;
        var style = updateMapConfig.style, center = updateMapConfig.center, zoom = updateMapConfig.zoom, rotation = updateMapConfig.rotation, pitch = updateMapConfig.pitch;
        if (!(0, util_1.isUndefined)(pitch)) {
            this.scene.setPitch(pitch);
        }
        if (!(0, util_1.isUndefined)(rotation)) {
            this.scene.setRotation(rotation);
        }
        if (style && style !== ((_a = this.lastOptions.map) === null || _a === void 0 ? void 0 : _a.style)) {
            this.scene.setMapStyle(style);
        }
        if (zoom && center) {
            this.scene.setZoomAndCenter(zoom, center);
        }
    };
    /**
     * 修改容器大小
     */
    Map.prototype.changeSize = function (width, height) {
        if (this.options.width === width && this.options.height === height)
            return;
        this.container.style.width = "".concat(width, "px");
        this.container.style.height = "".concat(height, "px");
        this.options = Object.assign(this.options, { width: width, height: height });
    };
    /**
     * 事件代理: 绑定事件
     */
    Map.prototype.on = function (name, callback, once) {
        this.proxyEventHander('on', name, callback, once);
        return this;
    };
    /**
     * 事件代理: 绑定一次事件
     */
    Map.prototype.once = function (name, callback) {
        this.proxyEventHander('once', name, callback);
        return this;
    };
    /**
     * 事件代理: 解绑事件
     */
    Map.prototype.off = function (name, callback) {
        this.proxyEventHander('off', name, callback);
        return this;
    };
    /**
     * 事件代理: 事件处理
     */
    Map.prototype.proxyEventHander = function (type, name, callback, once) {
        var sceneEvent = constants_1.SceneEventList.find(function (event) { return event.adaptation === name; });
        if (sceneEvent) {
            this.scene[type](sceneEvent.original, callback);
        }
        else if (constants_1.MapEventList.indexOf(name) !== -1) {
            this.scene[type](name, callback);
        }
        else if (name.includes('Layer:')) {
            var _a = tslib_1.__read(name.split(':'), 2), module_1 = _a[0], eventName = _a[1];
            var hasEventEmitter = this[module_1] && this[module_1][type];
            if (hasEventEmitter && constants_1.LayerEventList.indexOf(eventName) !== -1) {
                this[module_1][type](eventName, callback);
            }
            else {
                throw new Error("No event name \"".concat(name, "\""));
            }
        }
        else {
            _super.prototype[type].call(this, name, callback, once);
        }
    };
    /**
     * 获取 scene 实例
     */
    Map.prototype.getScene = function () {
        return this.scene;
    };
    /**
     * 获取 map 实例
     */
    Map.prototype.getMap = function () {
        var _a, _b, _c, _d;
        if (((_a = this.options.map) === null || _a === void 0 ? void 0 : _a.type) === types_1.BaseMapType.Amap) {
            return this.scene.map;
        }
        else if (((_b = this.options.map) === null || _b === void 0 ? void 0 : _b.type) === types_1.BaseMapType.AmapV2) {
            return this.scene.map;
        }
        else if (((_c = this.options.map) === null || _c === void 0 ? void 0 : _c.type) === types_1.BaseMapType.Mapbox) {
            return this.scene.map;
        }
        else if (((_d = this.options.map) === null || _d === void 0 ? void 0 : _d.type) === types_1.BaseMapType.Map) {
            return this.scene.map;
        }
        else {
            return this.scene.map;
        }
    };
    /**
     * 添加图层
     */
    Map.prototype.addLayer = function (layer) {
        this.layerGroup.addLayer(layer);
    };
    /**
     * 获取所有图层
     *  @deprecate
     */
    Map.prototype.getLayes = function () {
        console.warn('Replace to use getLayers()');
        return this.getLayers();
    };
    /**
     * 获取所有图层
     */
    Map.prototype.getLayers = function () {
        return this.layerGroup.getLayers();
    };
    /**
     * 根据图层名称获取图层
     */
    Map.prototype.getLayerByName = function (name) {
        return this.layerGroup.getLayerByName(name);
    };
    /**
     * 移除图层
     */
    Map.prototype.removeLayer = function (layer) {
        return this.layerGroup.removeLayer(layer);
    };
    /**
     * 移除内置所有的图层
     */
    Map.prototype.removeAllLayer = function () {
        this.layerGroup.removeAllLayer();
    };
    /**
     * 地图放大一级
     */
    Map.prototype.zoomIn = function () {
        this.scene.zoomIn();
    };
    /**
     * 地图缩小一级
     */
    Map.prototype.zoomOut = function () {
        this.scene.zoomOut();
    };
    /**
     * 设置地图倾角
     */
    Map.prototype.setPitch = function (pitch) {
        this.scene.setPitch(pitch);
    };
    /**
     * 设置地图缩放范围
     */
    Map.prototype.fitBounds = function (bound) {
        this.scene.fitBounds(bound);
    };
    /**
     * 设置地图状态
     * 可用来关闭地图的一些交互操作
     */
    Map.prototype.setMapStatus = function (status) {
        this.scene.setMapStatus(status);
    };
    /**
     * 设置场景的背景色
     */
    Map.prototype.setBgColor = function (color) {
        this.scene.setBgColor(color);
    };
    /**
     * 初始化组件
     */
    Map.prototype.initComponents = function () {
        this.initControls();
        this.initTooltip();
    };
    /**
     * 更新化组件
     */
    Map.prototype.updateComponents = function () {
        this.updateControls();
        this.initTooltip();
    };
    /**
     * 初始化控件
     */
    Map.prototype.initControls = function () {
        var _a = this.options, zoom = _a.zoom, scale = _a.scale, layerMenu = _a.layerMenu, legend = _a.legend;
        scale && this.addScaleControl(scale);
        zoom && this.addZoomControl(zoom);
        layerMenu && this.addLayerMenuControl(layerMenu);
        if (legend) {
            this.addLegendControl(legend);
            this.emit('add-legend');
        }
    };
    /**
     * 更新控件
     */
    Map.prototype.updateControls = function () {
        var _a = this.options, zoom = _a.zoom, scale = _a.scale, layerMenu = _a.layerMenu, legend = _a.legend;
        if (!(0, util_1.isEqual)(this.lastOptions.zoom, zoom)) {
            zoom ? this.updateZoomControl(zoom) : this.removeZoomControl();
        }
        if (!(0, util_1.isEqual)(this.lastOptions.scale, scale)) {
            scale ? this.updateScaleControl(scale) : this.removeScaleControl();
        }
        if (!(0, util_1.isEqual)(this.lastOptions.layerMenu, layerMenu)) {
            layerMenu ? this.updateLayerMenuControl(layerMenu) : this.removeLayerMenuControl();
        }
        if (!(0, util_1.isEqual)(this.lastOptions.legend, legend)) {
            legend ? this.updateLegendControl(legend) : this.removeLegendControl();
        }
    };
    /**
     * 添加 zoom 控件
     */
    Map.prototype.addZoomControl = function (options) {
        if (this.zoomControl) {
            return;
        }
        this.zoomControl = new l7_1.Zoom(options);
        this.scene.addControl(this.zoomControl);
    };
    /**
     * 更新 zoom 控件
     */
    Map.prototype.updateZoomControl = function (options) {
        if (!this.zoomControl) {
            this.addZoomControl(options);
            return;
        }
        this.removeZoomControl();
        this.addZoomControl(options);
    };
    /**
     * 移除 zoom 控件
     */
    Map.prototype.removeZoomControl = function () {
        if (this.zoomControl) {
            this.zoomControl.remove();
            this.zoomControl = undefined;
        }
    };
    /**
     * 添加 scale 控件
     */
    Map.prototype.addScaleControl = function (options) {
        if (this.scaleControl) {
            return;
        }
        this.scaleControl = new l7_1.Scale(options);
        this.scene.addControl(this.scaleControl);
    };
    /**
     * 更新 scale 控件
     */
    Map.prototype.updateScaleControl = function (options) {
        if (!this.scaleControl) {
            this.addScaleControl(options);
            return;
        }
        this.removeScaleControl();
        this.addScaleControl(options);
    };
    /**
     * 移除 scale 控件
     */
    Map.prototype.removeScaleControl = function () {
        if (this.scaleControl) {
            this.scaleControl.remove();
            this.scaleControl = undefined;
        }
    };
    /**
     * 添加 layerMenu 控件
     */
    Map.prototype.addLayerMenuControl = function (options) {
        // if (this.layerMenuControl) {
        //   return;
        // }
        var baseLayers = {};
        var overlayers = {};
        this.layerGroup.getLayers().forEach(function (_a) {
            var name = _a.name, layer = _a.layer;
            overlayers[name] = layer;
        });
        // this.layerMenuControl = new Layers(Object.assign({}, options, { baseLayers, overlayers }));
        // this.scene.addControl(this.layerMenuControl);
    };
    /**
     * 更新 layerMenu 控件
     */
    Map.prototype.updateLayerMenuControl = function (options) {
        // if (!this.layerMenuControl) {
        //   this.addLayerMenuControl(options);
        //   return;
        // }
        this.removeLayerMenuControl();
        this.addLayerMenuControl(options);
    };
    /**
     * 移除 layerMenu 控件
     */
    Map.prototype.removeLayerMenuControl = function () {
        // if (this.layerMenuControl) {
        //   this.layerMenuControl.remove();
        //   this.layerMenuControl = undefined;
        // }
    };
    /**
     * 获取 legend 配置项
     * 由各图各自实现，不同的图 legend 可能不同
     */
    Map.prototype.getLegendOptions = function () {
        return {};
    };
    /**
     * 添加 legend 控件
     */
    Map.prototype.addLegendControl = function (options) {
        if (this.legendControl) {
            return;
        }
        var legendTheme = this.theme['components'].legend;
        var legendOptions = (0, utils_1.deepAssign)({}, this.getLegendOptions(), options);
        var type = legendOptions.type, position = legendOptions.position, rest = tslib_1.__rest(legendOptions, ["type", "position"]);
        var items = [];
        if (type === 'category') {
            var options_1 = (0, utils_1.deepAssign)({}, { domStyles: legendTheme.category.domStyles }, rest);
            items.push({ type: type, options: options_1 });
        }
        else if (type === 'continue') {
            var options_2 = (0, utils_1.deepAssign)({}, { domStyles: legendTheme.continue.domStyles }, rest);
            items.push({ type: type, options: options_2 });
        }
        if (items.length) {
            this.legendControl = new legend_1.Legend({ position: position, items: items });
            this.scene.addControl(this.legendControl);
        }
    };
    /**
     * 更新 legend 控件
     */
    Map.prototype.updateLegendControl = function (options) {
        if (!this.legendControl) {
            this.addLegendControl(options);
            return;
        }
        this.removeLegendControl();
        this.addLegendControl(options);
    };
    /**
     * 移除 legend 控件
     */
    Map.prototype.removeLegendControl = function () {
        if (this.legendControl) {
            this.legendControl.remove();
            this.legendControl = undefined;
        }
    };
    /**
     * 初始化 tooltip
     */
    Map.prototype.initTooltip = function () {
        var _this = this;
        if (this.tooltip) {
            this.tooltip.destroy();
        }
        var tooltip = this.options.tooltip;
        if (tooltip) {
            var options = (0, utils_1.deepAssign)({}, { domStyles: this.theme['components'].tooltip.domStyles }, tooltip);
            var interactionLayers = this.layerGroup.getInteractionLayers();
            this.tooltip = new tooltip_1.Tooltip(this.scene, interactionLayers, options);
            this.tooltip.on('*', function (event) { return _this.emit(event.type, event); });
        }
    };
    /**
     * 导出地图图片
     */
    Map.prototype.exportPng = function (type) {
        return this.scene.exportPng(type);
    };
    /**
     * 销毁
     */
    Map.prototype.destroy = function () {
        var _a;
        // TODO: 清空已经绑定其他的事件
        _super.prototype.off.call(this, '*');
        this.removeScaleControl();
        this.removeZoomControl();
        this.removeLayerMenuControl();
        this.removeLegendControl();
        (_a = this.tooltip) === null || _a === void 0 ? void 0 : _a.destroy();
        this.scene.destroy();
    };
    /**
     * 默认的 options 配置项
     */
    Map.DefaultOptions = DEFAULT_OPTIONS;
    return Map;
}(event_emitter_1.default));
exports.Map = Map;
//# sourceMappingURL=index.js.map