/*
* 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 timeline from './timeline';

function waitTime(time) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve();
        }, time);
    });
};

export class ActionPlayback {

    constructor() {
        this._timer = 0;
        this._current = 0;

        this._ops = [];
        this._currentOpIndex = 0;

        this._isLastOpMousewheel = false;
    }

    getContext() {
        return {
            elapsedTime: this._elapsedTime,
            currentOpIndex: this._currentOpIndex,
            isLastOpMouseWheel: this._isLastOpMousewheel
        }
    }

    _reset() {
        this._currentOpIndex = 0;
        this._current = Date.now();
        this._elapsedTime = 0;
        this._isLastOpMousewheel = false;
    }

    _restoreContext(ctx) {
        this._elapsedTime = ctx.elapsedTime;
        this._currentOpIndex = ctx.currentOpIndex;
        this._isLastOpMousewheel = ctx.isLastOpMouseWheel;
    }

    async runAction(action, ctxToRestore) {
        this.stop();

        if (!action.ops.length) {
            return;
        }

        this._ops = action.ops.slice().sort((a, b) => {
            return a.time - b.time;
        });
        let firstOp = this._ops[0];
        this._ops.forEach(op => {
            op.time -= firstOp.time;
        });

        this._reset();

        if (ctxToRestore) {
            this._restoreContext(ctxToRestore);
            // Usually restore context happens when page is reloaded after mouseup.
            // In this case the _currentOpIndex is not increased yet.
            this._currentOpIndex++;
        }

        let self = this;

        async function takeScreenshot() {
            // Pause timeline when doing screenshot to avoid screenshot needs taking a while.
            timeline.pause();
            await __VRT_ACTION_SCREENSHOT__(action);
            timeline.resume();
        }

        return new Promise((resolve, reject) => {
            async function tick() {
                let current = Date.now();
                let dTime = current - self._current;
                self._elapsedTime += dTime;
                self._current = current;

                try {
                    // Execute all if there are multiple ops in one frame.
                    do {
                        const executed = await self._update(takeScreenshot);
                        if (!executed) {
                            break;
                        }
                    } while (true);
                }
                catch (e) {
                    // Stop running and throw error.
                    reject(e);
                    return;
                }

                if (self._currentOpIndex >= self._ops.length) {
                    // Finished
                    resolve();
                }
                else {
                    self._timer = setTimeout(tick, 0);
                }
            }
            tick();
        });
    }


    stop() {
        if (this._timer) {
            clearTimeout(this._timer);
            this._timer = 0;
        }
    }

    async _update(takeScreenshot) {
        let op = this._ops[this._currentOpIndex];

        if (!op || (op.time > this._elapsedTime)) {
            // Not yet.
            return;
        }

        let screenshotTaken = false;
        switch (op.type) {
            case 'mousedown':
                // Pause timeline to avoid frame not sync.
                timeline.pause();
                await __VRT_MOUSE_MOVE__(op.x, op.y);
                await __VRT_MOUSE_DOWN__();
                timeline.resume();
                break;
            case 'mouseup':
                timeline.pause();
                await __VRT_MOUSE_MOVE__(op.x, op.y);
                await __VRT_MOUSE_UP__();
                if (window.__VRT_RELOAD_TRIGGERED__) {
                    return;
                }
                timeline.resume();
                break;
            case 'mousemove':
                timeline.pause();
                await __VRT_MOUSE_MOVE__(op.x, op.y);
                timeline.resume();
                break;
            case 'mousewheel':
                let element = document.elementFromPoint(op.x, op.y);
                // Here dispatch mousewheel event because echarts used it.
                // TODO Consider upgrade?
                let event = new WheelEvent('mousewheel', {
                    // PENDING
                    // Needs inverse delta?
                    deltaY: op.deltaY,
                    clientX: op.x, clientY: op.y,
                    // Needs bubble to parent container
                    bubbles: true
                });
                element.dispatchEvent(event);
                this._isLastOpMousewheel = true;
                break;
            case 'screenshot':
                await takeScreenshot();
                screenshotTaken = true;
                break;
            case 'valuechange':
                document.querySelector(op.selector).value = op.value;
                break;
        }

        this._currentOpIndex++;

        // If next op is an auto screenshot
        let nextOp = this._ops[this._currentOpIndex];
        if (nextOp && nextOp.type === 'screenshot-auto') {
            let delay = nextOp.delay == null ? 400 : nextOp.delay;
            // TODO Configuration time
            await waitTime(delay);
            await takeScreenshot();
            screenshotTaken = true;
            this._currentOpIndex++;
        }

        if (this._isLastOpMousewheel && op.type !== 'mousewheel') {
            // Only take screenshot after mousewheel finished
            if (!screenshotTaken) {
                await takeScreenshot();
            }
            this._isLastOpMousewheel = false;
        }

        return true;
    }
};