import { __decorate, __metadata } from "tslib";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { Collapse } from "@material-ui/core";
import React from "react";
import { Droppable } from "react-beautiful-dnd";
import styled from "styled-components";
import { AutoBind } from "../../Common/AutoBind";
import { StyledButton } from "../../CommonUI/Components/Button";
import { PropertyEditorBoolean } from "../../CommonUI/PropertyEditing/PropertyEditorBoolean";
import { PropertyEditorColor } from "../../CommonUI/PropertyEditing/PropertyEditorColor";
import { PropertyEditorInteger } from "../../CommonUI/PropertyEditing/PropertyEditorInteger";
import { PropertyEditorOptionWithButtonGroup } from "../../CommonUI/PropertyEditing/PropertyEditorOptionWithButtonGroup";
import { PropertyEditorSelect } from "../../CommonUI/PropertyEditing/PropertyEditorSelect";
import { XBaseControl } from "../Controls/XBaseControl";
import { ChildFullWidthDiv } from "../Controls/XCommonStyled";
import { FormDesignConstants, FormMode } from "../FormDesignConstants";
import { DefaultOffOverride } from "../Utilities/DefaultOffOverride";
import { XDesignWrapper } from "../Utilities/XDesignWrapper";
import { XRuntimeWrapper } from "../Utilities/XRuntimeWrapper";
import { XBaseContainer } from "./XBaseContainer";
import { XBaseStackContainer } from "./XBaseStackContainer";
import { XGridEditLayer } from "./XGridEditLayer";
import { StackContainerColumn, StackContainerDiv } from "./XStackContainer";
export class XGridRow extends XBaseControl {
    constructor() {
        super(...arguments);
        this.onControlUpdate = () => { };
    }
    getDesignValidationIssues() {
        return [];
    }
    getRuntimeValidationIssues() {
        return [];
    }
    getAddedData() {
        return;
    }
    renderEditUI() {
        return (_jsx(_Fragment, { children: _jsx(PropertyEditorInteger, { editObject: this, propertyName: "height", label: "Height", updateCallback: this.onControlUpdate }, void 0) }, void 0));
    }
}
export class XGridArea extends XBaseStackContainer {
    constructor(row, column, width = 1, height = 1) {
        super();
        this.width = 1;
        this.height = 1;
        this.controls = [];
        this.oneControl = false;
        this.backgroundColorSettings = DefaultOffOverride.DEFAULT;
        this.innerMarginSettings = DefaultOffOverride.DEFAULT;
        this.formBorderSettings = DefaultOffOverride.DEFAULT;
        this.controlAlign = {};
        this.onControlUpdate = () => { };
        this.onSelect = (event) => {
            var _a, _b;
            event.preventDefault();
            let mode = (_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : FormMode.Runtime;
            if (mode === FormMode.LayoutDesign) {
                this.selectInDesigner();
            }
        };
        this.row = row;
        this.column = column;
        this.width = width;
        this.height = height;
    }
    add(control, index) {
        if (this.oneControl && this.controls.length === 1) {
            return;
        }
        // set control order
        if (index === undefined || index === null) {
            this.controls.push(control);
        }
        else {
            this.controls.splice(index, 0, control);
        }
        if (this.getFormContext())
            control.setFormContext(this.getFormContext());
    }
    backgroundColor() {
        var _a;
        return ((this.backgroundColorSettings === DefaultOffOverride.Override && this.containerBackgroundColor) || ((_a = this.container) === null || _a === void 0 ? void 0 : _a.defaultAreaBackgroundColor) ||
            super.backgroundColor());
    }
    hasOwnBorder() {
        return this.formBorderSettings === DefaultOffOverride.Override;
    }
    hasBorder() {
        var _a, _b;
        return (this.hasOwnBorder() ||
            (this.formBorderSettings === DefaultOffOverride.DEFAULT && ((_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.defaultShowContainerBorder)));
    }
    borderColor() {
        var _a;
        return ((this.hasOwnBorder() && this.containerBorderColor) || ((_a = this.container) === null || _a === void 0 ? void 0 : _a.defaultAreaBorderColor) ||
            super.borderColor());
    }
    borderStyle() {
        var _a;
        return ((this.hasOwnBorder() && this.containerBorderStyle) || ((_a = this.container) === null || _a === void 0 ? void 0 : _a.defaultAreaBorderStyle) ||
            super.borderStyle());
    }
    borderWidth() {
        var _a;
        return ((this.hasOwnBorder() && this.containerBorderWidth) || ((_a = this.container) === null || _a === void 0 ? void 0 : _a.defaultAreaBorderWidth) ||
            super.borderWidth());
    }
    borderRadius() {
        var _a;
        return ((this.hasOwnBorder() && this.containerBorderRadius) || ((_a = this.container) === null || _a === void 0 ? void 0 : _a.defaultAreaBorderRadius) ||
            super.borderRadius());
    }
    getInnerMargin() {
        var _a;
        return ((this.innerMarginSettings === DefaultOffOverride.Override && this.innerMargin) || ((_a = this.container) === null || _a === void 0 ? void 0 : _a.defaultAreaInnerMargin));
    }
    renderEditUI() {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
        return (_jsxs(_Fragment, { children: [_jsx(PropertyEditorInteger, { editObject: this, propertyName: "row", label: "Row Index", updateCallback: this.onControlUpdate, min: 0, max: ((_a = this.container) === null || _a === void 0 ? void 0 : _a.rowsLength) ? ((_b = this.container) === null || _b === void 0 ? void 0 : _b.rowsLength) - this.height : undefined, hint: `max value: ${((_c = this.container) === null || _c === void 0 ? void 0 : _c.rowsLength) ? ((_d = this.container) === null || _d === void 0 ? void 0 : _d.rowsLength) - this.height : undefined}` }, void 0),
                _jsx(PropertyEditorInteger, { editObject: this, propertyName: "column", label: "Column Index", updateCallback: this.onControlUpdate, min: 0, max: (((_e = this.container) === null || _e === void 0 ? void 0 : _e.columnsLength) || 12) - this.width, hint: `max value: ${(((_f = this.container) === null || _f === void 0 ? void 0 : _f.columnsLength) || 12) - this.width}` }, void 0),
                _jsx(PropertyEditorInteger, { editObject: this, propertyName: "width", label: "Width", updateCallback: this.onControlUpdate, min: 1, max: (((_g = this.container) === null || _g === void 0 ? void 0 : _g.columnsLength) || 12) - this.column, hint: `max value: ${(((_h = this.container) === null || _h === void 0 ? void 0 : _h.columnsLength) || 12) - this.column}` }, void 0),
                _jsx(PropertyEditorInteger, { editObject: this, propertyName: "height", label: "Height", updateCallback: this.onControlUpdate, max: ((_j = this.container) === null || _j === void 0 ? void 0 : _j.rowsLength) ? ((_k = this.container) === null || _k === void 0 ? void 0 : _k.rowsLength) - this.row : undefined, hint: `max value: ${((_l = this.container) === null || _l === void 0 ? void 0 : _l.rowsLength) ? ((_m = this.container) === null || _m === void 0 ? void 0 : _m.rowsLength) - this.row : undefined}` }, void 0),
                _jsx(PropertyEditorOptionWithButtonGroup, { editObject: this, label: "Border", propertyName: "formBorderSettings", updateCallback: this.onControlUpdate, options: [DefaultOffOverride.DEFAULT, DefaultOffOverride.Off, DefaultOffOverride.Override] }, void 0),
                _jsx(Collapse, Object.assign({ in: this.formBorderSettings === DefaultOffOverride.Override }, { children: _jsxs(ChildFullWidthDiv, { children: [_jsx(PropertyEditorInteger, { editObject: this, label: "Border Width", propertyName: "containerBorderWidth", updateCallback: this.controlUpdate, parentDefaultValue: (_o = this.getFormContext()) === null || _o === void 0 ? void 0 : _o.form.defaultContainerBorderWidth }, void 0),
                            _jsx(PropertyEditorInteger, { editObject: this, label: "Border Radius", propertyName: "containerBorderRadius", updateCallback: this.controlUpdate, parentDefaultValue: (_q = (_p = this.getFormContext()) === null || _p === void 0 ? void 0 : _p.form) === null || _q === void 0 ? void 0 : _q.defaultContainerBorderRadius }, void 0),
                            _jsx(PropertyEditorColor, { editObject: this, label: "Border Color", propertyName: "containerBorderColor", updateCallback: this.controlUpdate, parentDefaultValue: (_s = (_r = this.getFormContext()) === null || _r === void 0 ? void 0 : _r.form) === null || _s === void 0 ? void 0 : _s.defaultContainerBorderColor }, void 0),
                            _jsx(PropertyEditorSelect, { editObject: this, label: "Border Style", propertyName: "containerBorderStyle", updateCallback: this.controlUpdate, options: FormDesignConstants.BORDER_STYLES, parentDefaultValue: (_u = (_t = this.getFormContext()) === null || _t === void 0 ? void 0 : _t.form) === null || _u === void 0 ? void 0 : _u.defaultContainerBorderStyle }, void 0)] }, void 0) }), void 0),
                _jsx(PropertyEditorOptionWithButtonGroup, { editObject: this, propertyName: "innerMarginSettings", label: "Inner Margin", updateCallback: this.onControlUpdate, options: [DefaultOffOverride.DEFAULT, DefaultOffOverride.Off, DefaultOffOverride.Override], color: "primary" }, void 0),
                _jsx(Collapse, Object.assign({ in: this.innerMarginSettings === DefaultOffOverride.Override }, { children: _jsx(PropertyEditorInteger, { editObject: this, propertyName: "innerMargin", label: "Area Inner Margin", updateCallback: this.onControlUpdate }, void 0) }), void 0),
                _jsx(PropertyEditorOptionWithButtonGroup, { editObject: this, propertyName: "backgroundColorSettings", label: "Background Color", updateCallback: this.onControlUpdate, options: [DefaultOffOverride.DEFAULT, DefaultOffOverride.Off, DefaultOffOverride.Override], color: "primary" }, void 0),
                _jsx(Collapse, Object.assign({ in: this.backgroundColorSettings === DefaultOffOverride.Override }, { children: _jsx(PropertyEditorColor, { editObject: this, propertyName: "containerBackgroundColor", label: "Content Background Color", updateCallback: this.onControlUpdate }, void 0) }), void 0),
                _jsx(PropertyEditorBoolean, { editObject: this, propertyName: "oneControl", label: "Single Control?", updateCallback: this.onControlUpdate }, void 0),
                _jsx(Collapse, Object.assign({ in: this.oneControl }, { children: _jsxs(ChildFullWidthDiv, { children: [_jsx(PropertyEditorInteger, { editObject: this.controlAlign, propertyName: "top", label: "Top", updateCallback: this.onControlUpdate }, void 0),
                            _jsx(PropertyEditorInteger, { editObject: this.controlAlign, propertyName: "Left", label: "Left", updateCallback: this.onControlUpdate }, void 0),
                            _jsx(PropertyEditorInteger, { editObject: this.controlAlign, propertyName: "Right", label: "right", updateCallback: this.onControlUpdate }, void 0),
                            _jsx(PropertyEditorInteger, { editObject: this.controlAlign, propertyName: "bottom", label: "bottom", updateCallback: this.onControlUpdate }, void 0)] }, void 0) }), void 0)] }, void 0));
    }
    getDesignValidationIssues() {
        return [];
    }
    getRuntimeValidationIssues() {
        return [];
    }
    getAddedData() {
        return [];
    }
    render() {
        var _a, _b, _c, _d;
        let mode = (_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : FormMode.Runtime;
        let controls = this.getControls();
        if (mode === FormMode.FormDesign) {
            return (_jsxs(GridCellRender, Object.assign({ padding: this.getInnerMargin(), borderColor: this.borderColor(), borderStyle: this.borderStyle(), borderWidth: this.borderWidth(), borderRadius: this.borderRadius(), backgroundColor: this.backgroundColor(), columnSpan: this.width, columnStart: this.column, rowSpan: this.height, rowStart: this.row, "data-testid": `XGridCell-${this.row}-${this.column}` }, { children: [_jsx(Droppable, Object.assign({ droppableId: this.id, isDropDisabled: this.oneControl && controls.length >= 1 }, { children: (provided, snapShot) => {
                            return (_jsxs(StackContainerDiv, Object.assign({ ref: provided.innerRef }, provided.droppableProps, { style: {
                                    border: snapShot.isDraggingOver
                                        ? `${FormDesignConstants.DROPPABLE_BORDER_STYLE} ${FormDesignConstants.DROPPABLE_BORDER_WIDTH}px ${FormDesignConstants.DROPPABLE_BORDER_COLOR}`
                                        : "none",
                                    borderRadius: snapShot.isDraggingOver
                                        ? FormDesignConstants.DROPPABLE_BORDER_RADIUS
                                        : 0,
                                } }, { children: [this.getControls().map((control, index) => {
                                        var _a, _b;
                                        return (_jsx(StackContainerColumn, Object.assign({ colGap: this.interControlSpacing || ((_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.defaultInterControlSpacing), style: {
                                                border: snapShot.isDraggingOver
                                                    ? `${FormDesignConstants.DROPPABLE_BORDER_STYLE} ${FormDesignConstants.DROPPABLE_BORDER_WIDTH}px ${FormDesignConstants.DROPPABLE_BORDER_COLOR}`
                                                    : "none",
                                                borderRadius: snapShot.isDraggingOver
                                                    ? FormDesignConstants.DROPPABLE_BORDER_RADIUS
                                                    : 0,
                                            }, "data-testid": control.id }, { children: _jsx(XDesignWrapper, Object.assign({ id: control.id, index: index, innerComponent: control, editContext: this.getFormContext() }, { children: control.render() }), control.id) }), index));
                                    }), provided.placeholder] }), void 0));
                        } }), void 0), this.getControls().length === 0 && this.renderEmptyControlDiv()] }), void 0));
        }
        if (controls.length >= 1 && this.oneControl) {
            let control = controls[0];
            return (_jsx(GridCellRender, Object.assign({ padding: 0, borderColor: this.borderColor(), borderStyle: this.borderStyle(), borderWidth: this.borderWidth(), borderRadius: this.borderRadius(), backgroundColor: this.backgroundColor(), columnStart: this.column, columnSpan: this.width, rowStart: this.row, rowSpan: this.height, onClick: this.onSelect, "data-testid": `XGridCell-${this.row}-${this.column}` }, { children: _jsx(OneControlRender, Object.assign({ position: this.controlAlign, "data-testid": control.id }, { children: _jsx(StackContainerColumn, Object.assign({ colGap: this.interControlSpacing || ((_d = (_c = this.getFormContext()) === null || _c === void 0 ? void 0 : _c.form) === null || _d === void 0 ? void 0 : _d.defaultInterControlSpacing) }, { children: _jsx(XRuntimeWrapper, { innerComponent: control, context: this.getFormContext() }, void 0) }), void 0) }), void 0) }), void 0));
        }
        return (_jsxs(GridCellRender, Object.assign({ padding: this.getInnerMargin(), borderColor: this.borderColor(), borderStyle: this.borderStyle(), borderWidth: this.borderWidth(), borderRadius: this.borderRadius(), backgroundColor: this.backgroundColor(), columnStart: this.column, columnSpan: this.width, rowStart: this.row, rowSpan: this.height, onClick: this.onSelect, "data-testid": `XGridCell-${this.row}-${this.column}` }, { children: [controls.map((control, index) => {
                    var _a, _b;
                    return (_jsx(StackContainerColumn, Object.assign({ colGap: this.interControlSpacing || ((_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.defaultInterControlSpacing), "data-testid": control.id }, { children: _jsx(XRuntimeWrapper, { innerComponent: control, context: this.getFormContext() }, void 0) }), index));
                }), this.getControls().length === 0 && mode !== FormMode.LayoutDesign && this.renderEmptyControlDiv()] }), void 0));
    }
}
export class XGridContainer extends XBaseContainer {
    constructor() {
        super(...arguments);
        this.areas = [];
        this.rows = [new XGridRow()];
        // can not be less than 1
        this.rowsLength = 1;
        this.columnsLength = 12;
        this.gapBetweenAreas = 10;
        // area
        this.defaultAreaInnerMargin = 10;
        this.defaultShowAreaBorder = false;
        this.defaultAreaBorderColor = "lightGray";
        this.defaultAreaBorderRadius = 10;
        this.defaultAreaBorderWidth = 2;
        this.defaultAreaBackgroundColor = "#fff";
        this.showEditUIDialog = false;
    }
    remove(control) {
        if (control instanceof XGridArea) {
            this.removeArea(control);
        }
    }
    find(id) {
        for (let row of this.rows) {
            if (row.id === id)
                return row;
        }
        for (let cont of this.areas) {
            if (cont.id === id)
                return cont;
            for (let c of cont.getControls()) {
                if (c.id === id) {
                    return c;
                }
            }
        }
        return null;
    }
    setOrder(id, order) { }
    add(control, index) {
        if (control instanceof XGridArea) {
            this.addArea(control);
        }
        else if (control instanceof XGridRow) {
            this.addRow(control);
        }
    }
    getControls() {
        let controls = [...this.areas, ...this.rows];
        for (let a of this.areas) {
            controls = [...controls, ...a.getControls()];
        }
        return controls;
    }
    renderEditUI() {
        return (_jsxs(_Fragment, { children: [_jsx(StyledButton, Object.assign({ variant: "contained", color: "primary", onClick: (event) => {
                        event.stopPropagation();
                        this.showEditUIDialog = true;
                        this.controlUpdate();
                    } }, { children: "Open Edit UI" }), void 0), console.log("showEditUIDialog:", this.showEditUIDialog), this.showEditUIDialog && (_jsx(XGridEditLayer, { grid: this, updateCallback: () => {
                        this.showEditUIDialog = false;
                        this.controlUpdate();
                    } }, void 0))] }, void 0));
    }
    addArea(area) {
        area.container = this;
        if (this.getFormContext()) {
            area.setFormContext(this.getFormContext());
        }
        this.areas.push(area);
    }
    removeArea(area) {
        this.areas = this.areas.filter((a) => a.id !== area.id);
    }
    addRow(row) {
        if (this.getFormContext()) {
            row.setFormContext(this.getFormContext());
        }
        this.rows.push(row);
        this.rowsLength = this.rows.length;
    }
    removeRow(row) {
        this.rows = this.rows.filter((r) => r.id !== row.id);
    }
    render() {
        var _a, _b;
        let sortedAreas = this.areas.sort((a, b) => {
            if (a.row === b.row) {
                return a.column - b.column;
            }
            return a.row - b.row;
        });
        let mode = (_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : FormMode.Runtime;
        const rowsTemplate = this.rows
            .map((row) => (row.height ? `${row.height}px` : `minmax(75px, max-content)`))
            .join(" ");
        if (mode !== FormMode.LayoutDesign) {
            return (_jsx(GridContainerRender, Object.assign({ padding: this.getInnerMargin(), hasBorder: this.hasBorder(), borderColor: this.borderColor(), borderStyle: this.borderStyle(), borderWidth: this.borderWidth(), borderRadius: this.borderRadius(), backgroundColor: this.backgroundColor(), rowsTemplate: rowsTemplate }, { children: sortedAreas.map((area) => {
                    return _jsx(React.Fragment, { children: area.render() }, area.id);
                }) }), void 0));
        }
        return (_jsxs(GridContainerRender, Object.assign({ padding: this.getInnerMargin(), hasBorder: this.hasBorder(), borderColor: this.borderColor(), borderStyle: this.borderStyle(), borderWidth: this.borderWidth(), borderRadius: this.borderRadius(), backgroundColor: this.backgroundColor(), rowsTemplate: rowsTemplate }, { children: [sortedAreas.map((area) => {
                    return _jsx(React.Fragment, { children: area.render() }, area.id);
                }),
                sortedAreas.length === 0 && _jsx(PlaceholderGrid, { children: "Grid Layout Not Configured" }, void 0)] }), void 0));
    }
    getInnerMargin() {
        var _a, _b;
        return this.innerMargin || ((_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.defaultInnerContainerMargin);
    }
}
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [XGridArea]),
    __metadata("design:returntype", void 0)
], XGridContainer.prototype, "addArea", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [XGridArea]),
    __metadata("design:returntype", void 0)
], XGridContainer.prototype, "removeArea", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [XGridRow]),
    __metadata("design:returntype", void 0)
], XGridContainer.prototype, "addRow", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [XGridRow]),
    __metadata("design:returntype", void 0)
], XGridContainer.prototype, "removeRow", null);
export const GridContainerRender = styled.div `
    min-height: ${(props) => (props.padding || 0) + 75}px;
    width: 100%;

    display: grid;

    grid-template-columns: repeat(12, 1fr);
    grid-template-rows: ${(props) => props.rowsTemplate};

    padding: ${(props) => props.padding || 0}px;
    border: ${(props) => props.hasBorder
    ? `${(props.borderStyle || FormDesignConstants.CONTAINER_BORDER_STYLE).toLowerCase()} ${props.borderWidth || FormDesignConstants.CONTAINER_BORDER_COLOR}px ${props.borderColor || FormDesignConstants.CONTAINER_BORDER_COLOR}`
    : "none"};
    border-radius: ${(props) => props.borderRadius || FormDesignConstants.CONTAINER_BORDER_RADIOUS}px;

    background-color: ${(props) => props.backgroundColor || FormDesignConstants.CONTAINER_BACKGROUND_COLOR};
    position: relative;

    column-gap: ${(props) => props.gapBetweenAreas || 5}px;
    row-gap: ${(props) => props.gapBetweenAreas || 5}px;
`;
export const GridCellRender = styled.div `
    display: flex;
    flex-direction: column;
    position: relative;
    padding: ${(props) => props.padding || 0}px;
    min-height: 72px;
    height: 100%;
    overflow: auto;

    ${(props) => (props.height !== undefined ? `max-height: ${props.height}px; overflow: auto;` : ``)}

    border: ${(props) => `${props.borderStyle} ${props.borderWidth}px ${props.borderColor}`};
    border-radius: ${(props) => props.borderRadius}px;
    background-color: ${(props) => props.backgroundColor || FormDesignConstants.CONTAINER_BACKGROUND_COLOR};

    grid-column: ${(props) => props.columnStart + 1} / span ${(props) => props.columnSpan};
    grid-row-start: ${(props) => props.rowStart + 1};
    grid-row-end: ${(props) => (props.rowSpan !== undefined ? props.rowStart + 1 + props.rowSpan : props.rowStart + 2)};
`;
const OneControlRender = styled.div `
    position: absolute;

    ${(props) => props.position.top !== undefined ||
    props.position.left !== undefined ||
    props.position.bottom !== undefined ||
    props.position.right !== undefined
    ? `
                top: ${props.position.top || 0}px;
                left: ${props.position.left || 0}px;
                right: ${props.position.right || 0}px;
                bottom: ${props.position.bottom || 0}px;
            `
    : `
                top: 50%;
                left: 50%;
                transform: translateY(-50%) translateX(-50%);

            `}
`;
const PlaceholderGrid = styled.span `
    grid-column: 1 / span 12;
    grid-row: 1 / span 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px dashed #677c95;
    border-radius: 5px;
`;
//# sourceMappingURL=XGridContainer.js.map