/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import * as zrUtil from 'zrender/src/core/util';
import RoamController from './RoamController';
import * as roamHelper from '../../component/helper/roamHelper';
import {onIrrelevantElement} from '../../component/helper/cursorHelper';
import * as graphic from '../../util/graphic';
import {
    toggleHoverEmphasis,
    enableComponentHighDownFeatures,
    setDefaultStateProxy
} from '../../util/states';
import geoSourceManager from '../../coord/geo/geoSourceManager';
import {getUID} from '../../util/component';
import ExtensionAPI from '../../core/ExtensionAPI';
import GeoModel, { GeoCommonOptionMixin, GeoItemStyleOption, RegoinOption } from '../../coord/geo/GeoModel';
import MapSeries, { MapDataItemOption } from '../../chart/map/MapSeries';
import GlobalModel from '../../model/Global';
import { Payload, ECElement, LineStyleOption, InnerFocus, DisplayState } from '../../util/types';
import GeoView from '../geo/GeoView';
import MapView from '../../chart/map/MapView';
import Geo from '../../coord/geo/Geo';
import Model from '../../model/Model';
import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle';
import { getECData } from '../../util/innerStore';
import { createOrUpdatePatternFromDecal } from '../../util/decal';
import ZRText, {TextStyleProps} from 'zrender/src/graphic/Text';
import { ViewCoordSysTransformInfoPart } from '../../coord/View';
import { GeoSVGGraphicRecord, GeoSVGResource } from '../../coord/geo/GeoSVGResource';
import Displayable from 'zrender/src/graphic/Displayable';
import Element from 'zrender/src/Element';
import SeriesData from '../../data/SeriesData';
import { GeoJSONRegion } from '../../coord/geo/Region';
import { SVGNodeTagLower } from 'zrender/src/tool/parseSVG';
import { makeInner } from '../../util/model';
import { GeoProjection, ProjectionStream } from '../../coord/geo/geoTypes';

interface RegionsGroup extends graphic.Group {
}

type RegionModel = ReturnType<GeoModel['getRegionModel']> | ReturnType<MapSeries['getRegionModel']>;

type MapOrGeoModel = GeoModel | MapSeries;

interface ViewBuildContext {
    api: ExtensionAPI;
    geo: Geo;
    mapOrGeoModel: GeoModel | MapSeries;
    data: SeriesData;
    isVisualEncodedByVisualMap: boolean;
    isGeo: boolean;
    transformInfoRaw: ViewCoordSysTransformInfoPart;
}

interface GeoStyleableOption {
    itemStyle?: GeoItemStyleOption;
    lineStyle?: LineStyleOption;
}
type RegionName = string;

/**
 * Only these tags enable use `itemStyle` if they are named in SVG.
 * Other tags like <text> <tspan> <image> might not suitable for `itemStyle`.
 * They will not be considered to be styled until some requirements come.
 */
const OPTION_STYLE_ENABLED_TAGS: SVGNodeTagLower[] = [
    'rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path'
];
const OPTION_STYLE_ENABLED_TAG_MAP = zrUtil.createHashMap<number, SVGNodeTagLower>(
    OPTION_STYLE_ENABLED_TAGS
);
const STATE_TRIGGER_TAG_MAP = zrUtil.createHashMap<number, SVGNodeTagLower>(
    OPTION_STYLE_ENABLED_TAGS.concat(['g']) as SVGNodeTagLower[]
);
const LABEL_HOST_MAP = zrUtil.createHashMap<number, SVGNodeTagLower>(
    OPTION_STYLE_ENABLED_TAGS.concat(['g']) as SVGNodeTagLower[]
);
const mapLabelRaw = makeInner<{
    ignore: boolean
}, ZRText>();


function getFixedItemStyle(model: Model<GeoItemStyleOption>) {
    const itemStyle = model.getItemStyle();
    const areaColor = model.get('areaColor');

    // If user want the color not to be changed when hover,
    // they should both set areaColor and color to be null.
    if (areaColor != null) {
        itemStyle.fill = areaColor;
    }

    return itemStyle;
}
// Only stroke can be used for line.
// Using fill in style if stroke not exits.
// TODO Not sure yet. Perhaps a separate `lineStyle`?
function fixLineStyle(styleHost: { style: graphic.Path['style'] }) {
    const style = styleHost.style;
    if (style) {
        style.stroke = (style.stroke || style.fill);
        style.fill = null;
    }
}

class MapDraw {

    private uid: string;

    private _controller: RoamController;

    private _controllerHost: {
        target: graphic.Group;
        zoom?: number;
        zoomLimit?: GeoCommonOptionMixin['scaleLimit'];
    };

    readonly group: graphic.Group;


    /**
     * This flag is used to make sure that only one among
     * `pan`, `zoom`, `click` can occurs, otherwise 'selected'
     * action may be triggered when `pan`, which is unexpected.
     */
    private _mouseDownFlag: boolean;

    private _regionsGroup: RegionsGroup;

    private _regionsGroupByName: zrUtil.HashMap<RegionsGroup>;

    private _svgMapName: string;

    private _svgGroup: graphic.Group;

    private _svgGraphicRecord: GeoSVGGraphicRecord;

    // A name may correspond to multiple graphics.
    // Used as event dispatcher.
    private _svgDispatcherMap: zrUtil.HashMap<Element[], RegionName>;


    constructor(api: ExtensionAPI) {
        const group = new graphic.Group();
        this.uid = getUID('ec_map_draw');
        this._controller = new RoamController(api.getZr());
        this._controllerHost = { target: group };
        this.group = group;

        group.add(this._regionsGroup = new graphic.Group() as RegionsGroup);
        group.add(this._svgGroup = new graphic.Group());
    }

    draw(
        mapOrGeoModel: GeoModel | MapSeries,
        ecModel: GlobalModel,
        api: ExtensionAPI,
        fromView: MapView | GeoView,
        payload: Payload
    ): void {

        const isGeo = mapOrGeoModel.mainType === 'geo';

        // Map series has data. GEO model that controlled by map series
        // will be assigned with map data. Other GEO model has no data.
        let data = (mapOrGeoModel as MapSeries).getData && (mapOrGeoModel as MapSeries).getData();
        isGeo && ecModel.eachComponent({mainType: 'series', subType: 'map'}, function (mapSeries: MapSeries) {
            if (!data && mapSeries.getHostGeoModel() === mapOrGeoModel) {
                data = mapSeries.getData();
            }
        });

        const geo = mapOrGeoModel.coordinateSystem;

        const regionsGroup = this._regionsGroup;
        const group = this.group;

        const transformInfo = geo.getTransformInfo();
        const transformInfoRaw = transformInfo.raw;
        const transformInfoRoam = transformInfo.roam;

        // No animation when first draw or in action
        const isFirstDraw = !regionsGroup.childAt(0) || payload;

        if (isFirstDraw) {
            group.x = transformInfoRoam.x;
            group.y = transformInfoRoam.y;
            group.scaleX = transformInfoRoam.scaleX;
            group.scaleY = transformInfoRoam.scaleY;
            group.dirty();
        }
        else {
            graphic.updateProps(group, transformInfoRoam, mapOrGeoModel);
        }

        const isVisualEncodedByVisualMap = data
            && data.getVisual('visualMeta')
            && data.getVisual('visualMeta').length > 0;

        const viewBuildCtx = {
            api,
            geo,
            mapOrGeoModel,
            data,
            isVisualEncodedByVisualMap,
            isGeo,
            transformInfoRaw
        };

        if (geo.resourceType === 'geoJSON') {
            this._buildGeoJSON(viewBuildCtx);
        }
        else if (geo.resourceType === 'geoSVG') {
            this._buildSVG(viewBuildCtx);
        }

        this._updateController(mapOrGeoModel, ecModel, api);

        this._updateMapSelectHandler(mapOrGeoModel, regionsGroup, api, fromView);
    }

    private _buildGeoJSON(viewBuildCtx: ViewBuildContext): void {
        const regionsGroupByName = this._regionsGroupByName = zrUtil.createHashMap<RegionsGroup, string>();
        const regionsInfoByName = zrUtil.createHashMap<{
            dataIdx: number;
            regionModel: Model<RegoinOption> | Model<MapDataItemOption>;
        }, string>();
        const regionsGroup = this._regionsGroup;
        const transformInfoRaw = viewBuildCtx.transformInfoRaw;
        const mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
        const data = viewBuildCtx.data;
        const projection = viewBuildCtx.geo.projection;
        const projectionStream = projection && projection.stream;

        function transformPoint(point: number[], project: GeoProjection['project']): number[] {
            if (project) {
                // projection may return null point.
                point = project(point);
            }
            return point && [
                point[0] * transformInfoRaw.scaleX + transformInfoRaw.x,
                point[1] * transformInfoRaw.scaleY + transformInfoRaw.y
            ];
        };

        function transformPolygonPoints(inPoints: number[][]): number[][] {
            const outPoints = [];
            // If projectionStream is provided. Use it instead of single point project.
            const project = !projectionStream && projection && projection.project;
            for (let i = 0; i < inPoints.length; ++i) {
                const newPt = transformPoint(inPoints[i], project);
                newPt && outPoints.push(newPt);
            }
            return outPoints;
        }

        function getPolyShape(points: number[][]) {
            return {
                shape: {
                    points: transformPolygonPoints(points)
                }
            };
        }

        regionsGroup.removeAll();

        // Only when the resource is GeoJSON, there is `geo.regions`.
        zrUtil.each(viewBuildCtx.geo.regions, function (region: GeoJSONRegion) {
            const regionName = region.name;

            // Consider in GeoJson properties.name may be duplicated, for example,
            // there is multiple region named "United Kindom" or "France" (so many
            // colonies). And it is not appropriate to merge them in geo, which
            // will make them share the same label and bring trouble in label
            // location calculation.
            let regionGroup = regionsGroupByName.get(regionName);
            let { dataIdx, regionModel } = regionsInfoByName.get(regionName) || {};

            if (!regionGroup) {
                regionGroup = regionsGroupByName.set(regionName, new graphic.Group() as RegionsGroup);
                regionsGroup.add(regionGroup);

                dataIdx = data ? data.indexOfName(regionName) : null;
                regionModel = viewBuildCtx.isGeo
                    ? mapOrGeoModel.getRegionModel(regionName)
                    : (data ? data.getItemModel(dataIdx) as Model<MapDataItemOption> : null);

                regionsInfoByName.set(regionName, { dataIdx, regionModel });
            }

            const polygonSubpaths: graphic.Polygon[] = [];
            const polylineSubpaths: graphic.Polyline[] = [];

            zrUtil.each(region.geometries, function (geometry) {
                // Polygon and MultiPolygon
                if (geometry.type === 'polygon') {
                    let polys = [geometry.exterior].concat(geometry.interiors || []);
                    if (projectionStream) {
                        polys = projectPolys(polys, projectionStream);
                    }
                    zrUtil.each(polys, (poly) => {
                        polygonSubpaths.push(new graphic.Polygon(getPolyShape(poly)));
                    });
                }
                // LineString and MultiLineString
                else {
                    let points = geometry.points;
                    if (projectionStream) {
                        points = projectPolys(points, projectionStream, true);
                    }
                    zrUtil.each(points, points => {
                        polylineSubpaths.push(new graphic.Polyline(getPolyShape(points)));
                    });
                }
            });

            const centerPt = transformPoint(region.getCenter(), projection && projection.project);

            function createCompoundPath(subpaths: graphic.Path[], isLine?: boolean) {
                if (!subpaths.length) {
                    return;
                }
                const compoundPath = new graphic.CompoundPath({
                    culling: true,
                    segmentIgnoreThreshold: 1,
                    shape: {
                        paths: subpaths
                    }
                });
                regionGroup.add(compoundPath);
                applyOptionStyleForRegion(
                    viewBuildCtx, compoundPath, dataIdx, regionModel
                );
                resetLabelForRegion(
                    viewBuildCtx, compoundPath, regionName, regionModel, mapOrGeoModel, dataIdx, centerPt
                );

                if (isLine) {
                    fixLineStyle(compoundPath);
                    zrUtil.each(compoundPath.states, fixLineStyle);
                }
            }

            createCompoundPath(polygonSubpaths);
            createCompoundPath(polylineSubpaths, true);
        });

        // Ensure children have been added to `regionGroup` before calling them.
        regionsGroupByName.each(function (regionGroup, regionName) {
            const { dataIdx, regionModel } = regionsInfoByName.get(regionName);

            resetEventTriggerForRegion(
                viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel, dataIdx
            );
            resetTooltipForRegion(
                viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel
            );
            resetStateTriggerForRegion(
                viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel
            );

        }, this);
    }

    private _buildSVG(viewBuildCtx: ViewBuildContext): void {
        const mapName = viewBuildCtx.geo.map;
        const transformInfoRaw = viewBuildCtx.transformInfoRaw;

        this._svgGroup.x = transformInfoRaw.x;
        this._svgGroup.y = transformInfoRaw.y;
        this._svgGroup.scaleX = transformInfoRaw.scaleX;
        this._svgGroup.scaleY = transformInfoRaw.scaleY;

        if (this._svgResourceChanged(mapName)) {
            this._freeSVG();
            this._useSVG(mapName);
        }

        const svgDispatcherMap = this._svgDispatcherMap = zrUtil.createHashMap<Element[], RegionName>();

        let focusSelf = false;
        zrUtil.each(this._svgGraphicRecord.named, function (namedItem) {
            // Note that we also allow different elements have the same name.
            // For example, a glyph of a city and the label of the city have
            // the same name and their tooltip info can be defined in a single
            // region option.

            const regionName = namedItem.name;
            const mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
            const data = viewBuildCtx.data;
            const svgNodeTagLower = namedItem.svgNodeTagLower;
            const el = namedItem.el;

            const dataIdx = data ? data.indexOfName(regionName) : null;
            const regionModel = mapOrGeoModel.getRegionModel(regionName);

            if (OPTION_STYLE_ENABLED_TAG_MAP.get(svgNodeTagLower) != null
                && (el instanceof Displayable)
            ) {
                applyOptionStyleForRegion(viewBuildCtx, el, dataIdx, regionModel);
            }

            if (el instanceof Displayable) {
                el.culling = true;
            }

            // We do not know how the SVG like so we'd better not to change z2.
            // Otherwise it might bring some unexpected result. For example,
            // an area hovered that make some inner city can not be clicked.
            (el as ECElement).z2EmphasisLift = 0;

            // If self named:
            if (!namedItem.namedFrom) {
                // label should batter to be displayed based on the center of <g>
                // if it is named rather than displayed on each child.
                if (LABEL_HOST_MAP.get(svgNodeTagLower) != null) {
                    resetLabelForRegion(
                        viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx, null
                    );
                }

                resetEventTriggerForRegion(
                    viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx
                );

                resetTooltipForRegion(
                    viewBuildCtx, el, regionName, regionModel, mapOrGeoModel
                );

                if (STATE_TRIGGER_TAG_MAP.get(svgNodeTagLower) != null) {
                    const focus = resetStateTriggerForRegion(
                        viewBuildCtx, el, regionName, regionModel, mapOrGeoModel
                    );
                    if (focus === 'self') {
                        focusSelf = true;
                    }
                    const els = svgDispatcherMap.get(regionName) || svgDispatcherMap.set(regionName, []);
                    els.push(el);
                }
            }

        }, this);

        this._enableBlurEntireSVG(focusSelf, viewBuildCtx);
    }

    private _enableBlurEntireSVG(
        focusSelf: boolean,
        viewBuildCtx: ViewBuildContext
    ): void {
        // It's a little complicated to support blurring the entire geoSVG in series-map.
        // So do not suport it until some requirements come.
        // At present, in series-map, only regions can be blurred.
        if (focusSelf && viewBuildCtx.isGeo) {
            const blurStyle = (viewBuildCtx.mapOrGeoModel as GeoModel).getModel(['blur', 'itemStyle']).getItemStyle();
            // Only suport `opacity` here. Because not sure that other props are suitable for
            // all of the elements generated by SVG (especially for Text/TSpan/Image/... ).
            const opacity = blurStyle.opacity;
            this._svgGraphicRecord.root.traverse(el => {
                if (!el.isGroup) {
                    // PENDING: clear those settings to SVG elements when `_freeSVG`.
                    // (Currently it happen not to be needed.)
                    setDefaultStateProxy(el as Displayable);
                    const style = (el as Displayable).ensureState('blur').style || {};
                    // Do not overwrite the region style that already set from region option.
                    if (style.opacity == null && opacity != null) {
                        style.opacity = opacity;
                    }
                    // If `ensureState('blur').style = {}`, there will be default opacity.

                    // Enable `stateTransition` (animation).
                    (el as Displayable).ensureState('emphasis');
                }
            });
        }
    }

    remove(): void {
        this._regionsGroup.removeAll();
        this._regionsGroupByName = null;
        this._svgGroup.removeAll();
        this._freeSVG();
        this._controller.dispose();
        this._controllerHost = null;
    }

    findHighDownDispatchers(name: string, geoModel: GeoModel): Element[] {
        if (name == null) {
            return [];
        }

        const geo = geoModel.coordinateSystem;

        if (geo.resourceType === 'geoJSON') {
            const regionsGroupByName = this._regionsGroupByName;
            if (regionsGroupByName) {
                const regionGroup = regionsGroupByName.get(name);
                return regionGroup ? [regionGroup] : [];
            }
        }
        else if (geo.resourceType === 'geoSVG') {
            return this._svgDispatcherMap && this._svgDispatcherMap.get(name) || [];
        }
    }

    private _svgResourceChanged(mapName: string): boolean {
        return this._svgMapName !== mapName;
    }

    private _useSVG(mapName: string): void {
        const resource = geoSourceManager.getGeoResource(mapName);
        if (resource && resource.type === 'geoSVG') {
            const svgGraphic = (resource as GeoSVGResource).useGraphic(this.uid);
            this._svgGroup.add(svgGraphic.root);
            this._svgGraphicRecord = svgGraphic;
            this._svgMapName = mapName;
        }
    }

    private _freeSVG(): void {
        const mapName = this._svgMapName;
        if (mapName == null) {
            return;
        }

        const resource = geoSourceManager.getGeoResource(mapName);
        if (resource && resource.type === 'geoSVG') {
            (resource as GeoSVGResource).freeGraphic(this.uid);
        }
        this._svgGraphicRecord = null;
        this._svgDispatcherMap = null;
        this._svgGroup.removeAll();
        this._svgMapName = null;
    }

    private _updateController(
        this: MapDraw, mapOrGeoModel: GeoModel | MapSeries, ecModel: GlobalModel, api: ExtensionAPI
    ): void {
        const geo = mapOrGeoModel.coordinateSystem;
        const controller = this._controller;
        const controllerHost = this._controllerHost;

        // @ts-ignore FIXME:TS
        controllerHost.zoomLimit = mapOrGeoModel.get('scaleLimit');
        controllerHost.zoom = geo.getZoom();

        // roamType is will be set default true if it is null
        // @ts-ignore FIXME:TS
        controller.enable(mapOrGeoModel.get('roam') || false);
        const mainType = mapOrGeoModel.mainType;

        function makeActionBase(): Payload {
            const action = {
                type: 'geoRoam',
                componentType: mainType
            } as Payload;
            action[mainType + 'Id'] = mapOrGeoModel.id;
            return action;
        }

        controller.off('pan').on('pan', function (e) {
            this._mouseDownFlag = false;

            roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);

            api.dispatchAction(zrUtil.extend(makeActionBase(), {
                dx: e.dx,
                dy: e.dy,
                animation: {
                    duration: 0
                }
            }));
        }, this);

        controller.off('zoom').on('zoom', function (e) {
            this._mouseDownFlag = false;

            roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);

            api.dispatchAction(zrUtil.extend(makeActionBase(), {
                zoom: e.scale,
                originX: e.originX,
                originY: e.originY,
                animation: {
                    duration: 0
                }
            }));

        }, this);

        controller.setPointerChecker(function (e, x, y) {
            return geo.containPoint([x, y])
                && !onIrrelevantElement(e, api, mapOrGeoModel);
        });
    }

    /**
     * FIXME: this is a temporarily workaround.
     * When `geoRoam` the elements need to be reset in `MapView['render']`, because the props like
     * `ignore` might have been modified by `LabelManager`, and `LabelManager#addLabelsOfSeries`
     * will subsequently cache `defaultAttr` like `ignore`. If do not do this reset, the modified
     * props will have no chance to be restored.
     * Note: This reset should be after `clearStates` in `renderSeries` because `useStates` in
     * `renderSeries` will cache the modified `ignore` to `el._normalState`.
     * TODO:
     * Use clone/immutable in `LabelManager`?
     */
    resetForLabelLayout() {
        this.group.traverse(el => {
            const label = el.getTextContent();
            if (label) {
                label.ignore = mapLabelRaw(label).ignore;
            }
        });
    }

    private _updateMapSelectHandler(
        mapOrGeoModel: GeoModel | MapSeries,
        regionsGroup: RegionsGroup,
        api: ExtensionAPI,
        fromView: MapView | GeoView
    ): void {
        const mapDraw = this;

        regionsGroup.off('mousedown');
        regionsGroup.off('click');

        // @ts-ignore FIXME:TS resolve type conflict
        if (mapOrGeoModel.get('selectedMode')) {

            regionsGroup.on('mousedown', function () {
                mapDraw._mouseDownFlag = true;
            });

            regionsGroup.on('click', function (e) {
                if (!mapDraw._mouseDownFlag) {
                    return;
                }
                mapDraw._mouseDownFlag = false;
            });
        }
    }

};

function applyOptionStyleForRegion(
    viewBuildCtx: ViewBuildContext,
    el: Displayable,
    dataIndex: number,
    regionModel: Model<
        GeoStyleableOption & {
            emphasis?: GeoStyleableOption;
            select?: GeoStyleableOption;
            blur?: GeoStyleableOption;
        }
    >
): void {
    // All of the path are using `itemStyle`, because
    // (1) Some SVG also use fill on polyline (The different between
    // polyline and polygon is "open" or "close" but not fill or not).
    // (2) For the common props like opacity, if some use itemStyle
    // and some use `lineStyle`, it might confuse users.
    // (3) Most SVG use <path>, where can not detect wether draw a "line"
    // or a filled shape, so use `itemStyle` for <path>.

    const normalStyleModel = regionModel.getModel('itemStyle');
    const emphasisStyleModel = regionModel.getModel(['emphasis', 'itemStyle']);
    const blurStyleModel = regionModel.getModel(['blur', 'itemStyle']);
    const selectStyleModel = regionModel.getModel(['select', 'itemStyle']);

    // NOTE: DONT use 'style' in visual when drawing map.
    // This component is used for drawing underlying map for both geo component and map series.
    const normalStyle = getFixedItemStyle(normalStyleModel);
    const emphasisStyle = getFixedItemStyle(emphasisStyleModel);
    const selectStyle = getFixedItemStyle(selectStyleModel);
    const blurStyle = getFixedItemStyle(blurStyleModel);

    // Update the itemStyle if has data visual
    const data = viewBuildCtx.data;
    if (data) {
        // Only visual color of each item will be used. It can be encoded by visualMap
        // But visual color of series is used in symbol drawing

        // Visual color for each series is for the symbol draw
        const style = data.getItemVisual(dataIndex, 'style');
        const decal = data.getItemVisual(dataIndex, 'decal');
        if (viewBuildCtx.isVisualEncodedByVisualMap && style.fill) {
            normalStyle.fill = style.fill;
        }
        if (decal) {
            normalStyle.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api);
        }
    }

    // SVG text, tspan and image can be named but not supporeted
    // to be styled by region option yet.
    el.setStyle(normalStyle);
    el.style.strokeNoScale = true;
    el.ensureState('emphasis').style = emphasisStyle;
    el.ensureState('select').style = selectStyle;
    el.ensureState('blur').style = blurStyle;

    // Enable blur
    setDefaultStateProxy(el);
}

function resetLabelForRegion(
    viewBuildCtx: ViewBuildContext,
    el: Element,
    regionName: string,
    regionModel: RegionModel,
    mapOrGeoModel: MapOrGeoModel,
    // Exist only if `viewBuildCtx.data` exists.
    dataIdx: number,
    // If labelXY not provided, use `textConfig.position: 'inside'`
    labelXY: number[]
): void {
    const data = viewBuildCtx.data;
    const isGeo = viewBuildCtx.isGeo;

    const isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx) as number);
    const itemLayout = data && data.getItemLayout(dataIdx);

    // In the following cases label will be drawn
    // 1. In map series and data value is NaN
    // 2. In geo component
    // 3. Region has no series legendIcon, which will be add a showLabel flag in mapSymbolLayout
    if (
        ((isGeo || isDataNaN))
        || (itemLayout && itemLayout.showLabel)
    ) {

        const query = !isGeo ? dataIdx : regionName;
        let labelFetcher;

        // Consider dataIdx not found.
        if (!data || dataIdx >= 0) {
            labelFetcher = mapOrGeoModel;
        }

        const specifiedTextOpt: Partial<Record<DisplayState, TextStyleProps>> = labelXY ? {
            normal: {
                align: 'center',
                verticalAlign: 'middle'
            }
        } : null;

        // Caveat: must be called after `setDefaultStateProxy(el);` called.
        // because textContent will be assign with `el.stateProxy` inside.
        setLabelStyle<typeof query>(
            el,
            getLabelStatesModels(regionModel),
            {
                labelFetcher,
                labelDataIndex: query,
                defaultText: regionName
            },
            specifiedTextOpt
        );

        const textEl = el.getTextContent();
        if (textEl) {
            mapLabelRaw(textEl).ignore = textEl.ignore;

            if (el.textConfig && labelXY) {
                // Compute a relative offset based on the el bounding rect.
                const rect = el.getBoundingRect().clone();
                // Need to make sure the percent position base on the same rect in normal and
                // emphasis state. Otherwise if using boundingRect of el, but the emphasis state
                // has borderWidth (even 0.5px), the text position will be changed obviously
                // if the position is very big like ['1234%', '1345%'].
                el.textConfig.layoutRect = rect;
                el.textConfig.position = [
                    ((labelXY[0] - rect.x) / rect.width * 100) + '%',
                    ((labelXY[1] - rect.y) / rect.height * 100) + '%'
                ];
            }
        }

        // PENDING:
        // If labelLayout is enabled (test/label-layout.html), el.dataIndex should be specified.
        // But el.dataIndex is also used to determine whether user event should be triggered,
        // where el.seriesIndex or el.dataModel must be specified. At present for a single el
        // there is not case that "only label layout enabled but user event disabled", so here
        // we depends `resetEventTriggerForRegion` to do the job of setting `el.dataIndex`.

        (el as ECElement).disableLabelAnimation = true;
    }
    else {
        el.removeTextContent();
        el.removeTextConfig();
        (el as ECElement).disableLabelAnimation = null;
    }
}

function resetEventTriggerForRegion(
    viewBuildCtx: ViewBuildContext,
    eventTrigger: Element,
    regionName: string,
    regionModel: RegionModel,
    mapOrGeoModel: MapOrGeoModel,
    // Exist only if `viewBuildCtx.data` exists.
    dataIdx: number
): void {
    // setItemGraphicEl, setHoverStyle after all polygons and labels
    // are added to the regionGroup
    if (viewBuildCtx.data) {
        // FIXME: when series-map use a SVG map, and there are duplicated name specified
        // on different SVG elements, after `data.setItemGraphicEl(...)`:
        // (1) all of them will be mounted with `dataIndex`, `seriesIndex`, so that tooltip
        // can be triggered only mouse hover. That's correct.
        // (2) only the last element will be kept in `data`, so that if trigger tooltip
        // by `dispatchAction`, only the last one can be found and triggered. That might be
        // not correct. We will fix it in future if anyone demanding that.
        viewBuildCtx.data.setItemGraphicEl(dataIdx, eventTrigger);
    }
    // series-map will not trigger "geoselectchange" no matter it is
    // based on a declared geo component. Because series-map will
    // trigger "selectchange". If it trigger both the two events,
    // If users call `chart.dispatchAction({type: 'toggleSelect'})`,
    // it not easy to also fire event "geoselectchanged".
    else {
        // Package custom mouse event for geo component
        getECData(eventTrigger).eventData = {
            componentType: 'geo',
            componentIndex: mapOrGeoModel.componentIndex,
            geoIndex: mapOrGeoModel.componentIndex,
            name: regionName,
            region: (regionModel && regionModel.option) || {}
        };
    }
}

function resetTooltipForRegion(
    viewBuildCtx: ViewBuildContext,
    el: Element,
    regionName: string,
    regionModel: RegionModel,
    mapOrGeoModel: MapOrGeoModel
): void {
    if (!viewBuildCtx.data) {
        graphic.setTooltipConfig({
            el: el,
            componentModel: mapOrGeoModel,
            itemName: regionName,
            // @ts-ignore FIXME:TS fix the "compatible with each other"?
            itemTooltipOption: regionModel.get('tooltip')
        });
    }
}

function resetStateTriggerForRegion(
    viewBuildCtx: ViewBuildContext,
    el: Element,
    regionName: string,
    regionModel: RegionModel,
    mapOrGeoModel: MapOrGeoModel
): InnerFocus {
    // @ts-ignore FIXME:TS fix the "compatible with each other"?
    el.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode');
    // @ts-ignore FIXME:TS fix the "compatible with each other"?
    const emphasisModel = regionModel.getModel('emphasis');
    const focus = emphasisModel.get('focus');
    toggleHoverEmphasis(el, focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
    if (viewBuildCtx.isGeo) {
        enableComponentHighDownFeatures(el, mapOrGeoModel as GeoModel, regionName);
    }

    return focus;
}

function projectPolys(
    rings: number[][][], // Polygons include exterior and interiors. Or polylines.
    createStream: (outStream: ProjectionStream) => ProjectionStream,
    isLine?: boolean
) {
    const polygons: number[][][] = [];
    let curPoly: number[][];

    function startPolygon() {
        curPoly = [];
    }
    function endPolygon() {
        if (curPoly.length) {
            polygons.push(curPoly);
            curPoly = [];
        }
    }
    const stream = createStream({
        polygonStart: startPolygon,
        polygonEnd: endPolygon,
        lineStart: startPolygon,
        lineEnd: endPolygon,
        point(x, y) {
            // May have NaN values from stream.
            if (isFinite(x) && isFinite(y)) {
                curPoly.push([x, y]);
            }
        },
        sphere() {}
    });
    !isLine && stream.polygonStart();
    zrUtil.each(rings, ring => {
        stream.lineStart();
        for (let i = 0; i < ring.length; i++) {
            stream.point(ring[i][0], ring[i][1]);
        }
        stream.lineEnd();
    });
    !isLine && stream.polygonEnd();
    return polygons;
}

export default MapDraw;


// @ts-ignore FIXME:TS fix the "compatible with each other"?
