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

// TODO Batch by color

import * as graphic from '../../util/graphic';
import * as lineContain from 'zrender/src/contain/line';
import * as quadraticContain from 'zrender/src/contain/quadratic';
import { PathProps } from 'zrender/src/graphic/Path';
import SeriesData from '../../data/SeriesData';
import { StageHandlerProgressParams, LineStyleOption, ColorString } from '../../util/types';
import Model from '../../model/Model';
import { getECData } from '../../util/innerStore';
import Element from 'zrender/src/Element';

class LargeLinesPathShape {
    polyline = false;
    curveness = 0;
    segs: ArrayLike<number> = [];
}

interface LargeLinesPathProps extends PathProps {
    shape?: Partial<LargeLinesPathShape>
}

interface LargeLinesCommonOption {
    polyline?: boolean
    lineStyle?: LineStyleOption & {
        curveness?: number
    }
}

/**
 * Data which can support large lines.
 */
type LargeLinesData = SeriesData<Model<LargeLinesCommonOption> & {
    seriesIndex?: number
}>;

class LargeLinesPath extends graphic.Path {
    shape: LargeLinesPathShape;

    __startIndex: number;
    private _off: number = 0;

    hoverDataIdx: number = -1;

    notClear: boolean;

    constructor(opts?: LargeLinesPathProps) {
        super(opts);
    }

    reset() {
        this.notClear = false;
        this._off = 0;
    }

    getDefaultStyle() {
        return {
            stroke: '#000',
            fill: null as ColorString
        };
    }

    getDefaultShape() {
        return new LargeLinesPathShape();
    }

    buildPath(ctx: CanvasRenderingContext2D, shape: LargeLinesPathShape) {
        const segs = shape.segs;
        const curveness = shape.curveness;
        let i;

        if (shape.polyline) {
            for (i = this._off; i < segs.length;) {
                const count = segs[i++];
                if (count > 0) {
                    ctx.moveTo(segs[i++], segs[i++]);
                    for (let k = 1; k < count; k++) {
                        ctx.lineTo(segs[i++], segs[i++]);
                    }
                }
            }
        }
        else {
            for (i = this._off; i < segs.length;) {
                const x0 = segs[i++];
                const y0 = segs[i++];
                const x1 = segs[i++];
                const y1 = segs[i++];
                ctx.moveTo(x0, y0);
                if (curveness > 0) {
                    const x2 = (x0 + x1) / 2 - (y0 - y1) * curveness;
                    const y2 = (y0 + y1) / 2 - (x1 - x0) * curveness;
                    ctx.quadraticCurveTo(x2, y2, x1, y1);
                }
                else {
                    ctx.lineTo(x1, y1);
                }
            }
        }
        if (this.incremental) {
            this._off = i;
            this.notClear = true;
        }
    }

    findDataIndex(x: number, y: number) {

        const shape = this.shape;
        const segs = shape.segs;
        const curveness = shape.curveness;
        const lineWidth = this.style.lineWidth;

        if (shape.polyline) {
            let dataIndex = 0;
            for (let i = 0; i < segs.length;) {
                const count = segs[i++];
                if (count > 0) {
                    const x0 = segs[i++];
                    const y0 = segs[i++];
                    for (let k = 1; k < count; k++) {
                        const x1 = segs[i++];
                        const y1 = segs[i++];
                        if (lineContain.containStroke(x0, y0, x1, y1, lineWidth, x, y)) {
                            return dataIndex;
                        }
                    }
                }

                dataIndex++;
            }
        }
        else {
            let dataIndex = 0;
            for (let i = 0; i < segs.length;) {
                const x0 = segs[i++];
                const y0 = segs[i++];
                const x1 = segs[i++];
                const y1 = segs[i++];
                if (curveness > 0) {
                    const x2 = (x0 + x1) / 2 - (y0 - y1) * curveness;
                    const y2 = (y0 + y1) / 2 - (x1 - x0) * curveness;

                    if (quadraticContain.containStroke(
                        x0, y0, x2, y2, x1, y1, lineWidth, x, y
                    )) {
                        return dataIndex;
                    }
                }
                else {
                    if (lineContain.containStroke(
                        x0, y0, x1, y1, lineWidth, x, y
                    )) {
                        return dataIndex;
                    }
                }

                dataIndex++;
            }
        }

        return -1;
    }

    contain(x: number, y: number): boolean {
        const localPos = this.transformCoordToLocal(x, y);
        const rect = this.getBoundingRect();
        x = localPos[0];
        y = localPos[1];

        if (rect.contain(x, y)) {
            // Cache found data index.
            const dataIdx = this.hoverDataIdx = this.findDataIndex(x, y);
            return dataIdx >= 0;
        }
        this.hoverDataIdx = -1;
        return false;
    }

    getBoundingRect() {
        // Ignore stroke for large symbol draw.
        let rect = this._rect;
        if (!rect) {
            const shape = this.shape;
            const points = shape.segs;
            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++];
                minX = Math.min(x, minX);
                maxX = Math.max(x, maxX);
                minY = Math.min(y, minY);
                maxY = Math.max(y, maxY);
            }

            rect = this._rect = new graphic.BoundingRect(minX, minY, maxX, maxY);
        }
        return rect;
    }
}

class LargeLineDraw {
    group = new graphic.Group();
    private _newAdded: LargeLinesPath[];
    /**
     * Update symbols draw by new data
     */
    updateData(data: LargeLinesData) {
        this._clear();

        const lineEl = this._create();
        lineEl.setShape({
            segs: data.getLayout('linesPoints')
        });

        this._setCommon(lineEl, data);
    };

    /**
     * @override
     */
    incrementalPrepareUpdate(data: LargeLinesData) {
        this.group.removeAll();
        this._clear();
    };

    /**
     * @override
     */
    incrementalUpdate(taskParams: StageHandlerProgressParams, data: LargeLinesData) {
        const lastAdded = this._newAdded[0];
        const linePoints = data.getLayout('linesPoints');

        const oldSegs = lastAdded && lastAdded.shape.segs;

        // Merging the exists. Each element has 1e4 points.
        // Consider the performance balance between too much elements and too much points in one shape(may affect hover optimization)
        if (oldSegs && oldSegs.length < 2e4) {
            const oldLen = oldSegs.length;
            const newSegs = new Float32Array(oldLen + linePoints.length);
            // Concat two array
            newSegs.set(oldSegs);
            newSegs.set(linePoints, oldLen);
            lastAdded.setShape({
                segs: newSegs
            });
        }
        else {
            // Clear
            this._newAdded = [];

            const lineEl = this._create();
            lineEl.incremental = true;
            lineEl.setShape({
                segs: linePoints
            });
            this._setCommon(lineEl, data);
            lineEl.__startIndex = taskParams.start;
        }
    }

    /**
     * @override
     */
    remove() {
        this._clear();
    }

    eachRendered(cb: (el: Element) => boolean | void) {
        this._newAdded[0] && cb(this._newAdded[0]);
    }

    private _create() {
        const lineEl = new LargeLinesPath({
            cursor: 'default',
            ignoreCoarsePointer: true
        });
        this._newAdded.push(lineEl);
        this.group.add(lineEl);
        return lineEl;
    }


    private _setCommon(lineEl: LargeLinesPath, data: LargeLinesData, isIncremental?: boolean) {
        const hostModel = data.hostModel;

        lineEl.setShape({
            polyline: hostModel.get('polyline'),
            curveness: hostModel.get(['lineStyle', 'curveness'])
        });

        lineEl.useStyle(
            hostModel.getModel('lineStyle').getLineStyle()
        );
        lineEl.style.strokeNoScale = true;

        const style = data.getVisual('style');
        if (style && style.stroke) {
            lineEl.setStyle('stroke', style.stroke);
        }
        lineEl.setStyle('fill', null);

        const ecData = getECData(lineEl);
        // Enable tooltip
        // PENDING May have performance issue when path is extremely large
        ecData.seriesIndex = hostModel.seriesIndex;
        lineEl.on('mousemove', function (e) {
            ecData.dataIndex = null;
            const dataIndex = lineEl.hoverDataIdx;
            if (dataIndex > 0) {
                // Provide dataIndex for tooltip
                ecData.dataIndex = dataIndex + lineEl.__startIndex;
            }
        });
    };

    private _clear() {
        this._newAdded = [];
        this.group.removeAll();
    };


}

export default LargeLineDraw;