"use strict";
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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const BehaviorUtils_1 = require("./BehaviorUtils");
const Styles_1 = require("../editor/components/styles/Styles");
const AliasBox_1 = require("../editor/boxes/AliasBox");
const ListBox_1 = require("../editor/boxes/ListBox");
const SelectBox_1 = require("../editor/boxes/SelectBox");
const BalanceTreeUtils_1 = require("./BalanceTreeUtils");
const PiUtils_1 = require("./PiUtils");
function createDefaultExpressionBox(exp, role, children, initializer) {
    const leftMost = BalanceTreeUtils_1.BTREE.isLeftMostChild(exp);
    const rightMost = BalanceTreeUtils_1.BTREE.isRightMostChild(exp);
    if (leftMost || rightMost) {
        let result;
        if (children.length === 1 && ListBox_1.isHorizontalBox(children[0])) {
            result = children[0];
        }
        else {
            result = new ListBox_1.HorizontalListBox(exp, BalanceTreeUtils_1.EXPRESSION, children);
        }
        if (leftMost) {
            result.insertChild(new AliasBox_1.AliasBox(exp, BalanceTreeUtils_1.LEFT_MOST, PiUtils_1.NBSP, { style: Styles_1.STYLES.aliasExpression }));
        }
        if (rightMost) {
            result.addChild(new AliasBox_1.AliasBox(exp, BalanceTreeUtils_1.RIGHT_MOST, PiUtils_1.NBSP, { style: Styles_1.STYLES.aliasExpression }));
        }
        return result;
    }
    else {
        if (children.length === 1) {
            return children[0];
        }
        else {
            return new ListBox_1.HorizontalListBox(exp, BalanceTreeUtils_1.EXPRESSION, children);
        }
    }
}
exports.createDefaultExpressionBox = createDefaultExpressionBox;
function createDefaultBinaryBox(projection, exp, symbol, editor, style) {
    const result = new ListBox_1.HorizontalListBox(exp, BalanceTreeUtils_1.BINARY_EXPRESSION);
    const projectionToUse = !!projection.rootProjection ? projection.rootProjection : projection;
    result.addChildren([
        (!!exp.piLeft() ? projectionToUse.getBox(exp.piLeft()) : new AliasBox_1.AliasBox(exp, "PiBinaryExpression-left", "[add-left]", { propertyName: "left" })),
        new AliasBox_1.AliasBox(exp, BalanceTreeUtils_1.BEFORE_BINARY_OPERATOR, PiUtils_1.NBSP, {
            style: Styles_1.STYLES.aliasExpression
        }),
        createOperatorBox(editor, exp, symbol),
        new AliasBox_1.AliasBox(exp, BalanceTreeUtils_1.AFTER_BINARY_OPERATOR, PiUtils_1.NBSP, {
            style: Styles_1.STYLES.aliasExpression
        }),
        (!!exp.piRight() ? projectionToUse.getBox(exp.piRight()) : new AliasBox_1.AliasBox(exp, "PiBinaryExpression-right", "[add-right]", { propertyName: "right" }))
    ]);
    return result;
}
exports.createDefaultBinaryBox = createDefaultBinaryBox;
function createOperatorBox(editor, exp, symbol, style) {
    const operatorBox = new SelectBox_1.SelectBox(exp, BalanceTreeUtils_1.EXPRESSION_SYMBOL, "<...>", () => {
        if (!!editor.actions && editor.actions.binaryExpressionCreators) {
            return editor.actions.binaryExpressionCreators
                .filter(e => !e.isApplicable || e.isApplicable(operatorBox))
                .map(e => ({
                id: e.trigger,
                label: e.trigger,
                description: "empty description for operator",
                icon: null,
                hideInList: false
            }));
        }
        else {
            return [];
        }
    }, () => null, (option) => __awaiter(this, void 0, void 0, function* () {
        if (editor.actions && editor.actions.binaryExpressionCreators) {
            const alias = editor.actions.binaryExpressionCreators.filter(e => e.trigger === option.id)[0];
            if (alias) {
                const newExp = alias.expressionBuilder(operatorBox, alias.trigger, editor);
                newExp.piSetLeft(exp.piLeft());
                newExp.piSetRight(exp.piRight());
                PiUtils_1.PiUtils.replaceExpression(exp, newExp, editor);
                BalanceTreeUtils_1.BTREE.balanceTree(newExp, editor);
                exp = newExp;
                yield editor.selectElement(newExp.piRight());
                yield editor.selectBox(operatorBox.nextLeafRight.firstLeaf, BehaviorUtils_1.PiCaret.LEFT_MOST);
            }
        }
    }), {
        style: style
    });
    operatorBox.getSelectedOption = () => {
        return { id: symbol, label: symbol };
    };
    return operatorBox;
}
exports.createOperatorBox = createOperatorBox;
//# sourceMappingURL=PiExpressionHelpers.js.map