/*
* 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.
*/

// FIXME step not support polar

import * as zrUtil from 'zrender/src/core/util';
import SymbolDraw from '../helper/SymbolDraw';
import SymbolClz from '../helper/Symbol';
import lineAnimationDiff from './lineAnimationDiff';
import * as graphic from '../../util/graphic';
import * as modelUtil from '../../util/model';
import {ECPolyline, ECPolygon} from './poly';
import ChartView from '../../view/Chart';
import {prepareDataCoordInfo, getStackedOnPoint} from './helper';
import {createGridClipPath, createPolarClipPath} from '../helper/createClipPathFromCoordSys';
import LineSeriesModel, { LineSeriesOption } from './LineSeries';
import type GlobalModel from '../../model/Global';
import type ExtensionAPI from '../../core/ExtensionAPI';
// TODO
import Cartesian2D from '../../coord/cartesian/Cartesian2D';
import Polar from '../../coord/polar/Polar';
import type List from '../../data/List';
import type {
    Payload,
    Dictionary,
    ColorString,
    ECElement,
    DisplayState,
    LabelOption,
    ParsedValue
} from '../../util/types';
import type OrdinalScale from '../../scale/Ordinal';
import type Axis2D from '../../coord/cartesian/Axis2D';
import { CoordinateSystemClipArea, isCoordinateSystemType } from '../../coord/CoordinateSystem';
import { setStatesStylesFromModel, setStatesFlag, enableHoverEmphasis } from '../../util/states';
import Model from '../../model/Model';
import {setLabelStyle, getLabelStatesModels, labelInner} from '../../label/labelStyle';
import {getDefaultLabel, getDefaultInterpolatedLabel} from '../helper/labelHelper';

import { getECData } from '../../util/innerStore';
import { createFloat32Array } from '../../util/vendor';

type PolarArea = ReturnType<Polar['getArea']>;
type Cartesian2DArea = ReturnType<Cartesian2D['getArea']>;

interface SymbolExtended extends SymbolClz {
    __temp: boolean
}

function isPointsSame(points1: ArrayLike<number>, points2: ArrayLike<number>) {
    if (points1.length !== points2.length) {
        return;
    }
    for (let i = 0; i < points1.length; i++) {
        if (points1[i] !== points2[i]) {
            return;
        }
    }
    return true;
}

function bboxFromPoints(points: ArrayLike<number>) {
    let minX = Infinity;
    let minY = Infinity;
    let maxX = -Infinity;
    let maxY = -Infinity;

    for (let i = 0; i < points.length;) {
        const x = points[i++];
        const y = points[i++];
        if (!isNaN(x)) {
            minX = Math.min(x, minX);
            maxX = Math.max(x, maxX);
        }
        if (!isNaN(y)) {
            minY = Math.min(y, minY);
            maxY = Math.max(y, maxY);
        }
    }
    return [
        [minX, minY],
        [maxX, maxY]
    ];
}

function getBoundingDiff(points1: ArrayLike<number>, points2: ArrayLike<number>): number {

    const [min1, max1] = bboxFromPoints(points1);
    const [min2, max2] = bboxFromPoints(points2);

    // Get a max value from each corner of two boundings.
    return Math.max(
        Math.abs(min1[0] - min2[0]),
        Math.abs(min1[1] - min2[1]),

        Math.abs(max1[0] - max2[0]),
        Math.abs(max1[1] - max2[1])
    );
}

function getSmooth(smooth: number | boolean) {
    return typeof smooth === 'number' ? smooth : (smooth ? 0.5 : 0);
}

function getStackedOnPoints(
    coordSys: Cartesian2D | Polar,
    data: List,
    dataCoordInfo: ReturnType<typeof prepareDataCoordInfo>
) {
    if (!dataCoordInfo.valueDim) {
        return [];
    }

    const len = data.count();
    const points = createFloat32Array(len * 2);
    for (let idx = 0; idx < len; idx++) {
        const pt = getStackedOnPoint(dataCoordInfo, coordSys, data, idx);
        points[idx * 2] = pt[0];
        points[idx * 2 + 1] = pt[1];
    }

    return points;
}

function turnPointsIntoStep(
    points: ArrayLike<number>,
    coordSys: Cartesian2D | Polar,
    stepTurnAt: 'start' | 'end' | 'middle'
): number[] {
    const baseAxis = coordSys.getBaseAxis();
    const baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;

    const stepPoints: number[] = [];
    let i = 0;
    const stepPt: number[] = [];
    const pt: number[] = [];
    const nextPt: number[] = [];
    for (; i < points.length - 2; i += 2) {
        nextPt[0] = points[i + 2];
        nextPt[1] = points[i + 3];
        pt[0] = points[i];
        pt[1] = points[i + 1];
        stepPoints.push(pt[0], pt[1]);

        switch (stepTurnAt) {
            case 'end':
                stepPt[baseIndex] = nextPt[baseIndex];
                stepPt[1 - baseIndex] = pt[1 - baseIndex];
                stepPoints.push(stepPt[0], stepPt[1]);
                break;
            case 'middle':
                const middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
                const stepPt2 = [];
                stepPt[baseIndex] = stepPt2[baseIndex] = middle;
                stepPt[1 - baseIndex] = pt[1 - baseIndex];
                stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
                stepPoints.push(stepPt[0], stepPt[1]);
                stepPoints.push(stepPt2[0], stepPt2[1]);
                break;
            default:
                // default is start
                stepPt[baseIndex] = pt[baseIndex];
                stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
                stepPoints.push(stepPt[0], stepPt[1]);
        }
    }
    // Last points
    stepPoints.push(points[i++], points[i++]);
    return stepPoints;
}

function getVisualGradient(
    data: List,
    coordSys: Cartesian2D | Polar
) {
    const visualMetaList = data.getVisual('visualMeta');
    if (!visualMetaList || !visualMetaList.length || !data.count()) {
        // When data.count() is 0, gradient range can not be calculated.
        return;
    }

    if (coordSys.type !== 'cartesian2d') {
        if (__DEV__) {
            console.warn('Visual map on line style is only supported on cartesian2d.');
        }
        return;
    }

    let coordDim: 'x' | 'y';
    let visualMeta;

    for (let i = visualMetaList.length - 1; i >= 0; i--) {
        const dimIndex = visualMetaList[i].dimension;
        const dimName = data.dimensions[dimIndex];
        const dimInfo = data.getDimensionInfo(dimName);
        coordDim = (dimInfo && dimInfo.coordDim) as 'x' | 'y';
        // Can only be x or y
        if (coordDim === 'x' || coordDim === 'y') {
            visualMeta = visualMetaList[i];
            break;
        }
    }

    if (!visualMeta) {
        if (__DEV__) {
            console.warn('Visual map on line style only support x or y dimension.');
        }
        return;
    }

    // If the area to be rendered is bigger than area defined by LinearGradient,
    // the canvas spec prescribes that the color of the first stop and the last
    // stop should be used. But if two stops are added at offset 0, in effect
    // browsers use the color of the second stop to render area outside
    // LinearGradient. So we can only infinitesimally extend area defined in
    // LinearGradient to render `outerColors`.

    const axis = coordSys.getAxis(coordDim);

    interface ColorStop {
        offset: number
        coord?: number
        color: ColorString
    }
    // dataToCoor mapping may not be linear, but must be monotonic.
    const colorStops: ColorStop[] = zrUtil.map(visualMeta.stops, function (stop) {
        return {
            offset: 0,
            coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
            color: stop.color
        };
    });
    const stopLen = colorStops.length;
    const outerColors = visualMeta.outerColors.slice();

    if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
        colorStops.reverse();
        outerColors.reverse();
    }

    const tinyExtent = 10; // Arbitrary value: 10px
    const minCoord = colorStops[0].coord - tinyExtent;
    const maxCoord = colorStops[stopLen - 1].coord + tinyExtent;
    const coordSpan = maxCoord - minCoord;

    if (coordSpan < 1e-3) {
        return 'transparent';
    }

    zrUtil.each(colorStops, function (stop) {
        stop.offset = (stop.coord - minCoord) / coordSpan;
    });
    colorStops.push({
        offset: stopLen ? colorStops[stopLen - 1].offset : 0.5,
        color: outerColors[1] || 'transparent'
    });
    colorStops.unshift({ // notice colorStops.length have been changed.
        offset: stopLen ? colorStops[0].offset : 0.5,
        color: outerColors[0] || 'transparent'
    });

    // zrUtil.each(colorStops, function (colorStop) {
    //     // Make sure each offset has rounded px to avoid not sharp edge
    //     colorStop.offset = (Math.round(colorStop.offset * (end - start) + start) - start) / (end - start);
    // });

    const gradient = new graphic.LinearGradient(0, 0, 0, 0, colorStops, true);
    gradient[coordDim] = minCoord;
    gradient[coordDim + '2' as 'x2' | 'y2'] = maxCoord;

    return gradient;
}

function getIsIgnoreFunc(
    seriesModel: LineSeriesModel,
    data: List,
    coordSys: Cartesian2D
) {
    const showAllSymbol = seriesModel.get('showAllSymbol');
    const isAuto = showAllSymbol === 'auto';

    if (showAllSymbol && !isAuto) {
        return;
    }

    const categoryAxis = coordSys.getAxesByScale('ordinal')[0];
    if (!categoryAxis) {
        return;
    }

    // Note that category label interval strategy might bring some weird effect
    // in some scenario: users may wonder why some of the symbols are not
    // displayed. So we show all symbols as possible as we can.
    if (isAuto
        // Simplify the logic, do not determine label overlap here.
        && canShowAllSymbolForCategory(categoryAxis, data)
    ) {
        return;
    }

    // Otherwise follow the label interval strategy on category axis.
    const categoryDataDim = data.mapDimension(categoryAxis.dim);
    const labelMap: Dictionary<1> = {};

    zrUtil.each(categoryAxis.getViewLabels(), function (labelItem) {
        labelMap[labelItem.tickValue] = 1;
    });

    return function (dataIndex: number) {
        return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
    };
}

function canShowAllSymbolForCategory(
    categoryAxis: Axis2D,
    data: List
) {
    // In mose cases, line is monotonous on category axis, and the label size
    // is close with each other. So we check the symbol size and some of the
    // label size alone with the category axis to estimate whether all symbol
    // can be shown without overlap.
    const axisExtent = categoryAxis.getExtent();
    let availSize = Math.abs(axisExtent[1] - axisExtent[0]) / (categoryAxis.scale as OrdinalScale).count();
    isNaN(availSize) && (availSize = 0); // 0/0 is NaN.

    // Sampling some points, max 5.
    const dataLen = data.count();
    const step = Math.max(1, Math.round(dataLen / 5));
    for (let dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
        if (SymbolClz.getSymbolSize(
                data, dataIndex
            // Only for cartesian, where `isHorizontal` exists.
            )[categoryAxis.isHorizontal() ? 1 : 0]
            // Empirical number
            * 1.5 > availSize
        ) {
            return false;
        }
    }

    return true;
}


function isPointNull(x: number, y: number) {
    return isNaN(x) || isNaN(y);
}

function getLastIndexNotNull(points: ArrayLike<number>) {
    let len = points.length / 2;
    for (; len > 0; len--) {
        if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
            break;
        }
    }

    return len - 1;
}

function getPointAtIndex(points: ArrayLike<number>, idx: number) {
    return [points[idx * 2], points[idx * 2 + 1]];
}

function getIndexRange(points: ArrayLike<number>, xOrY: number, dim: 'x' | 'y') {
    const len = points.length / 2;

    const dimIdx = dim === 'x' ? 0 : 1;
    let a;
    let b;
    let prevIndex = 0;
    let nextIndex = -1;
    for (let i = 0; i < len; i++) {
        b = points[i * 2 + dimIdx];
        if (isNaN(b) || isNaN(points[i * 2 + 1 - dimIdx])) {
            continue;
        }
        if (i === 0) {
            a = b;
            continue;
        }
        if (a <= xOrY && b >= xOrY || a >= xOrY && b <= xOrY) {
            nextIndex = i;
            break;
        }

        prevIndex = i;
        a = b;
    }

    return {
        range: [prevIndex, nextIndex],
        t: (xOrY - a) / (b - a)
    };
}


interface EndLabelAnimationRecord {
    lastFrameIndex: number
    originalX?: number
    originalY?: number
}

function createLineClipPath(
    lineView: LineView,
    coordSys: Cartesian2D | Polar,
    hasAnimation: boolean,
    seriesModel: LineSeriesModel
) {
    if (isCoordinateSystemType<Cartesian2D>(coordSys, 'cartesian2d')) {
        const endLabelModel = seriesModel.getModel('endLabel');
        const showEndLabel = endLabelModel.get('show');
        const valueAnimation = endLabelModel.get('valueAnimation');
        const data = seriesModel.getData();

        const labelAnimationRecord: EndLabelAnimationRecord = { lastFrameIndex: 0 };

        const during = showEndLabel
            ? (percent: number, clipRect: graphic.Rect) => {
                lineView._endLabelOnDuring(
                    percent,
                    clipRect,
                    data,
                    labelAnimationRecord,
                    valueAnimation,
                    endLabelModel,
                    coordSys
                );
            }
            : null;

        const isHorizontal = coordSys.getBaseAxis().isHorizontal();
        const clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, () => {
            const endLabel = lineView._endLabel;
            if (endLabel && hasAnimation) {
                if (labelAnimationRecord.originalX != null) {
                    endLabel.attr({
                        x: labelAnimationRecord.originalX,
                        y: labelAnimationRecord.originalY
                    });
                }
            }
        }, during);
        // Expand clip shape to avoid clipping when line value exceeds axis
        if (!seriesModel.get('clip', true)) {
            const rectShape = clipPath.shape;
            const expandSize = Math.max(rectShape.width, rectShape.height);
            if (isHorizontal) {
                rectShape.y -= expandSize;
                rectShape.height += expandSize * 2;
            }
            else {
                rectShape.x -= expandSize;
                rectShape.width += expandSize * 2;
            }
        }

        // Set to the final frame. To make sure label layout is right.
        if (during) {
            during(1, clipPath);
        }
        return clipPath;
    }
    else {
        if (__DEV__) {
            if (seriesModel.get(['endLabel', 'show'])) {
                console.warn('endLabel is not supported for lines in polar systems.');
            }
        }
        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
    }

}

function getEndLabelStateSpecified(endLabelModel: Model, coordSys: Cartesian2D) {
    const baseAxis = coordSys.getBaseAxis();
    const isHorizontal = baseAxis.isHorizontal();
    const isBaseInversed = baseAxis.inverse;
    const align = isHorizontal
        ? isBaseInversed ? 'right' : 'left'
        : 'center';
    const verticalAlign = isHorizontal
        ? 'middle'
        : (isBaseInversed ? 'top' : 'bottom');

    return {
        normal: {
            align: endLabelModel.get('align') || align,
            verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign,
            padding: endLabelModel.get('distance') || 0
        }
    };
}

class LineView extends ChartView {

    static readonly type = 'line';

    _symbolDraw: SymbolDraw;

    _lineGroup: graphic.Group;
    _coordSys: Cartesian2D | Polar;

    _endLabel: graphic.Text;

    _polyline: ECPolyline;
    _polygon: ECPolygon;

    _stackedOnPoints: ArrayLike<number>;
    _points: ArrayLike<number>;

    _step: LineSeriesOption['step'];
    _valueOrigin: LineSeriesOption['areaStyle']['origin'];

    _clipShapeForSymbol: CoordinateSystemClipArea;

    _data: List;

    init() {
        const lineGroup = new graphic.Group();

        const symbolDraw = new SymbolDraw();
        this.group.add(symbolDraw.group);

        this._symbolDraw = symbolDraw;
        this._lineGroup = lineGroup;
    }

    render(seriesModel: LineSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
        const coordSys = seriesModel.coordinateSystem;
        const group = this.group;
        const data = seriesModel.getData();
        const lineStyleModel = seriesModel.getModel('lineStyle');
        const areaStyleModel = seriesModel.getModel('areaStyle');

        let points = data.getLayout('points') as number[] || [];

        const isCoordSysPolar = coordSys.type === 'polar';
        const prevCoordSys = this._coordSys;

        const symbolDraw = this._symbolDraw;
        let polyline = this._polyline;
        let polygon = this._polygon;

        const lineGroup = this._lineGroup;

        const hasAnimation = seriesModel.get('animation');

        const isAreaChart = !areaStyleModel.isEmpty();

        const valueOrigin = areaStyleModel.get('origin');
        const dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);

        let stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);

        const showSymbol = seriesModel.get('showSymbol');

        const isIgnoreFunc = showSymbol && !isCoordSysPolar
            && getIsIgnoreFunc(seriesModel, data, coordSys as Cartesian2D);

        // Remove temporary symbols
        const oldData = this._data;
        oldData && oldData.eachItemGraphicEl(function (el: SymbolExtended, idx) {
            if (el.__temp) {
                group.remove(el);
                oldData.setItemGraphicEl(idx, null);
            }
        });

        // Remove previous created symbols if showSymbol changed to false
        if (!showSymbol) {
            symbolDraw.remove();
        }

        group.add(lineGroup);

        // FIXME step not support polar
        const step = !isCoordSysPolar ? seriesModel.get('step') : false;
        let clipShapeForSymbol: PolarArea | Cartesian2DArea;
        if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
            clipShapeForSymbol = coordSys.getArea();
            // Avoid float number rounding error for symbol on the edge of axis extent.
            // See #7913 and `test/dataZoom-clip.html`.
            if ((clipShapeForSymbol as Cartesian2DArea).width != null) {
                (clipShapeForSymbol as Cartesian2DArea).x -= 0.1;
                (clipShapeForSymbol as Cartesian2DArea).y -= 0.1;
                (clipShapeForSymbol as Cartesian2DArea).width += 0.2;
                (clipShapeForSymbol as Cartesian2DArea).height += 0.2;
            }
            else if ((clipShapeForSymbol as PolarArea).r0) {
                (clipShapeForSymbol as PolarArea).r0 -= 0.5;
                (clipShapeForSymbol as PolarArea).r += 0.5;
            }
        }
        this._clipShapeForSymbol = clipShapeForSymbol;
        // Initialization animation or coordinate system changed
        if (
            !(polyline && prevCoordSys.type === coordSys.type && step === this._step)
        ) {
            showSymbol && symbolDraw.updateData(data, {
                isIgnore: isIgnoreFunc,
                clipShape: clipShapeForSymbol,
                disableAnimation: true,
                getSymbolPoint(idx) {
                    return [points[idx * 2], points[idx * 2 + 1]];
                }
            });

            hasAnimation && this._initSymbolLabelAnimation(
                data,
                coordSys,
                clipShapeForSymbol
            );

            if (step) {
                // TODO If stacked series is not step
                points = turnPointsIntoStep(points, coordSys, step);

                if (stackedOnPoints) {
                    stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
                }
            }

            polyline = this._newPolyline(points);
            if (isAreaChart) {
                polygon = this._newPolygon(
                    points, stackedOnPoints
                );
            }

            // NOTE: Must update _endLabel before setClipPath.
            if (!isCoordSysPolar) {
                this._initOrUpdateEndLabel(seriesModel, coordSys as Cartesian2D);
            }

            lineGroup.setClipPath(
                createLineClipPath(this, coordSys, true, seriesModel)
            );
        }
        else {
            if (isAreaChart && !polygon) {
                // If areaStyle is added
                polygon = this._newPolygon(
                    points, stackedOnPoints
                );
            }
            else if (polygon && !isAreaChart) {
                // If areaStyle is removed
                lineGroup.remove(polygon);
                polygon = this._polygon = null;
            }

            // NOTE: Must update _endLabel before setClipPath.
            if (!isCoordSysPolar) {
                this._initOrUpdateEndLabel(seriesModel, coordSys as Cartesian2D);
            }

            // Update clipPath
            lineGroup.setClipPath(
                createLineClipPath(this, coordSys, false, seriesModel)
            );

            // Always update, or it is wrong in the case turning on legend
            // because points are not changed
            showSymbol && symbolDraw.updateData(data, {
                isIgnore: isIgnoreFunc,
                clipShape: clipShapeForSymbol,
                disableAnimation: true,
                getSymbolPoint(idx) {
                    return [points[idx * 2], points[idx * 2 + 1]];
                }
            });

            // In the case data zoom triggerred refreshing frequently
            // Data may not change if line has a category axis. So it should animate nothing
            if (!isPointsSame(this._stackedOnPoints, stackedOnPoints)
                || !isPointsSame(this._points, points)
            ) {
                if (hasAnimation) {
                    this._doUpdateAnimation(
                        data, stackedOnPoints, coordSys, api, step, valueOrigin
                    );
                }
                else {
                    // Not do it in update with animation
                    if (step) {
                        // TODO If stacked series is not step
                        points = turnPointsIntoStep(points, coordSys, step);
                        if (stackedOnPoints) {
                            stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
                        }
                    }

                    polyline.setShape({
                        points: points
                    });
                    polygon && polygon.setShape({
                        points: points,
                        stackedOnPoints: stackedOnPoints
                    });
                }
            }
        }

        const visualColor = getVisualGradient(data, coordSys)
            || data.getVisual('style')[data.getVisual('drawType')];
        const focus = seriesModel.get(['emphasis', 'focus']);
        const blurScope = seriesModel.get(['emphasis', 'blurScope']);

        polyline.useStyle(zrUtil.defaults(
            // Use color in lineStyle first
            lineStyleModel.getLineStyle(),
            {
                fill: 'none',
                stroke: visualColor,
                lineJoin: 'bevel' as CanvasLineJoin
            }
        ));

        setStatesStylesFromModel(polyline, seriesModel, 'lineStyle');

        if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') {
            const emphasisLineStyle = polyline.getState('emphasis').style;
            emphasisLineStyle.lineWidth = polyline.style.lineWidth + 1;
        }

        // Needs seriesIndex for focus
        getECData(polyline).seriesIndex = seriesModel.seriesIndex;
        enableHoverEmphasis(polyline, focus, blurScope);

        const smooth = getSmooth(seriesModel.get('smooth'));
        const smoothMonotone = seriesModel.get('smoothMonotone');
        const connectNulls = seriesModel.get('connectNulls');
        polyline.setShape({
            smooth,
            smoothMonotone,
            connectNulls
        });

        if (polygon) {
            const stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
            let stackedOnSmooth = 0;

            polygon.useStyle(zrUtil.defaults(
                areaStyleModel.getAreaStyle(),
                {
                    fill: visualColor,
                    opacity: 0.7,
                    lineJoin: 'bevel' as CanvasLineJoin,
                    decal: data.getVisual('style').decal
                }
            ));

            if (stackedOnSeries) {
                stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
            }

            polygon.setShape({
                smooth,
                stackedOnSmooth,
                smoothMonotone,
                connectNulls
            });

            setStatesStylesFromModel(polygon, seriesModel, 'areaStyle');
            // Needs seriesIndex for focus
            getECData(polygon).seriesIndex = seriesModel.seriesIndex;
            enableHoverEmphasis(polygon, focus, blurScope);
        }

        const changePolyState = (toState: DisplayState) => {
            this._changePolyState(toState);
        };

        data.eachItemGraphicEl(function (el) {
            // Switch polyline / polygon state if element changed its state.
            el && ((el as ECElement).onHoverStateChange = changePolyState);
        });

        (this._polyline as ECElement).onHoverStateChange = changePolyState;

        this._data = data;
        // Save the coordinate system for transition animation when data changed
        this._coordSys = coordSys;
        this._stackedOnPoints = stackedOnPoints;
        this._points = points;
        this._step = step;
        this._valueOrigin = valueOrigin;
    }

    dispose() {}

    highlight(
        seriesModel: LineSeriesModel,
        ecModel: GlobalModel,
        api: ExtensionAPI,
        payload: Payload
    ) {
        const data = seriesModel.getData();
        const dataIndex = modelUtil.queryDataIndex(data, payload);

        this._changePolyState('emphasis');

        if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
            const points = data.getLayout('points');
            let symbol = data.getItemGraphicEl(dataIndex) as SymbolClz;
            if (!symbol) {
                // Create a temporary symbol if it is not exists
                const x = points[dataIndex * 2];
                const y = points[dataIndex * 2 + 1];
                if (isNaN(x) || isNaN(y)) {
                    // Null data
                    return;
                }
                // fix #11360: should't draw symbol outside clipShapeForSymbol
                if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
                    return;
                }
                symbol = new SymbolClz(data, dataIndex);
                symbol.x = x;
                symbol.y = y;
                symbol.setZ(
                    seriesModel.get('zlevel'),
                    seriesModel.get('z')
                );
                (symbol as SymbolExtended).__temp = true;
                data.setItemGraphicEl(dataIndex, symbol);

                // Stop scale animation
                symbol.stopSymbolAnimation(true);

                this.group.add(symbol);
            }
            symbol.highlight();
        }
        else {
            // Highlight whole series
            ChartView.prototype.highlight.call(
                this, seriesModel, ecModel, api, payload
            );
        }
    }

    downplay(
        seriesModel: LineSeriesModel,
        ecModel: GlobalModel,
        api: ExtensionAPI,
        payload: Payload
    ) {
        const data = seriesModel.getData();
        const dataIndex = modelUtil.queryDataIndex(data, payload) as number;

        this._changePolyState('normal');

        if (dataIndex != null && dataIndex >= 0) {
            const symbol = data.getItemGraphicEl(dataIndex) as SymbolExtended;
            if (symbol) {
                if (symbol.__temp) {
                    data.setItemGraphicEl(dataIndex, null);
                    this.group.remove(symbol);
                }
                else {
                    symbol.downplay();
                }
            }
        }
        else {
            // FIXME
            // can not downplay completely.
            // Downplay whole series
            ChartView.prototype.downplay.call(
                this, seriesModel, ecModel, api, payload
            );
        }
    }

    _changePolyState(toState: DisplayState) {
        const polygon = this._polygon;
        setStatesFlag(this._polyline, toState);
        polygon && setStatesFlag(polygon, toState);
    }

    _newPolyline(points: ArrayLike<number>) {
        let polyline = this._polyline;
        // Remove previous created polyline
        if (polyline) {
            this._lineGroup.remove(polyline);
        }

        polyline = new ECPolyline({
            shape: {
                points
            },
            segmentIgnoreThreshold: 2,
            z2: 10
        });

        this._lineGroup.add(polyline);

        this._polyline = polyline;

        return polyline;
    }

    _newPolygon(points: ArrayLike<number>, stackedOnPoints: ArrayLike<number>) {
        let polygon = this._polygon;
        // Remove previous created polygon
        if (polygon) {
            this._lineGroup.remove(polygon);
        }

        polygon = new ECPolygon({
            shape: {
                points,
                stackedOnPoints: stackedOnPoints
            },
            segmentIgnoreThreshold: 2
        });

        this._lineGroup.add(polygon);

        this._polygon = polygon;
        return polygon;
    }

    _initSymbolLabelAnimation(
        data: List,
        coordSys: Polar | Cartesian2D,
        clipShape: PolarArea | Cartesian2DArea
    ) {
        let isHorizontalOrRadial: boolean;
        let isCoordSysPolar: boolean;
        const baseAxis = coordSys.getBaseAxis();
        const isAxisInverse = baseAxis.inverse;
        if (coordSys.type === 'cartesian2d') {
            isHorizontalOrRadial = (baseAxis as Axis2D).isHorizontal();
            isCoordSysPolar = false;
        }
        else if (coordSys.type === 'polar') {
            isHorizontalOrRadial = baseAxis.dim === 'angle';
            isCoordSysPolar = true;
        }

        const seriesModel = data.hostModel;
        let seriesDuration = seriesModel.get('animationDuration');
        if (typeof seriesDuration === 'function') {
            seriesDuration = seriesDuration(null);
        }
        const seriesDalay = seriesModel.get('animationDelay') || 0;
        const seriesDalayValue = typeof seriesDalay === 'function'
            ? seriesDalay(null)
            : seriesDalay;

        data.eachItemGraphicEl(function (symbol: SymbolExtended, idx) {
            const el = symbol;
            if (el) {
                const point = [symbol.x, symbol.y];
                let start;
                let end;
                let current;
                if (isCoordSysPolar) {
                    const polarClip = clipShape as PolarArea;
                    const coord = (coordSys as Polar).pointToCoord(point);
                    if (isHorizontalOrRadial) {
                        start = polarClip.startAngle;
                        end = polarClip.endAngle;
                        current = -coord[1] / 180 * Math.PI;
                    }
                    else {
                        start = polarClip.r0;
                        end = polarClip.r;
                        current = coord[0];
                    }
                }
                else {
                    const gridClip = clipShape as Cartesian2DArea;
                    if (isHorizontalOrRadial) {
                        start = gridClip.x;
                        end = gridClip.x + gridClip.width;
                        current = symbol.x;
                    }
                    else {
                        start = gridClip.y + gridClip.height;
                        end = gridClip.y;
                        current = symbol.y;
                    }
                }
                let ratio = end === start ? 0 : (current - start) / (end - start);
                if (isAxisInverse) {
                    ratio = 1 - ratio;
                }

                const delay = typeof seriesDalay === 'function' ? seriesDalay(idx)
                    : (seriesDuration * ratio) + seriesDalayValue;

                const symbolPath = el.getSymbolPath();
                const text = symbolPath.getTextContent();

                el.attr({ scaleX: 0, scaleY: 0});
                el.animateTo({
                    scaleX: 1,
                    scaleY: 1
                }, {
                    duration: 200,
                    delay: delay
                });

                if (text) {
                    text.animateFrom({
                        style: {
                            opacity: 0
                        }
                    }, {
                        duration: 300,
                        delay: delay
                    });
                }

                (symbolPath as ECElement).disableLabelAnimation = true;
            }
        });
    }

    _initOrUpdateEndLabel(
        seriesModel: LineSeriesModel,
        coordSys: Cartesian2D
    ) {
        const endLabelModel = seriesModel.getModel('endLabel');

        if (endLabelModel.get('show')) {
            const data = seriesModel.getData();
            const polyline = this._polyline;
            let endLabel = this._endLabel;
            if (!endLabel) {
                endLabel = this._endLabel = new graphic.Text({
                    z2: 200 // should be higher than item symbol
                });
                endLabel.ignoreClip = true;
                polyline.setTextContent(this._endLabel);
                (polyline as ECElement).disableLabelAnimation = true;
            }

            // Find last non-NaN data to display data
            const dataIndex = getLastIndexNotNull(data.getLayout('points'));
            if (dataIndex >= 0) {
                setLabelStyle(
                    endLabel,
                    getLabelStatesModels(seriesModel, 'endLabel'),
                    {
                        labelFetcher: seriesModel,
                        labelDataIndex: dataIndex,
                        defaultText(dataIndex, opt, overrideValue) {
                            return overrideValue ? getDefaultInterpolatedLabel(data, overrideValue)
                                : getDefaultLabel(data, dataIndex);
                        },
                        enableTextSetter: true
                    },
                    getEndLabelStateSpecified(endLabelModel, coordSys)
                );
            }
        }
        else if (this._endLabel) {
            this._polyline.removeTextContent();
            this._endLabel = null;
        }
    }

    _endLabelOnDuring(
        percent: number,
        clipRect: graphic.Rect,
        data: List,
        animationRecord: EndLabelAnimationRecord,
        valueAnimation: boolean,
        endLabelModel: Model<LabelOption>,
        coordSys: Cartesian2D
    ) {
        const endLabel = this._endLabel;
        const polyline = this._polyline;

        if (endLabel) {
            // NOTE: Don't remove percent < 1. percent === 1 means the first frame during render.
            // The label is not prepared at this time.
            if (percent < 1 && animationRecord.originalX == null) {
                animationRecord.originalX = endLabel.x;
                animationRecord.originalY = endLabel.y;
            }

            const points = data.getLayout('points');
            const seriesModel = data.hostModel as LineSeriesModel;
            const connectNulls = seriesModel.get('connectNulls');
            const precision = endLabelModel.get('precision');

            const baseAxis = coordSys.getBaseAxis();
            const isHorizontal = baseAxis.isHorizontal();
            const isBaseInversed = baseAxis.inverse;
            const clipShape = clipRect.shape;

            const xOrY = isBaseInversed
                ? isHorizontal ? clipShape.x : (clipShape.y + clipShape.height)
                : isHorizontal ? (clipShape.x + clipShape.width) : clipShape.y;
            const dim = isHorizontal ? 'x' : 'y';

            const dataIndexRange = getIndexRange(points, xOrY, dim);
            const indices = dataIndexRange.range;

            const diff = indices[1] - indices[0];
            let value: ParsedValue;
            if (diff >= 1) {
                // diff > 1 && connectNulls, which is on the null data.
                if (diff > 1 && !connectNulls) {
                    const pt = getPointAtIndex(points, indices[0]);
                    endLabel.attr({ x: pt[0], y: pt[1] });
                    valueAnimation && (value = seriesModel.getRawValue(indices[0]) as ParsedValue);
                }
                else {
                    const pt = polyline.getPointOn(xOrY, dim);
                    pt && endLabel.attr({ x: pt[0], y: pt[1] });

                    const startValue = seriesModel.getRawValue(indices[0]) as ParsedValue;
                    const endValue = seriesModel.getRawValue(indices[1]) as ParsedValue;
                    valueAnimation && (value = modelUtil.interpolateRawValues(
                        data, precision, startValue, endValue, dataIndexRange.t
                    ) as ParsedValue);
                }
                animationRecord.lastFrameIndex = indices[0];
            }
            else {
                // If diff <= 0, which is the range is not found(Include NaN)
                // Choose the first point or last point.
                const idx = (percent === 1 || animationRecord.lastFrameIndex > 0) ? indices[0] : 0;
                const pt = getPointAtIndex(points, idx);
                valueAnimation && (value = seriesModel.getRawValue(idx) as ParsedValue);
                endLabel.attr({ x: pt[0], y: pt[1] });
            }
            if (valueAnimation) {
                labelInner(endLabel).setLabelText(value);
            }
        }
    }

    /**
     * @private
     */
    // FIXME Two value axis
    _doUpdateAnimation(
        data: List,
        stackedOnPoints: ArrayLike<number>,
        coordSys: Cartesian2D | Polar,
        api: ExtensionAPI,
        step: LineSeriesOption['step'],
        valueOrigin: LineSeriesOption['areaStyle']['origin']
    ) {
        const polyline = this._polyline;
        const polygon = this._polygon;
        const seriesModel = data.hostModel;

        const diff = lineAnimationDiff(
            this._data, data,
            this._stackedOnPoints, stackedOnPoints,
            this._coordSys, coordSys,
            this._valueOrigin, valueOrigin
        );

        let current = diff.current;
        let stackedOnCurrent = diff.stackedOnCurrent;
        let next = diff.next;
        let stackedOnNext = diff.stackedOnNext;
        if (step) {
            // TODO If stacked series is not step
            current = turnPointsIntoStep(diff.current, coordSys, step);
            stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step);
            next = turnPointsIntoStep(diff.next, coordSys, step);
            stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step);
        }

        // Don't apply animation if diff is large.
        // For better result and avoid memory explosion problems like
        // https://github.com/apache/incubator-echarts/issues/12229
        if (getBoundingDiff(current, next) > 3000
            || (polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000)
        ) {
            polyline.setShape({
                points: next
            });
            if (polygon) {
                polygon.setShape({
                    points: next,
                    stackedOnPoints: stackedOnNext
                });
            }
            return;
        }

        (polyline.shape as any).__points = diff.current;
        polyline.shape.points = current;

        const target = {
            shape: {
                points: next
            }
        };
        // Also animate the original points.
        // If points reference is changed when turning into step line.
        if (diff.current !== current) {
            (target.shape as any).__points = diff.next;
        }

        // Stop previous animation.
        polyline.stopAnimation();
        graphic.updateProps(polyline, target, seriesModel);

        if (polygon) {
            polygon.setShape({
                // Reuse the points with polyline.
                points: current,
                stackedOnPoints: stackedOnCurrent
            });
            polygon.stopAnimation();
            graphic.updateProps(polygon, {
                shape: {
                    stackedOnPoints: stackedOnNext
                }
            }, seriesModel);
            // If use attr directly in updateProps.
            if (polyline.shape.points !== polygon.shape.points) {
                polygon.shape.points = polyline.shape.points;
            }
        }


        const updatedDataInfo: {
            el: SymbolExtended,
            ptIdx: number
        }[] = [];
        const diffStatus = diff.status;

        for (let i = 0; i < diffStatus.length; i++) {
            const cmd = diffStatus[i].cmd;
            if (cmd === '=') {
                const el = data.getItemGraphicEl(diffStatus[i].idx1) as SymbolExtended;
                if (el) {
                    updatedDataInfo.push({
                        el: el,
                        ptIdx: i    // Index of points
                    });
                }
            }
        }

        if (polyline.animators && polyline.animators.length) {
            polyline.animators[0].during(function () {
                polygon && polygon.dirtyShape();
                const points = (polyline.shape as any).__points;
                for (let i = 0; i < updatedDataInfo.length; i++) {
                    const el = updatedDataInfo[i].el;
                    const offset = updatedDataInfo[i].ptIdx * 2;
                    el.x = points[offset];
                    el.y = points[offset + 1];
                    el.markRedraw();
                }
            });
        }
    }

    remove(ecModel: GlobalModel) {
        const group = this.group;
        const oldData = this._data;
        this._lineGroup.removeAll();
        this._symbolDraw.remove(true);
        // Remove temporary created elements when highlighting
        oldData && oldData.eachItemGraphicEl(function (el: SymbolExtended, idx) {
            if (el.__temp) {
                group.remove(el);
                oldData.setItemGraphicEl(idx, null);
            }
        });

        this._polyline =
            this._polygon =
            this._coordSys =
            this._points =
            this._stackedOnPoints =
            this._endLabel =
            this._data = null;
    }
}

export default LineView;
