import { __assign, __extends, __rest } from "tslib";
import { clone, isEqual, isUndefined, omit } from '@antv/util';
import { CompositeLayer } from '../../core/composite-layer';
import { LineLayer } from '../../core-layers/line-layer';
import { PolygonLayer } from '../../core-layers/polygon-layer';
import { TextLayer } from '../../core-layers/text-layer';
import { getDefaultState } from './adaptor';
import { EMPTY_GEOJSON_SOURCE } from '../common/constants';
import { DEFAULT_OPTIONS, DEFAULT_STATE } from './constants';
import { getLabelLayerOptions } from '../common/label-layer';
var ChoroplethLayer = /** @class */ (function (_super) {
    __extends(ChoroplethLayer, _super);
    function ChoroplethLayer(options) {
        var _this = _super.call(this, options) || this;
        /**
         * 复合图层类型
         */
        _this.type = CompositeLayer.LayerType.ChoroplethLayer;
        /**
         * 选中数据
         */
        _this.selectData = [];
        /**
         * 图层交互状态配置
         */
        _this.layerState = DEFAULT_STATE;
        /**
         * 图层是否具有交互属性
         */
        _this.interaction = true;
        /**
         * 图层高亮回调
         */
        _this.onHighlighHandle = function (event) {
            var feature = event.feature, featureId = event.featureId;
            _this.setHighlightLayerSource(feature, featureId);
        };
        /**
         * 图层取消高亮回调
         */
        _this.onUnhighlighHandle = function () {
            _this.setHighlightLayerSource();
        };
        /**
         * 图层选中回调
         */
        _this.onSelectHandle = function (event) {
            var feature = event.feature, featureId = event.featureId;
            _this.handleSelectData(featureId, feature);
        };
        _this.initSubLayersEvent();
        return _this;
    }
    Object.defineProperty(ChoroplethLayer.prototype, "layer", {
        /**
         * 主图层
         */
        get: function () {
            return this.fillLayer;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ChoroplethLayer.prototype, "fillLayer", {
        /**
         * 填充面图层
         */
        get: function () {
            return this.subLayers.getLayer('fillLayer');
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ChoroplethLayer.prototype, "strokeLayer", {
        /**
         * 描边图层
         */
        get: function () {
            return this.subLayers.getLayer('strokeLayer');
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ChoroplethLayer.prototype, "highlightStrokeLayer", {
        /**
         * 高亮描边图层
         */
        get: function () {
            return this.subLayers.getLayer('highlightStrokeLayer');
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ChoroplethLayer.prototype, "selectFillLayer", {
        /**
         * 选中填充面图层
         */
        get: function () {
            return this.subLayers.getLayer('selectFillLayer');
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ChoroplethLayer.prototype, "selectStrokeLayer", {
        /**
         * 选中描边图层
         */
        get: function () {
            return this.subLayers.getLayer('selectStrokeLayer');
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ChoroplethLayer.prototype, "labelLayer", {
        /**
         * 标注文本图层
         */
        get: function () {
            return this.subLayers.getLayer('labelLayer');
        },
        enumerable: false,
        configurable: true
    });
    /**
     * 获取默认配置
     */
    ChoroplethLayer.prototype.getDefaultOptions = function () {
        return ChoroplethLayer.DefaultOptions;
    };
    /**
     * 创建子图层
     */
    ChoroplethLayer.prototype.createSubLayers = function () {
        var source = this.source;
        this.layerState = getDefaultState(this.options.state);
        // 映射填充面图层
        var fillLayer = new PolygonLayer(__assign(__assign({}, this.getFillLayerOptions()), { id: 'fillLayer', shape: 'fill', source: source }));
        var fillBottomColor = this.options.fillBottomColor;
        fillBottomColor && fillLayer.layer.setBottomColor(fillBottomColor);
        // 描边图层
        var strokeLayer = new LineLayer(__assign(__assign({}, this.getStrokeLayerOptions()), { id: 'strokeLayer', shape: 'line', source: source }));
        // 高亮描边图层
        var highlightStrokeLayer = new LineLayer(__assign(__assign({}, this.gethigHlightStrokeLayerOptions()), { id: 'highlightStrokeLayer' }));
        // 选中填充图层
        var selectFillLayer = new PolygonLayer(__assign(__assign({}, this.getSelectFillLayerOptions()), { id: 'selectFillLayer' }));
        // 选中描边图层
        var selectStrokeLayer = new LineLayer(__assign(__assign({}, this.getSelectStrokeLayerOptions()), { id: 'selectStrokeLayer' }));
        // 标注图层
        var labelLayer = new TextLayer(__assign(__assign({}, getLabelLayerOptions(this.options)), { id: 'labelLayer', source: source }));
        var subLayers = [fillLayer, strokeLayer, highlightStrokeLayer, selectFillLayer, selectStrokeLayer, labelLayer];
        return subLayers;
    };
    /**
     * 获取填充图层配置项
     */
    ChoroplethLayer.prototype.getFillLayerOptions = function () {
        // omit source 目前是图层共享 source，避免更新时透传 source 数据
        var _a = omit(this.options, ['source']), visible = _a.visible, minZoom = _a.minZoom, maxZoom = _a.maxZoom, _b = _a.zIndex, zIndex = _b === void 0 ? 0 : _b, fillColor = _a.fillColor, opacity = _a.opacity, baseConfig = __rest(_a, ["visible", "minZoom", "maxZoom", "zIndex", "fillColor", "opacity"]);
        var defaultState = this.layerState;
        var fillState = {
            active: defaultState.active.fillColor === false ? false : { color: defaultState.active.fillColor },
            select: false,
        };
        var fillStyle = { opacity: opacity };
        var options = __assign(__assign({}, baseConfig), { visible: visible, minZoom: minZoom, maxZoom: maxZoom, zIndex: zIndex, color: fillColor, state: fillState, style: fillStyle });
        return options;
    };
    ChoroplethLayer.prototype.getStrokeLayerOptions = function () {
        var _a = this.options, visible = _a.visible, minZoom = _a.minZoom, maxZoom = _a.maxZoom, _b = _a.zIndex, zIndex = _b === void 0 ? 0 : _b, opacity = _a.opacity, strokeColor = _a.strokeColor, lineWidth = _a.lineWidth, lineOpacity = _a.lineOpacity, lineDash = _a.lineDash, lineType = _a.lineType;
        var strokeStyle = {
            opacity: isUndefined(lineOpacity) ? opacity : lineOpacity,
            dashArray: lineDash,
            lineType: lineType,
        };
        var options = {
            visible: visible,
            zIndex: zIndex,
            minZoom: minZoom,
            maxZoom: maxZoom,
            size: lineWidth,
            color: strokeColor,
            style: strokeStyle,
        };
        return options;
    };
    ChoroplethLayer.prototype.gethigHlightStrokeLayerOptions = function () {
        var _a = this.options, visible = _a.visible, minZoom = _a.minZoom, maxZoom = _a.maxZoom, _b = _a.zIndex, zIndex = _b === void 0 ? 0 : _b, lineWidth = _a.lineWidth;
        var defaultState = this.layerState;
        var color = defaultState.active.strokeColor || undefined;
        var size = defaultState.active.lineWidth || lineWidth;
        var options = {
            visible: visible && Boolean(color),
            zIndex: zIndex + 0.1,
            minZoom: minZoom,
            maxZoom: maxZoom,
            source: EMPTY_GEOJSON_SOURCE,
            size: size,
            color: color,
            style: { opacity: defaultState.active.lineOpacity },
        };
        return options;
    };
    ChoroplethLayer.prototype.getSelectFillLayerOptions = function () {
        var _a = this.options, visible = _a.visible, minZoom = _a.minZoom, maxZoom = _a.maxZoom, _b = _a.zIndex, zIndex = _b === void 0 ? 0 : _b, opacity = _a.opacity;
        var defaultState = this.layerState;
        var color = defaultState.select.fillColor || undefined;
        var fillStyle = { opacity: opacity };
        var option = {
            visible: visible && Boolean(color),
            zIndex: zIndex + 0.1,
            minZoom: minZoom,
            maxZoom: maxZoom,
            source: EMPTY_GEOJSON_SOURCE,
            color: color,
            style: fillStyle,
            state: { select: false, active: false },
        };
        return option;
    };
    ChoroplethLayer.prototype.getSelectStrokeLayerOptions = function () {
        var _a = this.options, visible = _a.visible, minZoom = _a.minZoom, maxZoom = _a.maxZoom, _b = _a.zIndex, zIndex = _b === void 0 ? 0 : _b, lineWidth = _a.lineWidth;
        var defaultState = this.layerState;
        var color = defaultState.select.strokeColor || undefined;
        var size = defaultState.select.lineWidth || lineWidth;
        var option = {
            visible: visible && Boolean(color),
            zIndex: zIndex + 0.1,
            minZoom: minZoom,
            maxZoom: maxZoom,
            source: EMPTY_GEOJSON_SOURCE,
            size: size,
            color: color,
            style: { opacity: defaultState.select.lineOpacity },
        };
        return option;
    };
    /**
     * 设置子图层数据
     */
    ChoroplethLayer.prototype.setSubLayersSource = function (source) {
        if (this.isSourceInstance(source)) {
            this.source = source;
            this.fillLayer.setSource(source);
            this.strokeLayer.setSource(source);
            this.labelLayer.setSource(source);
        }
        else {
            var data = source.data, option = __rest(source, ["data"]);
            this.source.setData(data, option);
        }
        this.highlightStrokeLayer.changeData(EMPTY_GEOJSON_SOURCE);
        this.selectFillLayer.changeData(EMPTY_GEOJSON_SOURCE);
        this.selectStrokeLayer.changeData(EMPTY_GEOJSON_SOURCE);
    };
    /**
     * 设置高亮描边子图层数据
     */
    ChoroplethLayer.prototype.setHighlightLayerSource = function (feature, featureId) {
        if (featureId === void 0) { featureId = -999; }
        if (this.highlightData === featureId) {
            return;
        }
        var features = feature ? [feature] : [];
        var parser = this.source.parser;
        var data = parser.type === 'geojson' ? { type: 'FeatureCollection', features: features } : features;
        this.highlightStrokeLayer.changeData({ data: data, parser: parser });
        this.highlightData = featureId;
    };
    /**
     * 设置选中描边与填充子图层数据
     */
    ChoroplethLayer.prototype.setSelectLayerSource = function (selectData) {
        if (selectData === void 0) { selectData = []; }
        if (this.selectData.length === selectData.length &&
            isEqual(this.selectData.map(function (_a) {
                var featureId = _a.featureId;
                return featureId;
            }), selectData.map(function (_a) {
                var featureId = _a.featureId;
                return featureId;
            }))) {
            return;
        }
        var features = selectData.map(function (_a) {
            var feature = _a.feature;
            return feature;
        });
        var parser = this.source.parser;
        var data = parser.type === 'geojson' ? { type: 'FeatureCollection', features: features } : features;
        this.selectFillLayer.changeData({ data: data, parser: parser });
        this.selectStrokeLayer.changeData({ data: data, parser: parser });
        this.selectData = selectData;
    };
    /**
     * 初始化子图层事件
     */
    ChoroplethLayer.prototype.initSubLayersEvent = function () {
        // 初始化主图层交互事件
        this.fillLayer.off('mousemove', this.onHighlighHandle);
        this.fillLayer.off('mouseout', this.onHighlighHandle);
        this.fillLayer.off('click', this.onSelectHandle);
        this.selectData = [];
        this.highlightData = null;
        if (!this.options.state)
            return;
        // active
        if (this.options.state.active) {
            this.fillLayer.on('mousemove', this.onHighlighHandle);
            this.fillLayer.on('mouseout', this.onUnhighlighHandle);
        }
        // select
        if (this.options.state.select) {
            this.fillLayer.on('click', this.onSelectHandle);
        }
    };
    /**
     * 处理选择数据私有方法
     */
    ChoroplethLayer.prototype.handleSelectData = function (featureId, feature) {
        var enabledMultiSelect = this.options.enabledMultiSelect;
        var selectData = clone(this.selectData);
        var index = selectData.findIndex(function (item) { return item.featureId === featureId; });
        if (index === -1) {
            if (enabledMultiSelect) {
                selectData.push({ feature: feature, featureId: featureId });
            }
            else {
                selectData = [{ feature: feature, featureId: featureId }];
            }
            this.emit('select', feature, clone(selectData));
        }
        else {
            var unselectFeature = selectData[index];
            if (enabledMultiSelect) {
                selectData.splice(index, 1);
            }
            else {
                selectData = [];
            }
            this.emit('unselect', unselectFeature, clone(selectData));
        }
        this.setSelectLayerSource(selectData);
    };
    /**
     * 更新
     */
    ChoroplethLayer.prototype.update = function (options) {
        _super.prototype.update.call(this, options);
        this.initSubLayersEvent();
    };
    /**
     * 更新: 更新配置
     */
    ChoroplethLayer.prototype.updateOption = function (options) {
        _super.prototype.updateOption.call(this, options);
        this.layerState = getDefaultState(this.options.state);
    };
    /**
     * 更新子图层
     */
    ChoroplethLayer.prototype.updateSubLayers = function (options) {
        // 映射填充面图层
        this.fillLayer.update(this.getFillLayerOptions());
        // 描边图层
        this.strokeLayer.update(this.getStrokeLayerOptions());
        // 高亮图层
        this.highlightStrokeLayer.update(this.gethigHlightStrokeLayerOptions());
        // 选中填充图层
        this.selectFillLayer.update(this.getSelectFillLayerOptions());
        // 选中描边图层
        this.selectStrokeLayer.update(this.getSelectStrokeLayerOptions());
        // 标注图层
        this.labelLayer.update(getLabelLayerOptions(this.options));
        // 重置高亮/选中状态
        if (this.options.visible) {
            if (!isUndefined(options.state) && !isEqual(this.lastOptions.state, this.options.state)) {
                this.updateHighlightSubLayers();
            }
            if (this.layerState.active.strokeColor) {
                this.setHighlightLayerSource();
            }
            if (this.layerState.select.fillColor || this.layerState.select.strokeColor) {
                this.setSelectLayerSource();
            }
        }
    };
    /**
     * 更新高亮及选中子图层
     */
    ChoroplethLayer.prototype.updateHighlightSubLayers = function () {
        var defaultState = this.layerState;
        var lasetDefaultState = getDefaultState(this.lastOptions.state);
        if (lasetDefaultState.active.strokeColor !== defaultState.active.strokeColor) {
            defaultState.active.strokeColor ? this.highlightStrokeLayer.show() : this.highlightStrokeLayer.hide();
        }
        if (lasetDefaultState.select.fillColor !== defaultState.select.fillColor) {
            defaultState.select.fillColor ? this.selectFillLayer.show() : this.selectFillLayer.hide();
        }
        if (lasetDefaultState.select.strokeColor !== defaultState.select.strokeColor) {
            defaultState.select.strokeColor ? this.selectStrokeLayer.show() : this.selectStrokeLayer.hide();
        }
    };
    /**
     * 设置图层 zIndex
     */
    ChoroplethLayer.prototype.setIndex = function (zIndex) {
        this.fillLayer.setIndex(zIndex);
        this.strokeLayer.setIndex(zIndex);
        this.highlightStrokeLayer.setIndex(zIndex + 0.1);
        this.selectFillLayer.setIndex(zIndex + 0.1);
        this.selectStrokeLayer.setIndex(zIndex + 0.1);
        this.labelLayer.setIndex(zIndex + 0.1);
    };
    /**
     * 设置图层高亮状态
     */
    ChoroplethLayer.prototype.setActive = function (field, value) {
        var source = this.fillLayer.source;
        var featureId = source.getFeatureId(field, value);
        if (isUndefined(featureId)) {
            throw new Error('Feature non-existent' + field + value);
        }
        if (this.layerState.active.fillColor) {
            this.fillLayer.layer.setActive(featureId);
        }
        if (this.layerState.active.strokeColor) {
            var feature = source.getFeatureById(featureId);
            this.setHighlightLayerSource(feature, featureId);
        }
    };
    /**
     * 设置图层选中状态
     */
    ChoroplethLayer.prototype.setSelect = function (field, value) {
        var source = this.fillLayer.source;
        var featureId = source.getFeatureId(field, value);
        if (isUndefined(featureId)) {
            throw new Error('Feature non-existent' + field + value);
        }
        if (this.layerState.select.strokeColor === false || this.layerState.select.fillColor === false) {
            return;
        }
        var feature = source.getFeatureById(featureId);
        this.handleSelectData(featureId, feature);
        // TODO: L7 method pickFeature(id|{x,y})
    };
    /**
     * 图层框选数据
     */
    ChoroplethLayer.prototype.boxSelect = function (bounds, callback) {
        this.fillLayer.boxSelect(bounds, callback);
    };
    /**
     * 默认配置项
     */
    ChoroplethLayer.DefaultOptions = DEFAULT_OPTIONS;
    return ChoroplethLayer;
}(CompositeLayer));
export { ChoroplethLayer };
//# sourceMappingURL=index.js.map