var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
    return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import { AcCmColor, AcCmColorMethod, AcDbLayerTableRecord } from '@mlightcad/data-model';
import { AcApDocManager } from '../app';
import { AcEdCommand, AcEdOpenMode, AcEdPromptKeywordOptions, AcEdPromptStatus, AcEdPromptStringOptions } from '../editor';
import { eventBus } from '../editor/global/eventBus';
import { AcApI18n } from '../i18n';
/**
 * AutoCAD-style command-line layer command (`-LAYER`).
 *
 * This command intentionally avoids any dialog UI and keeps all interactions
 * in command line prompts.
 */
var AcApLayerCmd = /** @class */ (function (_super) {
    __extends(AcApLayerCmd, _super);
    /**
     * Creates a command-line `-LAYER` command instance.
     *
     * The command is registered as a write-mode command because layer operations
     * can modify database state (current layer, visibility, lock state, color,
     * descriptions, and table records).
     */
    function AcApLayerCmd() {
        var _this = _super.call(this) || this;
        _this.mode = AcEdOpenMode.Write;
        return _this;
    }
    /**
     * Runs the interactive `-LAYER` loop.
     *
     * The command keeps prompting for top-level options until the user cancels
     * or confirms an empty input. Each selected keyword dispatches to one
     * dedicated branch handler.
     *
     * @param context - Active application context containing view and document.
     * @returns Resolves when the command exits.
     */
    AcApLayerCmd.prototype.execute = function (context) {
        return __awaiter(this, void 0, void 0, function () {
            var action, _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!true) return [3 /*break*/, 26];
                        return [4 /*yield*/, this.promptMainKeyword()];
                    case 1:
                        action = _b.sent();
                        if (!action)
                            return [2 /*return*/];
                        _a = action;
                        switch (_a) {
                            case '?': return [3 /*break*/, 2];
                            case 'Make': return [3 /*break*/, 3];
                            case 'Set': return [3 /*break*/, 5];
                            case 'New': return [3 /*break*/, 7];
                            case 'On': return [3 /*break*/, 9];
                            case 'Off': return [3 /*break*/, 11];
                            case 'Color': return [3 /*break*/, 13];
                            case 'Freeze': return [3 /*break*/, 15];
                            case 'Thaw': return [3 /*break*/, 17];
                            case 'Lock': return [3 /*break*/, 19];
                            case 'Unlock': return [3 /*break*/, 21];
                            case 'Description': return [3 /*break*/, 23];
                        }
                        return [3 /*break*/, 25];
                    case 2:
                        this.listLayers(context);
                        return [3 /*break*/, 25];
                    case 3: return [4 /*yield*/, this.runMake(context)];
                    case 4:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 5: return [4 /*yield*/, this.runSet(context)];
                    case 6:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 7: return [4 /*yield*/, this.runNew(context)];
                    case 8:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 9: return [4 /*yield*/, this.runOnOff(context, false)];
                    case 10:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 11: return [4 /*yield*/, this.runOnOff(context, true)];
                    case 12:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 13: return [4 /*yield*/, this.runColor(context)];
                    case 14:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 15: return [4 /*yield*/, this.runFreeze(context, true)];
                    case 16:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 17: return [4 /*yield*/, this.runFreeze(context, false)];
                    case 18:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 19: return [4 /*yield*/, this.runLock(context, true)];
                    case 20:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 21: return [4 /*yield*/, this.runLock(context, false)];
                    case 22:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 23: return [4 /*yield*/, this.runDescription(context)];
                    case 24:
                        _b.sent();
                        return [3 /*break*/, 25];
                    case 25: return [3 /*break*/, 0];
                    case 26: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Prompts for one top-level `-LAYER` action keyword.
     *
     * The prompt is keyword-only and supports empty-enter termination (`allowNone`).
     *
     * @returns Selected top-level keyword, or `undefined` when canceled/finished.
     */
    AcApLayerCmd.prototype.promptMainKeyword = function () {
        return __awaiter(this, void 0, void 0, function () {
            var prompt, result, keyword;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        prompt = new AcEdPromptKeywordOptions(AcApI18n.t('jig.layer.main'));
                        prompt.allowNone = true;
                        this.addKeyword(prompt, 'list');
                        this.addKeyword(prompt, 'make');
                        this.addKeyword(prompt, 'set');
                        this.addKeyword(prompt, 'new');
                        this.addKeyword(prompt, 'on');
                        this.addKeyword(prompt, 'off');
                        this.addKeyword(prompt, 'color');
                        this.addKeyword(prompt, 'freeze');
                        this.addKeyword(prompt, 'thaw');
                        this.addKeyword(prompt, 'lock');
                        this.addKeyword(prompt, 'unlock');
                        this.addKeyword(prompt, 'description');
                        return [4 /*yield*/, AcApDocManager.instance.editor.getKeywords(prompt)];
                    case 1:
                        result = _a.sent();
                        if (result.status !== AcEdPromptStatus.OK)
                            return [2 /*return*/, undefined];
                        keyword = result.stringResult;
                        return [2 /*return*/, keyword];
                }
            });
        });
    };
    /**
     * Adds one localized keyword entry to the main `-LAYER` prompt.
     *
     * @param prompt - Target keyword prompt to receive the keyword option.
     * @param keyword - Translation-key suffix for `jig.layer.keywords.*`.
     */
    AcApLayerCmd.prototype.addKeyword = function (prompt, keyword) {
        prompt.keywords.add(AcApI18n.t("jig.layer.keywords.".concat(keyword, ".display")), AcApI18n.t("jig.layer.keywords.".concat(keyword, ".global")), AcApI18n.t("jig.layer.keywords.".concat(keyword, ".local")));
    };
    /**
     * Emits one user-facing message through the global event bus.
     *
     * This keeps command logic decoupled from concrete UI rendering.
     *
     * @param message - Message text to display.
     * @param type - Message severity category.
     */
    AcApLayerCmd.prototype.notify = function (message, type) {
        if (type === void 0) { type = 'info'; }
        eventBus.emit('message', { message: message, type: type });
    };
    /**
     * Prints all layer states to browser console and reports summary in UI.
     *
     * The list contains the current-layer marker and common status columns
     * (on/off, frozen, locked, color).
     *
     * @param context - Active command context used to resolve the layer table.
     */
    AcApLayerCmd.prototype.listLayers = function (context) {
        var db = context.doc.database;
        var layers = __spreadArray([], __read(db.tables.layerTable.newIterator()), false);
        var rows = layers.map(function (layer) { return ({
            name: layer.name,
            current: db.clayer === layer.name ? '*' : '',
            on: layer.isOff ? 'No' : 'Yes',
            frozen: layer.isFrozen ? 'Yes' : 'No',
            locked: layer.isLocked ? 'Yes' : 'No',
            color: layer.color.toString()
        }); });
        console.table(rows);
        this.notify("".concat(AcApI18n.t('jig.layer.listSummary'), " (").concat(rows.length, ")"), 'info');
    };
    /**
     * Parses a raw layer-name input string into a distinct name list.
     *
     * Supported forms:
     * - `*` to target all existing layer names.
     * - Comma-separated names (e.g. `A,B,C`).
     *
     * @param input - Raw user input from command line.
     * @param allNames - All existing layer names, used for wildcard expansion.
     * @returns Deduplicated list of requested layer names.
     */
    AcApLayerCmd.prototype.parseLayerNameInput = function (input, allNames) {
        var raw = input.trim();
        if (!raw)
            return [];
        if (raw === '*')
            return __spreadArray([], __read(allNames), false);
        var names = raw
            .split(',')
            .map(function (v) { return v.trim(); })
            .filter(Boolean);
        return __spreadArray([], __read(new Set(names)), false);
    };
    /**
     * Resolves layer records by name and separates missing names.
     *
     * @param context - Active command context with access to layer table.
     * @param names - Layer names to resolve.
     * @returns Object containing matched records and unresolved names.
     */
    AcApLayerCmd.prototype.resolveLayers = function (context, names) {
        var table = context.doc.database.tables.layerTable;
        var layers = [];
        var missing = [];
        names.forEach(function (name) {
            var layer = table.getAt(name);
            if (layer)
                layers.push(layer);
            else
                missing.push(name);
        });
        return { layers: layers, missing: missing };
    };
    /**
     * Sets or clears the frozen bit in `standardFlags`.
     *
     * The explicit bit operation is used to ensure both freeze and thaw are
     * applied deterministically.
     *
     * @param layer - Target layer table record.
     * @param frozen - `true` to freeze, `false` to thaw.
     */
    AcApLayerCmd.prototype.setLayerFrozen = function (layer, frozen) {
        var _a;
        var flags = (_a = layer.standardFlags) !== null && _a !== void 0 ? _a : 0;
        layer.standardFlags = frozen ? flags | 0x01 : flags & ~0x01;
    };
    /**
     * Sets or clears the locked bit in `standardFlags`.
     *
     * The explicit bit operation is used to ensure both lock and unlock are
     * applied deterministically.
     *
     * @param layer - Target layer table record.
     * @param locked - `true` to lock, `false` to unlock.
     */
    AcApLayerCmd.prototype.setLayerLocked = function (layer, locked) {
        var _a;
        var flags = (_a = layer.standardFlags) !== null && _a !== void 0 ? _a : 0;
        layer.standardFlags = locked ? flags | 0x04 : flags & ~0x04;
    };
    /**
     * Prompts for one or more layer names and parses them into a list.
     *
     * This helper powers batch operations such as on/off/freeze/thaw/lock/unlock
     * and supports wildcard `*` plus comma-separated names.
     *
     * @param message - Prompt message shown in command line.
     * @param context - Active command context used for wildcard expansion.
     * @returns Parsed layer names, or `undefined` when canceled/invalid.
     */
    AcApLayerCmd.prototype.promptLayerNames = function (message, context) {
        return __awaiter(this, void 0, void 0, function () {
            var prompt, result, allNames, names;
            var _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        prompt = new AcEdPromptStringOptions(message);
                        prompt.allowSpaces = false;
                        return [4 /*yield*/, AcApDocManager.instance.editor.getString(prompt)];
                    case 1:
                        result = _b.sent();
                        if (result.status !== AcEdPromptStatus.OK)
                            return [2 /*return*/, undefined];
                        allNames = __spreadArray([], __read(context.doc.database.tables.layerTable.newIterator()), false).map(function (layer) { return layer.name; });
                        names = this.parseLayerNameInput((_a = result.stringResult) !== null && _a !== void 0 ? _a : '', allNames);
                        if (!names.length) {
                            this.notify(AcApI18n.t('jig.layer.emptyInput'), 'warning');
                            return [2 /*return*/, undefined];
                        }
                        return [2 /*return*/, names];
                }
            });
        });
    };
    /**
     * Prompts for a single layer name.
     *
     * @param message - Prompt message shown in command line.
     * @returns Trimmed layer name, or `undefined` when canceled/empty.
     */
    AcApLayerCmd.prototype.promptSingleLayerName = function (message) {
        return __awaiter(this, void 0, void 0, function () {
            var prompt, result, name;
            var _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        prompt = new AcEdPromptStringOptions(message);
                        prompt.allowSpaces = true;
                        return [4 /*yield*/, AcApDocManager.instance.editor.getString(prompt)];
                    case 1:
                        result = _b.sent();
                        if (result.status !== AcEdPromptStatus.OK)
                            return [2 /*return*/, undefined];
                        name = ((_a = result.stringResult) !== null && _a !== void 0 ? _a : '').trim();
                        return [2 /*return*/, name || undefined];
                }
            });
        });
    };
    /**
     * Handles the `New` branch.
     *
     * Creates one or more missing layers while keeping existing ones unchanged.
     * The method reports creation count and duplicate names separately.
     *
     * @param context - Active command context used to access the layer table.
     * @returns Resolves when branch execution completes.
     */
    AcApLayerCmd.prototype.runNew = function (context) {
        return __awaiter(this, void 0, void 0, function () {
            var names, table, created, existed;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.promptLayerNames(AcApI18n.t('jig.layer.newPrompt'), context)];
                    case 1:
                        names = _a.sent();
                        if (!names)
                            return [2 /*return*/];
                        table = context.doc.database.tables.layerTable;
                        created = 0;
                        existed = [];
                        names.forEach(function (name) {
                            if (table.has(name)) {
                                existed.push(name);
                                return;
                            }
                            table.add(new AcDbLayerTableRecord({
                                name: name,
                                isOff: false,
                                isPlottable: true,
                                color: new AcCmColor(AcCmColorMethod.ByACI, 7),
                                linetype: 'Continuous'
                            }));
                            created++;
                        });
                        if (created > 0) {
                            this.notify("".concat(AcApI18n.t('jig.layer.created'), ": ").concat(created), 'success');
                        }
                        if (existed.length > 0) {
                            this.notify("".concat(AcApI18n.t('jig.layer.alreadyExists'), ": ").concat(existed.join(', ')), 'warning');
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Handles the `Set` branch.
     *
     * Sets one existing layer as current (`CLAYER`) and ensures the target is
     * visible/unfrozen before assignment.
     *
     * @param context - Active command context.
     * @returns Resolves when branch execution completes.
     */
    AcApLayerCmd.prototype.runSet = function (context) {
        return __awaiter(this, void 0, void 0, function () {
            var name, layer;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.promptSingleLayerName(AcApI18n.t('jig.layer.setPrompt'))];
                    case 1:
                        name = _a.sent();
                        if (!name)
                            return [2 /*return*/];
                        layer = context.doc.database.tables.layerTable.getAt(name);
                        if (!layer) {
                            this.notify("".concat(AcApI18n.t('jig.layer.notFound'), ": ").concat(name), 'warning');
                            return [2 /*return*/];
                        }
                        layer.isOff = false;
                        this.setLayerFrozen(layer, false);
                        context.doc.database.clayer = layer.name;
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Handles the `Make` branch.
     *
     * Creates the layer if missing, then makes it current. The resulting current
     * layer is turned on and thawed.
     *
     * @param context - Active command context.
     * @returns Resolves when branch execution completes.
     */
    AcApLayerCmd.prototype.runMake = function (context) {
        return __awaiter(this, void 0, void 0, function () {
            var name, table, layer;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.promptSingleLayerName(AcApI18n.t('jig.layer.makePrompt'))];
                    case 1:
                        name = _a.sent();
                        if (!name)
                            return [2 /*return*/];
                        table = context.doc.database.tables.layerTable;
                        layer = table.getAt(name);
                        if (!layer) {
                            layer = new AcDbLayerTableRecord({
                                name: name,
                                isOff: false,
                                isPlottable: true,
                                color: new AcCmColor(AcCmColorMethod.ByACI, 7),
                                linetype: 'Continuous'
                            });
                            table.add(layer);
                        }
                        layer.isOff = false;
                        this.setLayerFrozen(layer, false);
                        context.doc.database.clayer = layer.name;
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Handles `On` and `Off` branches.
     *
     * Batch toggles visibility for selected layers. Turning off the current layer
     * is skipped and reported as warning.
     *
     * @param context - Active command context.
     * @param off - `true` for `Off`, `false` for `On`.
     * @returns Resolves when branch execution completes.
     */
    AcApLayerCmd.prototype.runOnOff = function (context, off) {
        return __awaiter(this, void 0, void 0, function () {
            var names, db, _a, layers, missing, skippedCurrent;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0: return [4 /*yield*/, this.promptLayerNames(off
                            ? AcApI18n.t('jig.layer.offPrompt')
                            : AcApI18n.t('jig.layer.onPrompt'), context)];
                    case 1:
                        names = _b.sent();
                        if (!names)
                            return [2 /*return*/];
                        db = context.doc.database;
                        _a = this.resolveLayers(context, names), layers = _a.layers, missing = _a.missing;
                        if (missing.length > 0) {
                            this.notify("".concat(AcApI18n.t('jig.layer.notFound'), ": ").concat(missing.join(', ')), 'warning');
                        }
                        skippedCurrent = [];
                        layers.forEach(function (layer) {
                            if (off && layer.name === db.clayer) {
                                skippedCurrent.push(layer.name);
                                return;
                            }
                            layer.isOff = off;
                        });
                        if (skippedCurrent.length > 0) {
                            this.notify(AcApI18n.t('jig.layer.cannotChangeCurrent'), 'warning');
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Handles `Freeze` and `Thaw` branches.
     *
     * Batch toggles frozen state using explicit bit operations. Freezing the
     * current layer is skipped and reported as warning.
     *
     * @param context - Active command context.
     * @param freeze - `true` for `Freeze`, `false` for `Thaw`.
     * @returns Resolves when branch execution completes.
     */
    AcApLayerCmd.prototype.runFreeze = function (context, freeze) {
        return __awaiter(this, void 0, void 0, function () {
            var names, db, _a, layers, missing, skippedCurrent;
            var _this = this;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0: return [4 /*yield*/, this.promptLayerNames(freeze
                            ? AcApI18n.t('jig.layer.freezePrompt')
                            : AcApI18n.t('jig.layer.thawPrompt'), context)];
                    case 1:
                        names = _b.sent();
                        if (!names)
                            return [2 /*return*/];
                        db = context.doc.database;
                        _a = this.resolveLayers(context, names), layers = _a.layers, missing = _a.missing;
                        if (missing.length > 0) {
                            this.notify("".concat(AcApI18n.t('jig.layer.notFound'), ": ").concat(missing.join(', ')), 'warning');
                        }
                        skippedCurrent = [];
                        layers.forEach(function (layer) {
                            if (freeze && layer.name === db.clayer) {
                                skippedCurrent.push(layer.name);
                                return;
                            }
                            _this.setLayerFrozen(layer, freeze);
                        });
                        if (skippedCurrent.length > 0) {
                            this.notify(AcApI18n.t('jig.layer.cannotChangeCurrent'), 'warning');
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Handles `Lock` and `Unlock` branches.
     *
     * Batch toggles lock state using explicit bit operations.
     *
     * @param context - Active command context.
     * @param lock - `true` for `Lock`, `false` for `Unlock`.
     * @returns Resolves when branch execution completes.
     */
    AcApLayerCmd.prototype.runLock = function (context, lock) {
        return __awaiter(this, void 0, void 0, function () {
            var names, _a, layers, missing;
            var _this = this;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0: return [4 /*yield*/, this.promptLayerNames(lock
                            ? AcApI18n.t('jig.layer.lockPrompt')
                            : AcApI18n.t('jig.layer.unlockPrompt'), context)];
                    case 1:
                        names = _b.sent();
                        if (!names)
                            return [2 /*return*/];
                        _a = this.resolveLayers(context, names), layers = _a.layers, missing = _a.missing;
                        if (missing.length > 0) {
                            this.notify("".concat(AcApI18n.t('jig.layer.notFound'), ": ").concat(missing.join(', ')), 'warning');
                        }
                        layers.forEach(function (layer) { return _this.setLayerLocked(layer, lock); });
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Parses one color input token into `AcCmColor`.
     *
     * Supported formats:
     * - ACI index (`1..255`)
     * - RGB string accepted by `AcCmColor.fromString`
     * - CSS color names accepted by `AcCmColor.fromString`
     *
     * `ByLayer` and `ByBlock` are rejected for explicit layer color assignment.
     *
     * @param input - Raw color input string.
     * @returns Parsed color object, or `undefined` when invalid/unsupported.
     */
    AcApLayerCmd.prototype.parseColorInput = function (input) {
        var value = input.trim();
        if (!value)
            return undefined;
        if (/^\d+$/.test(value)) {
            var index = Number(value);
            if (index >= 1 && index <= 255) {
                return new AcCmColor(AcCmColorMethod.ByACI, index);
            }
            return undefined;
        }
        var color = AcCmColor.fromString(value);
        if (!color)
            return undefined;
        if (color.isByACI) {
            var index = color.colorIndex;
            if (index == null || index < 1 || index > 255) {
                return undefined;
            }
        }
        if (color.isByLayer || color.isByBlock)
            return undefined;
        return color;
    };
    /**
     * Handles the `Color` branch.
     *
     * Prompts target layers first, then prompts color value and applies a cloned
     * color instance to each resolved layer.
     *
     * @param context - Active command context.
     * @returns Resolves when branch execution completes.
     */
    AcApLayerCmd.prototype.runColor = function (context) {
        return __awaiter(this, void 0, void 0, function () {
            var names, _a, layers, missing, colorPrompt, colorResult, color;
            var _b;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0: return [4 /*yield*/, this.promptLayerNames(AcApI18n.t('jig.layer.colorLayerPrompt'), context)];
                    case 1:
                        names = _c.sent();
                        if (!names)
                            return [2 /*return*/];
                        _a = this.resolveLayers(context, names), layers = _a.layers, missing = _a.missing;
                        if (missing.length > 0) {
                            this.notify("".concat(AcApI18n.t('jig.layer.notFound'), ": ").concat(missing.join(', ')), 'warning');
                        }
                        if (layers.length === 0)
                            return [2 /*return*/];
                        colorPrompt = new AcEdPromptStringOptions(AcApI18n.t('jig.layer.colorValuePrompt'));
                        colorPrompt.allowSpaces = false;
                        return [4 /*yield*/, AcApDocManager.instance.editor.getString(colorPrompt)];
                    case 2:
                        colorResult = _c.sent();
                        if (colorResult.status !== AcEdPromptStatus.OK)
                            return [2 /*return*/];
                        color = this.parseColorInput((_b = colorResult.stringResult) !== null && _b !== void 0 ? _b : '');
                        if (!color) {
                            this.notify(AcApI18n.t('jig.layer.invalidColor'), 'warning');
                            return [2 /*return*/];
                        }
                        layers.forEach(function (layer) {
                            layer.color = color.clone();
                        });
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Handles the `Description` branch.
     *
     * Updates the description text of one specified layer. Empty description is
     * allowed and treated as clear.
     *
     * @param context - Active command context.
     * @returns Resolves when branch execution completes.
     */
    AcApLayerCmd.prototype.runDescription = function (context) {
        return __awaiter(this, void 0, void 0, function () {
            var name, layer, descPrompt, result;
            var _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0: return [4 /*yield*/, this.promptSingleLayerName(AcApI18n.t('jig.layer.descriptionLayerPrompt'))];
                    case 1:
                        name = _b.sent();
                        if (!name)
                            return [2 /*return*/];
                        layer = context.doc.database.tables.layerTable.getAt(name);
                        if (!layer) {
                            this.notify("".concat(AcApI18n.t('jig.layer.notFound'), ": ").concat(name), 'warning');
                            return [2 /*return*/];
                        }
                        descPrompt = new AcEdPromptStringOptions(AcApI18n.t('jig.layer.descriptionValuePrompt'));
                        descPrompt.allowSpaces = true;
                        descPrompt.allowEmpty = true;
                        return [4 /*yield*/, AcApDocManager.instance.editor.getString(descPrompt)];
                    case 2:
                        result = _b.sent();
                        if (result.status !== AcEdPromptStatus.OK)
                            return [2 /*return*/];
                        layer.description = (_a = result.stringResult) !== null && _a !== void 0 ? _a : '';
                        return [2 /*return*/];
                }
            });
        });
    };
    return AcApLayerCmd;
}(AcEdCommand));
export { AcApLayerCmd };
//# sourceMappingURL=AcApLayerCmd.js.map