/*
 * Copyright (C) 2016-2020 Kano Computing Ltd.
 * License: http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Part } from '../../part.js';
import { part, property, component } from '../../decorators.js';
import { PartComponent } from '../../component.js';
import { transformLegacyTerminal } from './legacy.js';
class TerminalComponent extends PartComponent {
    constructor() {
        super(...arguments);
        this.visible = false;
    }
}
__decorate([
    property({ type: Boolean, value: false })
], TerminalComponent.prototype, "visible", void 0);
let TerminalPart = class TerminalPart extends Part {
    constructor() {
        super();
        this.domNode = document.createElement('div');
        this.message = '';
        this.lastLine = null;
        this.core = this._components.get('core');
        this._invalidateSub = this.core.onDidInvalidate(() => this.render());
        this.domNode.style.position = 'absolute';
        this.domNode.style.top = '0';
        this.domNode.style.left = '0';
        this.domNode.style.right = '0';
        this.domNode.style.bottom = '0';
        this.domNode.style.overflow = 'hidden';
        this.domNode.style.background = 'rgba(0, 0, 0, 0.9)';
        this.domNode.style.color = 'green';
    }
    static transformLegacy(app) {
        transformLegacyTerminal(app);
    }
    onInstall(context) {
        context.dom.root.appendChild(this.domNode);
        this.render();
    }
    render() {
        if (!this.core.invalidated) {
            return;
        }
        this.domNode.style.visibility = this.core.visible ? 'visible' : 'hidden';
        this.core.apply();
    }
    print(message) {
        this.message += message;
    }
    printLine(message) {
        this.print(`${message}\n`);
    }
    _printStack() {
        let lines;
        if (this.message === '') {
            return;
        }
        lines = this.message.split('\n');
        if (!this.lastLine) {
            this.lastLine = document.createElement('div');
            this.domNode.appendChild(this.lastLine);
        }
        lines.forEach((line, index) => {
            if (index === 0) {
                this.lastLine.innerText = this.lastLine.innerText + line;
                return;
            }
            const div = document.createElement('div');
            div.innerText = line;
            this.domNode.appendChild(div);
        });
        while (this.domNode.children.length > 30) {
            this.domNode.removeChild(this.domNode.firstChild);
        }
        this.domNode.scrollTop = this.domNode.scrollHeight;
        if (this.domNode.lastChild) {
            this.lastLine = this.domNode.lastChild;
        }
        this.message = '';
    }
    clear() {
        while (this.domNode.firstChild) {
            this.domNode.removeChild(this.domNode.firstChild);
        }
        this.lastLine = null;
        this.message = '';
    }
    set visible(state) {
        this.core.visible = state;
        this.core.invalidate();
    }
    _stopRendering() {
        clearInterval(this._renderingInterval);
    }
    _startRendering() {
        this._stopRendering();
        // Only do a real print at 20 fps. This will bulk all the DOM writes
        // that happens really fast
        this._renderingInterval = window.setInterval(this._printStack.bind(this), 1000 / 20);
    }
    onStart() {
        super.onStart();
        this._startRendering();
    }
    onStop() {
        super.onStop();
        this._stopRendering();
        this.clear();
    }
    dispose() {
        super.dispose();
        this._invalidateSub.dispose();
    }
};
__decorate([
    component(TerminalComponent)
], TerminalPart.prototype, "core", void 0);
TerminalPart = __decorate([
    part('terminal')
], TerminalPart);
export { TerminalPart };
//# sourceMappingURL=terminal.js.map