"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Notation = exports.MetaData = exports.Command = exports.findContainingBlock = exports.isRawBlock = exports.isLine = exports.isBlock = exports.GroupBlock = exports.RoleBlock = exports.BreaksBlock = exports.BeatDurationBlock = exports.CycleBlock = exports.RepeatBlock = exports.SectionBlock = exports.Block = exports.RawBlock = exports.RoleDef = void 0;
const entity_1 = require("./entity");
const cycle_1 = require("./cycle");
const core_1 = require("./core");
const block_1 = require("./block");
Object.defineProperty(exports, "RoleDef", { enumerable: true, get: function () { return block_1.RoleDef; } });
Object.defineProperty(exports, "RawBlock", { enumerable: true, get: function () { return block_1.RawBlock; } });
Object.defineProperty(exports, "Block", { enumerable: true, get: function () { return block_1.Block; } });
Object.defineProperty(exports, "SectionBlock", { enumerable: true, get: function () { return block_1.SectionBlock; } });
Object.defineProperty(exports, "RepeatBlock", { enumerable: true, get: function () { return block_1.RepeatBlock; } });
Object.defineProperty(exports, "CycleBlock", { enumerable: true, get: function () { return block_1.CycleBlock; } });
Object.defineProperty(exports, "BeatDurationBlock", { enumerable: true, get: function () { return block_1.BeatDurationBlock; } });
Object.defineProperty(exports, "BreaksBlock", { enumerable: true, get: function () { return block_1.BreaksBlock; } });
Object.defineProperty(exports, "RoleBlock", { enumerable: true, get: function () { return block_1.RoleBlock; } });
Object.defineProperty(exports, "GroupBlock", { enumerable: true, get: function () { return block_1.GroupBlock; } });
Object.defineProperty(exports, "isBlock", { enumerable: true, get: function () { return block_1.isBlock; } });
Object.defineProperty(exports, "isLine", { enumerable: true, get: function () { return block_1.isLine; } });
Object.defineProperty(exports, "isRawBlock", { enumerable: true, get: function () { return block_1.isRawBlock; } });
Object.defineProperty(exports, "findContainingBlock", { enumerable: true, get: function () { return block_1.findContainingBlock; } });
class Command extends entity_1.Entity {
    constructor(params = []) {
        super();
        this.autoGenerated = false;
        this.prevSibling = null;
        this.nextSibling = null;
        this.params = params;
        this.index = 0;
        this.validateParams();
    }
    validateParams() {
    }
    get name() {
        return this.constructor.name;
    }
    debugValue() {
        return { name: this.name, index: this.index, params: this.params };
    }
    getParam(name) {
        for (const param of this.params) {
            if (param.key == name)
                return param.value;
        }
        return null;
    }
    getParamAt(index) {
        return index < this.params.length ? this.params[index].value : null;
    }
    applyToNotation(notation) {
        this.applyToBlock(notation);
    }
}
exports.Command = Command;
class MetaData {
    constructor(key, value, params) {
        this.key = key;
        this.value = value;
        this.params = params;
        params = params || {};
    }
}
exports.MetaData = MetaData;
class Notation extends block_1.Block {
    constructor() {
        super("notation", null);
        this.TYPE = "Notation";
        this.metadata = new Map();
        this.onMissingRole = (name) => this.newRoleDef(name, name == "sw");
        this._currRoleDef = null;
        this._currentLine = null;
        this.localCycle = cycle_1.Cycle.DEFAULT;
        this.localAtomsPerBeat = 1;
        this.localBreaks = [];
    }
    get blocks() {
        return this.blockItems;
    }
    get currentAPB() {
        var _a;
        return (_a = this.localAtomsPerBeat) !== null && _a !== void 0 ? _a : 1;
    }
    set currentAPB(value) {
        this.localAtomsPerBeat = value;
    }
    get currentCycle() {
        var _a;
        return (_a = this.localCycle) !== null && _a !== void 0 ? _a : cycle_1.Cycle.DEFAULT;
    }
    set currentCycle(value) {
        this.localCycle = value;
    }
    get currentBreaks() {
        var _a;
        return (_a = this.localBreaks) !== null && _a !== void 0 ? _a : [];
    }
    set currentBreaks(value) {
        this.localBreaks = value;
    }
    get roles() {
        return Array.from(this.localRoles.values());
    }
    setCurrRole(name) {
        name = name.trim().toLowerCase();
        if (name.trim() == "") {
            throw new Error("Role name cannot be empty");
        }
        const roleDef = this.getRole(name) || (this.onMissingRole ? this.onMissingRole(name) || null : null);
        if (roleDef == null) {
            throw new Error("Role not found: " + name);
        }
        this._currRoleDef = roleDef;
    }
    getRoleDef(name) {
        var _a;
        name = name.trim().toLowerCase();
        if (name === "") {
            const roles = Array.from(this.localRoles.values());
            return roles[roles.length - 1] || null;
        }
        return (_a = this.localRoles.get(name)) !== null && _a !== void 0 ? _a : null;
    }
    newRoleDef(name, notesOnly = false) {
        name = name.trim().toLowerCase();
        if (name === "") {
            throw new Error("Role name cannot be empty");
        }
        if (this.localRoles.has(name)) {
            throw new Error("Role already exists: " + name);
        }
        const rd = new block_1.RoleDef();
        rd.name = name;
        rd.notesOnly = notesOnly;
        rd.index = this.localRoles.size;
        this.localRoles.set(name, rd);
        return rd;
    }
    addLine(line) {
        this.addBlockItem(line);
    }
    removeLine(line) {
        return this.removeBlockItem(line);
    }
    addRawBlock(raw) {
        this.addBlockItem(raw);
        this.resetLine();
    }
    addMetaData(meta, addBlock = true) {
        if (addBlock && !this.metadata.has(meta.key)) {
            const raw = new block_1.RawBlock(meta.key, "metadata");
            this.addRawBlock(raw);
        }
        this.metadata.set(meta.key, meta);
    }
    resetLine() {
        this._currentLine = null;
    }
    debugValue() {
        var _a;
        return {
            blocks: this.blocks.map((b) => b.debugValue()),
            currentAPB: this.currentAPB,
            currentBreaks: this.currentBreaks,
            currentCycle: (_a = this.currentCycle) === null || _a === void 0 ? void 0 : _a.uuid,
            roles: this.roles,
        };
    }
    get currRoleDef() {
        if (this._currRoleDef == null) {
            const roles = Array.from(this.localRoles.values());
            if (roles.length === 0) {
                return null;
            }
            else {
                this._currRoleDef = roles[roles.length - 1];
            }
        }
        return this._currRoleDef;
    }
    get currentLine() {
        if (this._currentLine == null) {
            return this.newLine();
        }
        return this._currentLine;
    }
    newLine() {
        if (this._currentLine && this._currentLine.isEmpty) {
            this.removeLine(this._currentLine);
        }
        this._currentLine = new core_1.Line();
        this.addLine(this._currentLine);
        return this._currentLine;
    }
}
exports.Notation = Notation;
//# sourceMappingURL=notation.js.map