"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormBuilder = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = tslib_1.__importDefault(require("react"));
const FormDesignConstants_1 = require("./Utilities/FormDesignConstants");
const XFormAndLayoutDesignPanel_1 = require("./Utilities/XFormAndLayoutDesignPanel");
const Topbar_1 = require("../CommonUI/BuilderUI/Topbar");
const AutoBind_1 = require("@appglue/common/dist/Common/AutoBind");
const FormContext_1 = require("./Utilities/FormContext");
const XUserFormTester_1 = require("./Utilities/XUserFormTester");
const RulesIcon_1 = require("../CommonUI/Icon/RulesIcon");
const TabletHorizontalIcon_1 = require("../CommonUI/Icon/TabletHorizontalIcon");
const TabletVerticalIcon_1 = require("../CommonUI/Icon/TabletVerticalIcon");
const CellphoneHorizontalIcon_1 = require("../CommonUI/Icon/CellphoneHorizontalIcon");
const CellphoneVerticalIcon_1 = require("../CommonUI/Icon/CellphoneVerticalIcon");
const PaperIcon_1 = require("../CommonUI/Icon/PaperIcon");
const BrushIcon_1 = require("../CommonUI/Icon/BrushIcon");
const OutlineIcon_1 = require("../CommonUI/Icon/OutlineIcon");
const NoneIcon_1 = require("../CommonUI/Icon/NoneIcon");
const Sidebar_1 = require("../CommonUI/BuilderUI/Sidebar");
const registerElements_1 = require("./registerElements");
const DataIcon_1 = require("../CommonUI/Icon/DataIcon");
const ConsentIcon_1 = require("../CommonUI/Icon/ConsentIcon");
const RuleTableIcon_1 = require("../CommonUI/Icon/RuleTableIcon");
const TestDataIcon_1 = require("../CommonUI/Icon/TestDataIcon");
const CodingIcon_1 = require("../CommonUI/Icon/CodingIcon");
const XFormRulePage_1 = require("./Builder/XFormRulePage");
const XBuilderEditPage_1 = require("../CommonUI/BuilderUI/XBuilderEditPage");
const XExecutableTester_1 = require("../CommonUI/Testing/XExecutableTester");
const ExecutionData_1 = require("@appglue/common/dist/Common/Data/ExecutionData/ExecutionData");
const DataBuilder_1 = require("../DataBuilder/DataBuilder");
class FormBuilder extends react_1.default.Component {
    formName = "";
    // this is either designer or runtime form
    editContext;
    tabs = [];
    designConfig = this.getDefaultDesignConfig();
    runtimeConfig = this.getDefaultRuntimeConfig();
    constructor(props) {
        super(props);
        // ensure controls are registered.
        registerElements_1.RegisterFormElements.doRegistration();
        this.editContext = this.setupProps(props);
        this.state = {
            mode: FormDesignConstants_1.FormMode.FormDesign,
            isJsonEditing: false,
            nextMode: FormDesignConstants_1.FormMode.FormDesign,
        };
        if (props.dataDefinition) {
            props.form.inputData = props.dataDefinition;
        }
    }
    componentDidUpdate(prevProps) {
        if (this.props.form !== prevProps.form) {
            this.editContext = this.setupProps(this.props);
            this.setState({
                mode: FormDesignConstants_1.FormMode.FormDesign,
                isJsonEditing: false,
                nextMode: FormDesignConstants_1.FormMode.FormDesign,
            });
        }
        else {
            if (this.props.formData !== prevProps.formData) {
                this.editContext.setFormData(this.props.formData ? this.props.formData : new ExecutionData_1.ExecutionData());
            }
            if (this.props.formName !== prevProps.formName)
                this.editContext.formName = this.props.formName;
            if (this.props.designValidationProvider !== prevProps.designValidationProvider)
                this.editContext.designValidationProvider = this.props.designValidationProvider;
            if (this.props.onFormClose !== prevProps.onFormClose)
                this.editContext.onFormClose = this.props.onFormClose;
            if (this.props.onFormSave !== prevProps.onFormSave)
                this.editContext.onFormSave = this.props.onFormSave;
            if (this.props.sampleDataProvider !== prevProps.sampleDataProvider)
                this.editContext.sampleDataProvider = this.props.sampleDataProvider;
            if (this.props.topDesignerExtensions !== prevProps.topDesignerExtensions)
                this.editContext.topDesignerExtensions = this.props.topDesignerExtensions;
            if (this.props.bottomDesignerExtensions !== prevProps.bottomDesignerExtensions)
                this.editContext.bottomDesignerExtensions = this.props.bottomDesignerExtensions;
            if (this.props.designConfig !== prevProps.designConfig)
                this.editContext.designConfig = this.props.designConfig;
            if (this.editContext.designConfig?.data === FormDesignConstants_1.FormDesignConstants.FORM_DATA_MODE_CURRENT) {
                this.editContext.data = new ExecutionData_1.ExecutionData(this.editContext.getFormData().values);
            }
            const { topDesignerExtensions, bottomDesignerExtensions } = this.props;
            if (topDesignerExtensions !== prevProps.topDesignerExtensions ||
                bottomDesignerExtensions !== prevProps.bottomDesignerExtensions) {
                this.tabs = this.getDefaultTabs();
                if (topDesignerExtensions) {
                    this.tabs.splice(0, 0, ...(topDesignerExtensions || []).map((d) => ({
                        icon: d.icon,
                        label: d.name,
                        value: d.name,
                        renderUI: d.renderUI,
                    })));
                }
                if (bottomDesignerExtensions) {
                    this.tabs = [
                        ...this.tabs,
                        ...(bottomDesignerExtensions || []).map((d) => ({
                            icon: d.icon,
                            label: d.name,
                            value: d.name,
                            renderUI: d.renderUI,
                        })),
                    ];
                }
            }
        }
        if (this.props.formName !== prevProps.formName)
            this.formName = this.props.formName || "";
        // set for data definition
        if (this.props.dataDefinition !== prevProps.dataDefinition && this.props.dataDefinition) {
            this.props.form.inputData = this.props.dataDefinition;
        }
    }
    setupProps(props) {
        let eContext = new FormContext_1.FormContext(props.form);
        eContext.designer = this;
        if (props.formData)
            eContext.setFormData(props.formData);
        eContext.formName = props.formName;
        eContext.designValidationProvider = props.designValidationProvider;
        eContext.onFormClose = props.onFormClose;
        eContext.onFormSave = props.onFormSave;
        eContext.sampleDataProvider = props.sampleDataProvider;
        eContext.topDesignerExtensions = props.topDesignerExtensions;
        eContext.bottomDesignerExtensions = props.bottomDesignerExtensions;
        eContext.designConfig = props.designConfig || this.getDefaultDesignConfig();
        if (eContext.designConfig.data === FormDesignConstants_1.FormDesignConstants.FORM_DATA_MODE_CURRENT) {
            const data = this.getDefaultData(props.form);
            eContext.data.values = data;
        }
        else if (eContext.designConfig.data === FormDesignConstants_1.FormDesignConstants.FORM_DATA_MODE_NONE) {
            eContext.data.values = {};
        }
        if (props.initialMode) {
            eContext.mode = props.initialMode;
        }
        this.editContext = eContext;
        this.props.form.setFormContext(eContext);
        if (props.formName) {
            this.formName = props.formName;
        }
        this.tabs = this.getDefaultTabs();
        const { topDesignerExtensions, bottomDesignerExtensions } = props;
        if (topDesignerExtensions) {
            this.tabs.splice(0, 0, ...topDesignerExtensions.map((d) => ({
                icon: d.icon,
                label: d.name,
                value: d.name,
                renderUI: d.renderUI,
            })));
        }
        if (bottomDesignerExtensions) {
            this.tabs = [
                ...this.tabs,
                ...bottomDesignerExtensions.map((d) => ({
                    icon: d.icon,
                    label: d.name,
                    value: d.name,
                    renderUI: d.renderUI,
                })),
            ];
        }
        return eContext;
    }
    getDefaultTabs() {
        return [
            {
                label: "Layout",
                icon: (0, jsx_runtime_1.jsx)(RuleTableIcon_1.RuleTableIcon, {}),
                value: FormDesignConstants_1.FormMode.LayoutDesign,
                renderUI: () => (0, jsx_runtime_1.jsx)(XFormAndLayoutDesignPanel_1.XFormAndLayoutDesignPanel, { editContext: this.editContext }),
            },
            {
                label: "Form",
                icon: (0, jsx_runtime_1.jsx)(ConsentIcon_1.ConsentIcon, {}),
                value: FormDesignConstants_1.FormMode.FormDesign,
                renderUI: () => (0, jsx_runtime_1.jsx)(XFormAndLayoutDesignPanel_1.XFormAndLayoutDesignPanel, { editContext: this.editContext }),
            },
            {
                label: "Test Form",
                icon: (0, jsx_runtime_1.jsx)(TestDataIcon_1.TestDataIcon, {}),
                value: FormDesignConstants_1.FormMode.Runtime,
                renderUI: () => (0, jsx_runtime_1.jsx)(XUserFormTester_1.XUserFormTester, { editContext: this.editContext }),
            },
            {
                label: "Test",
                icon: (0, jsx_runtime_1.jsx)(TestDataIcon_1.TestDataIcon, {}),
                value: FormDesignConstants_1.FormMode.Test,
                renderUI: () => ((0, jsx_runtime_1.jsx)(XExecutableTester_1.XExecutableTester, { saveUnitTest: this.props.saveUnitTest, builderName: "Test", executable: this.props.form })),
            },
            {
                label: "Edit Configuration",
                icon: (0, jsx_runtime_1.jsx)(CodingIcon_1.CodingIcon, {}),
                value: FormDesignConstants_1.FormMode.JSON,
                renderUI: () => (0, jsx_runtime_1.jsx)(XBuilderEditPage_1.XBuilderEditPage, { builder: this.props.form, updateCallback: () => { } }),
            },
            {
                label: "Data",
                icon: (0, jsx_runtime_1.jsx)(DataIcon_1.DataIcon, {}),
                value: FormDesignConstants_1.FormMode.Data,
                renderUI: () => ((0, jsx_runtime_1.jsx)(DataBuilder_1.DataBuilder, { definition: this.props.form.getInputDefinition(), readOnly: !this.props.form.canChangeInputs })),
            },
            {
                label: "Rules",
                icon: (0, jsx_runtime_1.jsx)(RulesIcon_1.RulesIcon, {}),
                value: FormDesignConstants_1.FormMode.Rules,
                renderUI: () => (0, jsx_runtime_1.jsx)(XFormRulePage_1.XFormRulePage, { form: this.props.form }),
            },
        ];
    }
    // form events.
    onFormSave() {
        // Save Action
        this.editContext.onFormSave(this.editContext.getFormData());
        // form Name update
        if (this.editContext.formName) {
            this.formName = this.editContext.formName;
            if (this.props.onFormNameUpdate) {
                this.props.onFormNameUpdate(this.editContext.formName);
            }
        }
    }
    onFormClose() {
        // Cancel Action
        this.editContext.onClose();
        // reset form name on cancel action
        this.formName = this.editContext.formName = this.props.formName || "";
    }
    onCopy() { }
    onCut() { }
    onDelete() { }
    getDefaultDesignConfig() {
        return {
            data: FormDesignConstants_1.FormDesignConstants.FORM_DATA_MODE_CURRENT,
            mode: FormDesignConstants_1.FormDesignConstants.FORM_MODE_PAPER,
        };
    }
    getDefaultRuntimeConfig() {
        return {
            data: FormDesignConstants_1.FormDesignConstants.FORM_DATA_MODE_CURRENT,
            mode: FormDesignConstants_1.FormDesignConstants.FORM_MODE_PAPER,
        };
    }
    getDefaultData(form) {
        let dataDef = form.getInputDefinition();
        const data = dataDef.getValueObject() || {};
        return data;
    }
    handleModeChange(mode) {
        if (this.state.mode === FormDesignConstants_1.FormMode.Runtime) {
            this.editContext.designConfig = this.runtimeConfig;
        }
        else {
            this.editContext.designConfig = this.designConfig;
        }
        if (this.state.mode !== FormDesignConstants_1.FormMode.JSON || !this.state.isJsonEditing) {
            this.editContext.mode = mode;
            this.setState({ mode, nextMode: mode });
        }
        else {
            this.setState({ nextMode: mode });
        }
    }
    onJsonEditing = (isJsonEditing) => {
        this.setState({
            isJsonEditing,
        });
    };
    onNextMode = (isLeaving) => {
        if (isLeaving) {
            this.editContext.mode = this.state.nextMode;
            this.setState({
                mode: this.state.nextMode,
            });
        }
        else {
            this.setState({
                nextMode: this.state.mode,
            });
        }
    };
    onChangeSampleData(value) {
        let des = this.editContext.designConfig;
        if (des) {
            des.data = value;
            if (value === FormDesignConstants_1.FormDesignConstants.FORM_DATA_MODE_NONE) {
                this.editContext.data.values = {};
            }
            else if (value === FormDesignConstants_1.FormDesignConstants.FORM_DATA_MODE_CURRENT) {
                const data = this.getDefaultData(this.props.form);
                this.editContext.data.values = {
                    ...data,
                };
            }
            this.forceUpdate();
        }
    }
    onUpdateDisplayMode(value) {
        let des = this.editContext.designConfig?.mode;
        if (des !== value && this.editContext.designConfig) {
            Reflect.set(this.editContext.designConfig, "mode", value);
            this.forceUpdate();
        }
    }
    onChangeFormName(newTitle) {
        let des = this.editContext;
        if (des) {
            des.formName = newTitle;
            if (this.editContext.refreshDesigner)
                this.editContext.refreshDesigner();
        }
        if (this.props.onFormNameUpdate) {
            this.props.onFormNameUpdate(newTitle);
        }
    }
    render() {
        return ((0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100vh", overflow: "hidden" }, "data-testid": "FormDesigner", children: [(0, jsx_runtime_1.jsx)(Topbar_1.Topbar, { name: this.editContext.formName, onChangeName: this.onChangeFormName, editContext: this.editContext, isActionDisabled: !(this.editContext.mode === FormDesignConstants_1.FormMode.FormDesign ||
                        this.editContext.mode === FormDesignConstants_1.FormMode.LayoutDesign) || !this.editContext.lastSelectionElement, isRequiredActionGroup: this.editContext.mode !== FormDesignConstants_1.FormMode.Runtime, onSave: this.props.onFormSave, onClose: this.props.onFormClose, prevItems: [
                        {
                            label: "Show Data",
                            items: FormDesignConstants_1.FormDesignConstants.FORM_DATA_MODE.map((m) => ({
                                value: m,
                            })),
                            value: this.editContext.designConfig?.data || "",
                            onSelect: this.onChangeSampleData,
                            type: Topbar_1.IInjectTopItemType.SELECT,
                        },
                        {
                            label: "Display Format",
                            value: this.editContext.designConfig?.mode || "",
                            items: [
                                {
                                    label: "Paper",
                                    icon: (0, jsx_runtime_1.jsx)(PaperIcon_1.PaperIcon, { alt: FormDesignConstants_1.FormDesignConstants.FORM_MODE_PAPER }),
                                },
                                {
                                    label: "Gray",
                                    icon: (0, jsx_runtime_1.jsx)(BrushIcon_1.BrushIcon, { alt: FormDesignConstants_1.FormDesignConstants.FORM_MODE_GRAY }),
                                },
                                {
                                    label: "Outline",
                                    icon: (0, jsx_runtime_1.jsx)(OutlineIcon_1.OutlineIcon, { alt: FormDesignConstants_1.FormDesignConstants.FORM_MODE_OUTLINE }),
                                },
                                {
                                    label: "White",
                                    icon: (0, jsx_runtime_1.jsx)(NoneIcon_1.NoneIcon, { alt: FormDesignConstants_1.FormDesignConstants.FORM_MODE_WHITE }),
                                },
                                {
                                    label: FormDesignConstants_1.FormDesignConstants.FORM_MODE_TABLET_HORIZONTAL,
                                    icon: ((0, jsx_runtime_1.jsx)(TabletHorizontalIcon_1.TabletHorizontalIcon, { alt: FormDesignConstants_1.FormDesignConstants.FORM_MODE_TABLET_HORIZONTAL })),
                                },
                                {
                                    label: FormDesignConstants_1.FormDesignConstants.FORM_MODE_TABLET_VERTICAL,
                                    icon: (0, jsx_runtime_1.jsx)(TabletVerticalIcon_1.TabletVerticalIcon, { alt: FormDesignConstants_1.FormDesignConstants.FORM_MODE_TABLET_VERTICAL }),
                                },
                                {
                                    label: FormDesignConstants_1.FormDesignConstants.FORM_MODE_PHONE_HORIZONTAL,
                                    icon: ((0, jsx_runtime_1.jsx)(CellphoneHorizontalIcon_1.CellphoneHorizontalIcon, { alt: FormDesignConstants_1.FormDesignConstants.FORM_MODE_PHONE_HORIZONTAL })),
                                },
                                {
                                    label: FormDesignConstants_1.FormDesignConstants.FORM_MODE_PHONE_VERTICAL,
                                    icon: (0, jsx_runtime_1.jsx)(CellphoneVerticalIcon_1.CellphoneVerticalIcon, { alt: FormDesignConstants_1.FormDesignConstants.FORM_MODE_PHONE_VERTICAL }),
                                },
                            ],
                            onSelect: this.onUpdateDisplayMode,
                            type: Topbar_1.IInjectTopItemType.ICONBUTTONGROUP,
                            wrapperStyle: { marginRight: this.editContext.mode === FormDesignConstants_1.FormMode.Runtime ? "auto" : 0 },
                        },
                    ] }), (0, jsx_runtime_1.jsx)(Sidebar_1.Sidebar, { items: this.tabs, value: this.editContext.mode, onChange: this.handleModeChange })] }));
    }
}
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "setupProps", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "onFormSave", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "onFormClose", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "onCopy", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "onCut", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "onDelete", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "handleModeChange", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "onChangeSampleData", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "onUpdateDisplayMode", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], FormBuilder.prototype, "onChangeFormName", null);
exports.FormBuilder = FormBuilder;
//# sourceMappingURL=FormBuilder.js.map