/*
* 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 BoundingRect, { RectLike } from 'zrender/src/core/BoundingRect';
import * as matrix from 'zrender/src/core/matrix';
import * as graphic from '../../util/graphic';
import { createTextStyle } from '../../label/labelStyle';
import * as layout from '../../util/layout';
import TimelineView from './TimelineView';
import TimelineAxis from './TimelineAxis';
import {createSymbol, normalizeSymbolOffset, normalizeSymbolSize} from '../../util/symbol';
import * as numberUtil from '../../util/number';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import { merge, each, extend, isString, bind, defaults, retrieve2 } from 'zrender/src/core/util';
import SliderTimelineModel from './SliderTimelineModel';
import { LayoutOrient, ZRTextAlign, ZRTextVerticalAlign, ZRElementEvent, ScaleTick } from '../../util/types';
import TimelineModel, { TimelineDataItemOption, TimelineCheckpointStyle } from './TimelineModel';
import { TimelineChangePayload, TimelinePlayChangePayload } from './timelineAction';
import Model from '../../model/Model';
import { PathProps, PathStyleProps } from 'zrender/src/graphic/Path';
import Scale from '../../scale/Scale';
import OrdinalScale from '../../scale/Ordinal';
import TimeScale from '../../scale/Time';
import IntervalScale from '../../scale/Interval';
import { VectorArray } from 'zrender/src/core/vector';
import { parsePercent } from 'zrender/src/contain/text';
import { makeInner } from '../../util/model';
import { getECData } from '../../util/innerStore';
import { enableHoverEmphasis } from '../../util/states';
import { createTooltipMarkup } from '../tooltip/tooltipMarkup';
import Displayable from 'zrender/src/graphic/Displayable';

const PI = Math.PI;

type TimelineSymbol = ReturnType<typeof createSymbol>;

type RenderMethodName = '_renderAxisLine' | '_renderAxisTick' | '_renderControl' | '_renderCurrentPointer';

type ControlName = 'play' | 'stop' | 'next' | 'prev';
type ControlIconName = 'playIcon' | 'stopIcon' | 'nextIcon' | 'prevIcon';

const labelDataIndexStore = makeInner<{
    dataIndex: number
}, graphic.Text>();

interface LayoutInfo {
    viewRect: BoundingRect
    mainLength: number
    orient: LayoutOrient

    rotation: number
    labelRotation: number
    labelPosOpt: number | '+' | '-'
    labelAlign: ZRTextAlign
    labelBaseline: ZRTextVerticalAlign

    playPosition: number[]
    prevBtnPosition: number[]
    nextBtnPosition: number[]
    axisExtent: number[]

    controlSize: number
    controlGap: number
}

class SliderTimelineView extends TimelineView {

    static type = 'timeline.slider';
    type = SliderTimelineView.type;

    api: ExtensionAPI;
    model: SliderTimelineModel;
    ecModel: GlobalModel;

    private _axis: TimelineAxis;

    private _viewRect: BoundingRect;

    private _timer: number;

    private _currentPointer: TimelineSymbol;

    private _progressLine: graphic.Line;

    private _mainGroup: graphic.Group;

    private _labelGroup: graphic.Group;

    private _tickSymbols: graphic.Path[];
    private _tickLabels: graphic.Text[];

    init(ecModel: GlobalModel, api: ExtensionAPI) {
        this.api = api;
    }

    /**
     * @override
     */
    render(timelineModel: SliderTimelineModel, ecModel: GlobalModel, api: ExtensionAPI) {
        this.model = timelineModel;
        this.api = api;
        this.ecModel = ecModel;

        this.group.removeAll();

        if (timelineModel.get('show', true)) {

            const layoutInfo = this._layout(timelineModel, api);
            const mainGroup = this._createGroup('_mainGroup');
            const labelGroup = this._createGroup('_labelGroup');

            const axis = this._axis = this._createAxis(layoutInfo, timelineModel);

            timelineModel.formatTooltip = function (dataIndex: number) {
                const name = axis.scale.getLabel({value: dataIndex});
                return createTooltipMarkup('nameValue', { noName: true, value: name });
            };

            each(
                ['AxisLine', 'AxisTick', 'Control', 'CurrentPointer'] as const,
                function (name) {
                    this['_render' + name as RenderMethodName](layoutInfo, mainGroup, axis, timelineModel);
                },
                this
            );

            this._renderAxisLabel(layoutInfo, labelGroup, axis, timelineModel);
            this._position(layoutInfo, timelineModel);
        }

        this._doPlayStop();

        this._updateTicksStatus();
    }

    /**
     * @override
     */
    remove() {
        this._clearTimer();
        this.group.removeAll();
    }

    /**
     * @override
     */
    dispose() {
        this._clearTimer();
    }

    private _layout(timelineModel: SliderTimelineModel, api: ExtensionAPI): LayoutInfo {
        const labelPosOpt = timelineModel.get(['label', 'position']);
        const orient = timelineModel.get('orient');
        const viewRect = getViewRect(timelineModel, api);
        let parsedLabelPos: number | '+' | '-';
        // Auto label offset.
        if (labelPosOpt == null || labelPosOpt === 'auto') {
            parsedLabelPos = orient === 'horizontal'
                ? ((viewRect.y + viewRect.height / 2) < api.getHeight() / 2 ? '-' : '+')
                : ((viewRect.x + viewRect.width / 2) < api.getWidth() / 2 ? '+' : '-');
        }
        else if (isString(labelPosOpt)) {
            parsedLabelPos = ({
                horizontal: {top: '-', bottom: '+'},
                vertical: {left: '-', right: '+'}
            } as const)[orient][labelPosOpt];
        }
        else {
            // is number
            parsedLabelPos = labelPosOpt;
        }

        const labelAlignMap = {
            horizontal: 'center',
            vertical: (parsedLabelPos >= 0 || parsedLabelPos === '+') ? 'left' : 'right'
        };

        const labelBaselineMap = {
            horizontal: (parsedLabelPos >= 0 || parsedLabelPos === '+') ? 'top' : 'bottom',
            vertical: 'middle'
        };
        const rotationMap = {
            horizontal: 0,
            vertical: PI / 2
        };

        // Position
        const mainLength = orient === 'vertical' ? viewRect.height : viewRect.width;

        const controlModel = timelineModel.getModel('controlStyle');
        const showControl = controlModel.get('show', true);
        const controlSize = showControl ? controlModel.get('itemSize') : 0;
        const controlGap = showControl ? controlModel.get('itemGap') : 0;
        const sizePlusGap = controlSize + controlGap;

        // Special label rotate.
        let labelRotation = timelineModel.get(['label', 'rotate']) || 0;
        labelRotation = labelRotation * PI / 180; // To radian.

        let playPosition: number[];
        let prevBtnPosition: number[];
        let nextBtnPosition: number[];
        const controlPosition = controlModel.get('position', true);
        const showPlayBtn = showControl && controlModel.get('showPlayBtn', true);
        const showPrevBtn = showControl && controlModel.get('showPrevBtn', true);
        const showNextBtn = showControl && controlModel.get('showNextBtn', true);
        let xLeft = 0;
        let xRight = mainLength;

        // position[0] means left, position[1] means middle.
        if (controlPosition === 'left' || controlPosition === 'bottom') {
            showPlayBtn && (playPosition = [0, 0], xLeft += sizePlusGap);
            showPrevBtn && (prevBtnPosition = [xLeft, 0], xLeft += sizePlusGap);
            showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
        }
        else { // 'top' 'right'
            showPlayBtn && (playPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
            showPrevBtn && (prevBtnPosition = [0, 0], xLeft += sizePlusGap);
            showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
        }
        const axisExtent = [xLeft, xRight];

        if (timelineModel.get('inverse')) {
            axisExtent.reverse();
        }

        return {
            viewRect: viewRect,
            mainLength: mainLength,
            orient: orient,

            rotation: rotationMap[orient],
            labelRotation: labelRotation,
            labelPosOpt: parsedLabelPos,
            labelAlign: timelineModel.get(['label', 'align']) || labelAlignMap[orient] as ZRTextAlign,
            labelBaseline: timelineModel.get(['label', 'verticalAlign'])
                || timelineModel.get(['label', 'baseline'])
                || labelBaselineMap[orient] as ZRTextVerticalAlign,

            // Based on mainGroup.
            playPosition: playPosition,
            prevBtnPosition: prevBtnPosition,
            nextBtnPosition: nextBtnPosition,
            axisExtent: axisExtent,

            controlSize: controlSize,
            controlGap: controlGap
        };
    }

    private _position(layoutInfo: LayoutInfo, timelineModel: SliderTimelineModel) {
        // Position is be called finally, because bounding rect is needed for
        // adapt content to fill viewRect (auto adapt offset).

        // Timeline may be not all in the viewRect when 'offset' is specified
        // as a number, because it is more appropriate that label aligns at
        // 'offset' but not the other edge defined by viewRect.

        const mainGroup = this._mainGroup;
        const labelGroup = this._labelGroup;

        let viewRect = layoutInfo.viewRect;
        if (layoutInfo.orient === 'vertical') {
            // transform to horizontal, inverse rotate by left-top point.
            const m = matrix.create();
            const rotateOriginX = viewRect.x;
            const rotateOriginY = viewRect.y + viewRect.height;
            matrix.translate(m, m, [-rotateOriginX, -rotateOriginY]);
            matrix.rotate(m, m, -PI / 2);
            matrix.translate(m, m, [rotateOriginX, rotateOriginY]);
            viewRect = viewRect.clone();
            viewRect.applyTransform(m);
        }

        const viewBound = getBound(viewRect);
        const mainBound = getBound(mainGroup.getBoundingRect());
        const labelBound = getBound(labelGroup.getBoundingRect());

        const mainPosition = [mainGroup.x, mainGroup.y];
        const labelsPosition = [labelGroup.x, labelGroup.y];

        labelsPosition[0] = mainPosition[0] = viewBound[0][0];

        const labelPosOpt = layoutInfo.labelPosOpt;

        if (labelPosOpt == null || isString(labelPosOpt)) { // '+' or '-'
            const mainBoundIdx = labelPosOpt === '+' ? 0 : 1;
            toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx);
            toBound(labelsPosition, labelBound, viewBound, 1, 1 - mainBoundIdx);
        }
        else {
            const mainBoundIdx = labelPosOpt >= 0 ? 0 : 1;
            toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx);
            labelsPosition[1] = mainPosition[1] + labelPosOpt;
        }

        mainGroup.setPosition(mainPosition);
        labelGroup.setPosition(labelsPosition);
        mainGroup.rotation = labelGroup.rotation = layoutInfo.rotation;

        setOrigin(mainGroup);
        setOrigin(labelGroup);

        function setOrigin(targetGroup: graphic.Group) {
            targetGroup.originX = viewBound[0][0] - targetGroup.x;
            targetGroup.originY = viewBound[1][0] - targetGroup.y;
        }

        function getBound(rect: RectLike) {
            // [[xmin, xmax], [ymin, ymax]]
            return [
                [rect.x, rect.x + rect.width],
                [rect.y, rect.y + rect.height]
            ];
        }

        function toBound(fromPos: VectorArray, from: number[][], to: number[][], dimIdx: number, boundIdx: number) {
            fromPos[dimIdx] += to[dimIdx][boundIdx] - from[dimIdx][boundIdx];
        }
    }

    private _createAxis(layoutInfo: LayoutInfo, timelineModel: SliderTimelineModel) {
        const data = timelineModel.getData();
        const axisType = timelineModel.get('axisType');

        const scale = createScaleByModel(timelineModel, axisType);

        // Customize scale. The `tickValue` is `dataIndex`.
        scale.getTicks = function () {
            return data.mapArray(['value'], function (value: number) {
                return {value};
            });
        };

        const dataExtent = data.getDataExtent('value');
        scale.setExtent(dataExtent[0], dataExtent[1]);
        scale.niceTicks();

        const axis = new TimelineAxis('value', scale, layoutInfo.axisExtent as [number, number], axisType);
        axis.model = timelineModel;

        return axis;
    }

    private _createGroup(key: '_mainGroup' | '_labelGroup') {
        const newGroup = this[key] = new graphic.Group();
        this.group.add(newGroup);
        return newGroup;
    }

    private _renderAxisLine(
        layoutInfo: LayoutInfo,
        group: graphic.Group,
        axis: TimelineAxis,
        timelineModel: SliderTimelineModel
    ) {
        const axisExtent = axis.getExtent();

        if (!timelineModel.get(['lineStyle', 'show'])) {
            return;
        }

        const line = new graphic.Line({
            shape: {
                x1: axisExtent[0], y1: 0,
                x2: axisExtent[1], y2: 0
            },
            style: extend(
                {lineCap: 'round'},
                timelineModel.getModel('lineStyle').getLineStyle()
            ),
            silent: true,
            z2: 1
        });
        group.add(line);

        const progressLine = this._progressLine = new graphic.Line({
            shape: {
                x1: axisExtent[0],
                x2: this._currentPointer
                    ? this._currentPointer.x : axisExtent[0],
                y1: 0, y2: 0
            },
            style: defaults(
                { lineCap: 'round', lineWidth: line.style.lineWidth } as PathStyleProps,
                timelineModel.getModel(['progress', 'lineStyle']).getLineStyle()
            ),
            silent: true,
            z2: 1
        });
        group.add(progressLine);
    }

    private _renderAxisTick(
        layoutInfo: LayoutInfo,
        group: graphic.Group,
        axis: TimelineAxis,
        timelineModel: SliderTimelineModel
    ) {
        const data = timelineModel.getData();
        // Show all ticks, despite ignoring strategy.
        const ticks = axis.scale.getTicks();

        this._tickSymbols = [];

        // The value is dataIndex, see the costomized scale.
        each(ticks, (tick: ScaleTick) => {
            const tickCoord = axis.dataToCoord(tick.value);
            const itemModel = data.getItemModel<TimelineDataItemOption>(tick.value);
            const itemStyleModel = itemModel.getModel('itemStyle');
            const hoverStyleModel = itemModel.getModel(['emphasis', 'itemStyle']);
            const progressStyleModel = itemModel.getModel(['progress', 'itemStyle']);

            const symbolOpt = {
                x: tickCoord,
                y: 0,
                onclick: bind(this._changeTimeline, this, tick.value)
            };
            const el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt);
            el.ensureState('emphasis').style = hoverStyleModel.getItemStyle();
            el.ensureState('progress').style = progressStyleModel.getItemStyle();

            enableHoverEmphasis(el);

            const ecData = getECData(el);
            if (itemModel.get('tooltip')) {
                ecData.dataIndex = tick.value;
                ecData.dataModel = timelineModel;
            }
            else {
                ecData.dataIndex = ecData.dataModel = null;
            }

            this._tickSymbols.push(el);
        });
    }

    private _renderAxisLabel(
        layoutInfo: LayoutInfo,
        group: graphic.Group,
        axis: TimelineAxis,
        timelineModel: SliderTimelineModel
    ) {
        const labelModel = axis.getLabelModel();

        if (!labelModel.get('show')) {
            return;
        }

        const data = timelineModel.getData();
        const labels = axis.getViewLabels();

        this._tickLabels = [];

        each(labels, (labelItem) => {
            // The tickValue is dataIndex, see the costomized scale.
            const dataIndex = labelItem.tickValue;

            const itemModel = data.getItemModel<TimelineDataItemOption>(dataIndex);
            const normalLabelModel = itemModel.getModel('label');
            const hoverLabelModel = itemModel.getModel(['emphasis', 'label']);
            const progressLabelModel = itemModel.getModel(['progress', 'label']);

            const tickCoord = axis.dataToCoord(labelItem.tickValue);
            const textEl = new graphic.Text({
                x: tickCoord,
                y: 0,
                rotation: layoutInfo.labelRotation - layoutInfo.rotation,
                onclick: bind(this._changeTimeline, this, dataIndex),
                silent: false,
                style: createTextStyle(normalLabelModel, {
                    text: labelItem.formattedLabel,
                    align: layoutInfo.labelAlign,
                    verticalAlign: layoutInfo.labelBaseline
                })
            });

            textEl.ensureState('emphasis').style = createTextStyle(hoverLabelModel);
            textEl.ensureState('progress').style = createTextStyle(progressLabelModel);

            group.add(textEl);
            enableHoverEmphasis(textEl);

            labelDataIndexStore(textEl).dataIndex = dataIndex;

            this._tickLabels.push(textEl);

        });
    }

    private _renderControl(
        layoutInfo: LayoutInfo,
        group: graphic.Group,
        axis: TimelineAxis,
        timelineModel: SliderTimelineModel
    ) {
        const controlSize = layoutInfo.controlSize;
        const rotation = layoutInfo.rotation;

        const itemStyle = timelineModel.getModel('controlStyle').getItemStyle();
        const hoverStyle = timelineModel.getModel(['emphasis', 'controlStyle']).getItemStyle();
        const playState = timelineModel.getPlayState();
        const inverse = timelineModel.get('inverse', true);

        makeBtn(
            layoutInfo.nextBtnPosition,
            'next',
            bind(this._changeTimeline, this, inverse ? '-' : '+')
        );
        makeBtn(
            layoutInfo.prevBtnPosition,
            'prev',
            bind(this._changeTimeline, this, inverse ? '+' : '-')
        );
        makeBtn(
            layoutInfo.playPosition,
            (playState ? 'stop' : 'play'),
            bind(this._handlePlayClick, this, !playState),
            true
        );

        function makeBtn(
            position: number[],
            iconName: ControlName,
            onclick: () => void,
            willRotate?: boolean
        ) {
            if (!position) {
                return;
            }
            const iconSize = parsePercent(
                retrieve2(timelineModel.get(['controlStyle', iconName + 'BtnSize' as any]), controlSize),
                controlSize
            );
            const rect = [0, -iconSize / 2, iconSize, iconSize];
            const btn = makeControlIcon(timelineModel, iconName + 'Icon' as ControlIconName, rect, {
                x: position[0],
                y: position[1],
                originX: controlSize / 2,
                originY: 0,
                rotation: willRotate ? -rotation : 0,
                rectHover: true,
                style: itemStyle,
                onclick: onclick
            });
            btn.ensureState('emphasis').style = hoverStyle;
            group.add(btn);
            enableHoverEmphasis(btn);
        }
    }

    private _renderCurrentPointer(
        layoutInfo: LayoutInfo,
        group: graphic.Group,
        axis: TimelineAxis,
        timelineModel: SliderTimelineModel
    ) {
        const data = timelineModel.getData();
        const currentIndex = timelineModel.getCurrentIndex();
        const pointerModel = data.getItemModel<TimelineDataItemOption>(currentIndex)
            .getModel('checkpointStyle');
        const me = this;

        const callback = {
            onCreate(pointer: TimelineSymbol) {
                pointer.draggable = true;
                pointer.drift = bind(me._handlePointerDrag, me);
                pointer.ondragend = bind(me._handlePointerDragend, me);
                pointerMoveTo(pointer, me._progressLine, currentIndex, axis, timelineModel, true);
            },
            onUpdate(pointer: TimelineSymbol) {
                pointerMoveTo(pointer, me._progressLine, currentIndex, axis, timelineModel);
            }
        };

        // Reuse when exists, for animation and drag.
        this._currentPointer = giveSymbol(
            pointerModel, pointerModel, this._mainGroup, {}, this._currentPointer, callback
        );
    }

    private _handlePlayClick(nextState: boolean) {
        this._clearTimer();
        this.api.dispatchAction({
            type: 'timelinePlayChange',
            playState: nextState,
            from: this.uid
        } as TimelinePlayChangePayload);
    }

    private _handlePointerDrag(dx: number, dy: number, e: ZRElementEvent) {
        this._clearTimer();
        this._pointerChangeTimeline([e.offsetX, e.offsetY]);
    }

    private _handlePointerDragend(e: ZRElementEvent) {
        this._pointerChangeTimeline([e.offsetX, e.offsetY], true);
    }

    private _pointerChangeTimeline(mousePos: number[], trigger?: boolean) {
        let toCoord = this._toAxisCoord(mousePos)[0];

        const axis = this._axis;
        const axisExtent = numberUtil.asc(axis.getExtent().slice());

        toCoord > axisExtent[1] && (toCoord = axisExtent[1]);
        toCoord < axisExtent[0] && (toCoord = axisExtent[0]);

        this._currentPointer.x = toCoord;
        this._currentPointer.markRedraw();

        this._progressLine.shape.x2 = toCoord;
        this._progressLine.dirty();

        const targetDataIndex = this._findNearestTick(toCoord);
        const timelineModel = this.model;

        if (trigger || (
            targetDataIndex !== timelineModel.getCurrentIndex()
            && timelineModel.get('realtime')
        )) {
            this._changeTimeline(targetDataIndex);
        }
    }

    private _doPlayStop() {
        this._clearTimer();

        if (this.model.getPlayState()) {
            this._timer = setTimeout(
                () => {
                    // Do not cache
                    const timelineModel = this.model;
                    this._changeTimeline(
                        timelineModel.getCurrentIndex()
                        + (timelineModel.get('rewind', true) ? -1 : 1)
                    );
                },
                this.model.get('playInterval')
            ) as any;
        }
    }

    private _toAxisCoord(vertex: number[]) {
        const trans = this._mainGroup.getLocalTransform();
        return graphic.applyTransform(vertex, trans, true);
    }

    private _findNearestTick(axisCoord: number) {
        const data = this.model.getData();
        let dist = Infinity;
        let targetDataIndex;
        const axis = this._axis;

        data.each(['value'], function (value, dataIndex) {
            const coord = axis.dataToCoord(value);
            const d = Math.abs(coord - axisCoord);
            if (d < dist) {
                dist = d;
                targetDataIndex = dataIndex;
            }
        });

        return targetDataIndex;
    }

    private _clearTimer() {
        if (this._timer) {
            clearTimeout(this._timer);
            this._timer = null;
        }
    }

    private _changeTimeline(nextIndex: number | '+' | '-') {
        const currentIndex = this.model.getCurrentIndex();

        if (nextIndex === '+') {
            nextIndex = currentIndex + 1;
        }
        else if (nextIndex === '-') {
            nextIndex = currentIndex - 1;
        }

        this.api.dispatchAction({
            type: 'timelineChange',
            currentIndex: nextIndex,
            from: this.uid
        } as TimelineChangePayload);
    }

    private _updateTicksStatus() {
        const currentIndex = this.model.getCurrentIndex();
        const tickSymbols = this._tickSymbols;
        const tickLabels = this._tickLabels;

        if (tickSymbols) {
            for (let i = 0; i < tickSymbols.length; i++) {
                tickSymbols && tickSymbols[i]
                    && tickSymbols[i].toggleState('progress', i < currentIndex);
            }
        }
        if (tickLabels) {
            for (let i = 0; i < tickLabels.length; i++) {
                tickLabels && tickLabels[i]
                    && tickLabels[i].toggleState(
                        'progress', labelDataIndexStore(tickLabels[i]).dataIndex <= currentIndex
                    );
            }
        }
    }
}

function createScaleByModel(model: SliderTimelineModel, axisType?: string): Scale {
    axisType = axisType || model.get('type');
    if (axisType) {
        switch (axisType) {
            // Buildin scale
            case 'category':
                return new OrdinalScale({
                    ordinalMeta: model.getCategories(),
                    extent: [Infinity, -Infinity]
                });
            case 'time':
                return new TimeScale({
                    locale: model.ecModel.getLocaleModel(),
                    useUTC: model.ecModel.get('useUTC')
                });
            default:
                // default to be value
                return new IntervalScale();
        }
    }
}


function getViewRect(model: SliderTimelineModel, api: ExtensionAPI) {
    return layout.getLayoutRect(
        model.getBoxLayoutParams(),
        {
            width: api.getWidth(),
            height: api.getHeight()
        },
        model.get('padding')
    );
}

function makeControlIcon(
    timelineModel: TimelineModel,
    objPath: ControlIconName,
    rect: number[],
    opts: PathProps
) {
    const style = opts.style;

    const icon = graphic.createIcon(
        timelineModel.get(['controlStyle', objPath]),
        opts || {},
        new BoundingRect(rect[0], rect[1], rect[2], rect[3])
    );

    // TODO createIcon won't use style in opt.
    if (style) {
        (icon as Displayable).setStyle(style);
    }

    return icon;
}

/**
 * Create symbol or update symbol
 * opt: basic position and event handlers
 */
function giveSymbol(
    hostModel: Model<TimelineDataItemOption | TimelineCheckpointStyle>,
    itemStyleModel: Model<TimelineDataItemOption['itemStyle'] | TimelineCheckpointStyle>,
    group: graphic.Group,
    opt: PathProps,
    symbol?: TimelineSymbol,
    callback?: {
        onCreate?: (symbol: TimelineSymbol) => void
        onUpdate?: (symbol: TimelineSymbol) => void
    }
) {
    const color = itemStyleModel.get('color');

    if (!symbol) {
        const symbolType = hostModel.get('symbol');
        symbol = createSymbol(symbolType, -1, -1, 2, 2, color);
        symbol.setStyle('strokeNoScale', true);
        group.add(symbol);
        callback && callback.onCreate(symbol);
    }
    else {
        symbol.setColor(color);
        group.add(symbol); // Group may be new, also need to add.
        callback && callback.onUpdate(symbol);
    }

    // Style
    const itemStyle = itemStyleModel.getItemStyle(['color']);
    symbol.setStyle(itemStyle);

    // Transform and events.
    opt = merge({
        rectHover: true,
        z2: 100
    }, opt, true);

    const symbolSize = normalizeSymbolSize(hostModel.get('symbolSize'));

    opt.scaleX = symbolSize[0] / 2;
    opt.scaleY = symbolSize[1] / 2;

    const symbolOffset = normalizeSymbolOffset(hostModel.get('symbolOffset'), symbolSize);
    if (symbolOffset) {
        opt.x = (opt.x || 0) + symbolOffset[0];
        opt.y = (opt.y || 0) + symbolOffset[1];
    }

    const symbolRotate = hostModel.get('symbolRotate');
    opt.rotation = (symbolRotate || 0) * Math.PI / 180 || 0;

    symbol.attr(opt);

    // FIXME
    // (1) When symbol.style.strokeNoScale is true and updateTransform is not performed,
    // getBoundingRect will return wrong result.
    // (This is supposed to be resolved in zrender, but it is a little difficult to
    // leverage performance and auto updateTransform)
    // (2) All of ancesters of symbol do not scale, so we can just updateTransform symbol.
    symbol.updateTransform();

    return symbol;
}

function pointerMoveTo(
    pointer: TimelineSymbol,
    progressLine: graphic.Line,
    dataIndex: number,
    axis: TimelineAxis,
    timelineModel: SliderTimelineModel,
    noAnimation?: boolean
) {
    if (pointer.dragging) {
        return;
    }

    const pointerModel = timelineModel.getModel('checkpointStyle');
    const toCoord = axis.dataToCoord(timelineModel.getData().get('value', dataIndex));

    if (noAnimation || !pointerModel.get('animation', true)) {
        pointer.attr({
            x: toCoord,
            y: 0
        });
        progressLine && progressLine.attr({
            shape: { x2: toCoord }
        });
    }
    else {
        const animationCfg = {
            duration: pointerModel.get('animationDuration', true),
            easing: pointerModel.get('animationEasing', true)
        };
        pointer.stopAnimation(null, true);
        pointer.animateTo({
            x: toCoord,
            y: 0
        }, animationCfg);
        progressLine && progressLine.animateTo({
            shape: { x2: toCoord }
        }, animationCfg);
    }
}

export default SliderTimelineView;
