"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
const Location_1 = require("./Location");
const ste_events_1 = require("ste-events");
const Log_1 = require("../core/Log");
class GameStateManager {
    get playerMajorLocationHistory() {
        return this._playerMajorLocationHistory;
    }
    get playerLocationHistory() {
        return this._playerLocationHistory;
    }
    get itemInteractedHistory() {
        return this._itemInteractedLocationHistory;
    }
    get playerLocation() {
        return this._playerLocation;
    }
    get onPlayerTravelled() {
        return this._onPlayerTravelled.asEvent();
    }
    get onPlayerMajorTravelled() {
        return this._onPlayerMajorTravelled.asEvent();
    }
    get onItemInteracted() {
        return this._onItemInteracted.asEvent();
    }
    get onBlockBroken() {
        return this._onBlockBroken.asEvent();
    }
    constructor(carto) {
        this._playerLocationHistory = [];
        this._playerLocationHistoryTimes = [];
        this._itemInteractedLocationHistory = [];
        this._itemInteractedLocationHistoryTimes = [];
        this._playerMajorLocationHistory = [];
        this._playerMajorLocationHistoryTimes = [];
        this.curTick = 0;
        this.pendingLocationChangeProcess = -1;
        this._eventsSeen = {};
        this._onPlayerTravelled = new ste_events_1.EventDispatcher();
        this._onItemInteracted = new ste_events_1.EventDispatcher();
        this._onBlockBroken = new ste_events_1.EventDispatcher();
        this._onPlayerMajorTravelled = new ste_events_1.EventDispatcher();
        this._tick = this._tick.bind(this);
        // @ts-ignore
        if (typeof window !== "undefined") {
            // @ts-ignore
            window.setInterval(this._tick, 50);
        }
    }
    _tick() {
        const thisTick = this.curTick++;
        // record the last stop if the player stops moving for 3 seconds.
        if (this.pendingLocationChangeProcess === thisTick && this._lastPlayerTravelledMessage) {
            this.pendingLocationChangeProcess = -1;
            const location = this._playerLocationHistory[this._playerLocationHistory.length - 1];
            const date = this._playerMajorLocationHistoryTimes[this._playerMajorLocationHistoryTimes.length - 1];
            this._playerMajorLocationHistory.push(location);
            this._playerMajorLocationHistoryTimes.push(date);
            this._onPlayerMajorTravelled.dispatch(this, this._lastPlayerTravelledMessage);
        }
    }
    handleEvent(message) {
        if (!message.header) {
            return;
        }
        const eventId = message.eventId;
        if (eventId) {
            if (this._eventsSeen[eventId] === true) {
                return;
            }
            this._eventsSeen[eventId] = true;
        }
        const eventName = message.header.eventName;
        if (!eventName) {
            return;
        }
        switch (eventName) {
            case "BlockBroken":
                const blockBrokenMessage = message;
                this._onBlockBroken.dispatch(this, blockBrokenMessage);
                break;
            case "ItemInteracted":
                const itemInteractedMessage = message;
                const interactedEventTime = new Date();
                let itemInteractedLocation = new Location_1.default(0, 0, 0);
                if (this._lastPlayerTravelledMessage) {
                    itemInteractedLocation = new Location_1.default(this._lastPlayerTravelledMessage.body.player.position.x, this._lastPlayerTravelledMessage.body.player.position.y, this._lastPlayerTravelledMessage.body.player.position.z);
                }
                this._itemInteractedLocationHistory.push(itemInteractedLocation);
                this._itemInteractedLocationHistoryTimes.push(interactedEventTime);
                this._onItemInteracted.dispatch(this, itemInteractedMessage);
                Log_1.default.verbose("Item was interacted");
                break;
            case "PlayerTravelled":
                const playerMessage = message;
                const location = new Location_1.default(playerMessage.body.player.position.x, playerMessage.body.player.position.y, playerMessage.body.player.position.z);
                const eventTime = new Date();
                this._lastPlayerTravelledMessage = playerMessage;
                this._playerLocationHistory.push(location);
                this._playerLocationHistoryTimes.push(eventTime);
                this._playerLocation = location;
                this._onPlayerTravelled.dispatch(this, playerMessage);
                let pushMajorLocationChange = false;
                if (this._playerMajorLocationHistory.length === 0) {
                    pushMajorLocationChange = true;
                }
                else {
                    const lastMajorLocation = this._playerMajorLocationHistory[this._playerMajorLocationHistory.length - 1];
                    if (location.distanceTo(lastMajorLocation) > 2) {
                        pushMajorLocationChange = true;
                    }
                }
                if (pushMajorLocationChange) {
                    this._playerMajorLocationHistory.push(location);
                    this._playerMajorLocationHistoryTimes.push(eventTime);
                    this._onPlayerMajorTravelled.dispatch(this, playerMessage);
                }
                else {
                    // record the last stop if the player stops moving for 3 seconds.
                    this.pendingLocationChangeProcess = this.curTick + 60;
                }
                break;
        }
    }
}
exports.default = GameStateManager;

//# sourceMappingURL=../maps/minecraft/GameStateManager.js.map
