import { __decorate, __metadata } from "tslib";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import styled from "styled-components";
import { XBaseContainer } from "./XBaseContainer";
import { FormMode, FormDesignConstants, TabOrientation } from "../FormDesignConstants";
import { PropertyEditorInteger } from "../../CommonUI/PropertyEditing/PropertyEditorInteger";
import { PropertyEditorColor } from "../../CommonUI/PropertyEditing/PropertyEditorColor";
import { XBaseControl } from "../Controls/XBaseControl";
import Tab from "@material-ui/core/Tab";
import { Droppable } from "react-beautiful-dnd";
import { TabPanel, TabContext, TabList } from "@material-ui/lab";
import { AutoBind } from "../../Common/AutoBind";
import { StateManager } from "../../CommonUI/StateManagement/StateManager";
import { ObserveState } from "../../CommonUI/StateManagement/ObserveState";
import { DataUtilities } from "../../Common/DataUtilities";
import { XBaseStackContainer } from "./XBaseStackContainer";
import { StackContainerDiv, StackContainerColumn } from "./XStackContainer";
import { XDesignWrapper } from "../Utilities/XDesignWrapper";
import { PropertyEditorSelect } from "../../CommonUI/PropertyEditing/PropertyEditorSelect";
import { ChildFullWidthDiv } from "../Controls/XCommonStyled";
import { Collapse } from "@material-ui/core";
import { DefaultOnOff } from "../Utilities/DefaultOnOff";
import { PropertyEditorList } from "../../CommonUI/PropertyEditing/PropertyEditorList";
import { PropertyEditorBoolean } from "../../CommonUI/PropertyEditing/PropertyEditorBoolean";
import { PropertyEditorText } from "../../CommonUI/PropertyEditing/PropertyEditorText";
import { PropertyEditorOptionWithButtonGroup } from "../../CommonUI/PropertyEditing/PropertyEditorOptionWithButtonGroup";
import { XRuntimeWrapper } from "../Utilities/XRuntimeWrapper";
const StyledTab = styled(Tab) `
    && {
        padding: 0;
    }
`;
const TabContainerWrapper = styled("div") `
    width: 100%;
    padding: ${(props) => props.padding || 0}px;
    min-height: ${(props) => (props.padding || 0) * 2 + (props.minHeight || 75)}px;
    border: ${(props) => props.hasBorder
    ? `${(props.borderStyle || FormDesignConstants.CONTAINER_BORDER_STYLE).toLowerCase()} ${props.borderWidth || FormDesignConstants.CONTAINER_BORDER_WIDTH}px ${props.borderColor || FormDesignConstants.CONTAINER_BORDER_COLOR}`
    : "none"};
    border-radius: ${(props) => props.borderRadius || FormDesignConstants.CONTAINER_BORDER_RADIOUS}px;
    // overflow: hidden;
    background-color: ${(props) => props.backgroundColor || FormDesignConstants.CONTAINER_BACKGROUND_COLOR};
    position: relative;

    ${(props) => props.orientation === TabOrientation.Veritical &&
    `
		display: flex;
	`}
`;
const TabHeaderWrapper = styled("div") `
    padding: ${(props) => props.padding || 0}px;
    border: ${(props) => props.hasBorder ? `${props.borderStyle.toLowerCase()} ${props.borderWidth}px ${props.borderColor}` : "none"};
    border-radius: ${(props) => props.borderRadius || 0}px;
`;
const StyledTabPanel = styled(TabPanel) `
    && {
        padding: 0;
    }
`;
export class XTabContainerTabHeader {
    constructor() {
        this.icon = null;
        this.title = "";
    }
    getStorageData() {
        return DataUtilities.cloneWithoutReact(this, ["tab"]);
    }
    setStorageData(data) {
        DataUtilities.spreadData(this, data, []);
    }
}
export class XTabContainerTabContent extends XBaseStackContainer {
    setFormContext(value) {
        if (!value)
            throw new Error("cannot set edit context to null (base control)");
        super.setFormContext(value);
        for (let c of this.controls) {
            c.setFormContext(value);
        }
    }
    getFormMode() {
        return this.getFormContext().mode || FormMode.Runtime;
    }
    getStorageData() {
        let retData = DataUtilities.cloneWithoutReact(this, ["container", "form", "controls", "_formContext", "tab"]);
        Reflect.set(retData, "__controls", this.controls.map((c) => {
            return c.getStorageData();
        }));
        return retData;
    }
    getInnerControlSpacing() {
        return this.getContainer().interControlSpacing;
    }
    getContainer() {
        return this.tab.container;
    }
    hasOwnBorder() {
        return this.overrideFormBorderSettings === DefaultOnOff.On;
    }
    hasBorder() {
        return (this.hasOwnBorder() ||
            (this.overrideFormBorderSettings === DefaultOnOff.DEFAULT && this.getContainer().defaultShowContentBorder));
    }
    borderColor() {
        return (this.hasOwnBorder() && this.contentBorderColor) || this.getContainer().defaultContentBorderColor;
    }
    borderStyle() {
        return (this.hasOwnBorder() && this.contentBorderStyle) || this.getContainer().defaultContentBorderStyle;
    }
    borderWidth() {
        return (this.hasOwnBorder() && this.contentBorderWidth) || this.getContainer().defaultContentBorderWidth;
    }
    borderRadius() {
        return (this.hasOwnBorder() && this.contentBorderRadius) || this.getContainer().defaultContentBorderRadius;
    }
    backgroundColor() {
        return this.contentBackgroundColor || this.getContainer().defaultTabContentBackground;
    }
    getInnerMargin() {
        return this.innerMargin || this.getContainer().defaultTabContentInnerMargin;
    }
    render() {
        var _a, _b;
        let mode = (_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : FormMode.Runtime;
        if (mode === FormMode.FormDesign) {
            return (_jsx(Droppable, Object.assign({ droppableId: this.id }, { children: (provided, snapshot) => {
                    return (_jsxs(StackContainerDiv, Object.assign({ padding: this.getInnerMargin(), hasBorder: snapshot.isDraggingOver || this.hasBorder(), borderColor: (snapshot.isDraggingOver && FormDesignConstants.DROPPABLE_BORDER_COLOR) ||
                            this.borderColor(), borderStyle: (snapshot.isDraggingOver && FormDesignConstants.DROPPABLE_BORDER_STYLE) ||
                            this.borderStyle(), borderWidth: (snapshot.isDraggingOver && FormDesignConstants.DROPPABLE_BORDER_WIDTH) ||
                            this.borderWidth(), borderRadius: (snapshot.isDraggingOver && FormDesignConstants.DROPPABLE_BORDER_RADIUS) ||
                            this.borderRadius(), backgroundColor: this.backgroundColor(), ref: provided.innerRef }, provided.droppableProps, { children: [this.controls.map((control, index) => {
                                var _a, _b;
                                return (_jsx(StackContainerColumn, Object.assign({ colGap: this.getInnerControlSpacing() || ((_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.defaultInterControlSpacing), id: 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, this.controls.length === 0 && this.renderEmptyControlDiv(this.getInnerMargin())] }), void 0));
                } }), this.id));
        }
        else {
            return (_jsxs(StackContainerDiv, Object.assign({ padding: this.getInnerMargin(), hasBorder: this.hasBorder(), borderColor: this.borderColor(), borderStyle: this.borderStyle(), borderWidth: this.borderWidth(), borderRadius: this.borderRadius(), backgroundColor: this.backgroundColor() }, { children: [this.controls.map((control, index) => {
                        var _a, _b;
                        return (_jsx(StackContainerColumn, Object.assign({ colGap: this.getInnerControlSpacing() || ((_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.defaultInterControlSpacing), id: control.id }, { children: _jsx(XRuntimeWrapper, { innerComponent: control, context: this.getFormContext() }, void 0) }), index));
                    }), this.controls.length === 0 &&
                        mode !== FormMode.Runtime &&
                        this.renderEmptyControlDiv(this.getInnerMargin(), "Add controls in the form design tab")] }), void 0));
        }
    }
    renderEditUI() {
        throw new Error("Method not implemented.");
    }
}
export class XTabContainerTab extends XBaseControl {
    getAddedData() {
        return;
    }
    getStorageData() {
        let resData = DataUtilities.cloneWithoutReact(this, [
            "_formContext",
            "_formRuntimeContext",
            "header",
            "content",
            "container",
        ]);
        Reflect.set(resData, "__header", this.header.getStorageData());
        Reflect.set(resData, "__content", this.content.getStorageData());
        return resData;
    }
    setStorageData(data) {
        DataUtilities.spreadData(this, data, ["__header", "__content"]);
        let headerData = Reflect.get(data, "__header");
        let header = new XTabContainerTabHeader();
        header.setStorageData(headerData);
        this.setHeader(header);
        let contentData = Reflect.get(data, "__content");
        let content = new XTabContainerTabContent();
        content.setStorageData(contentData);
        this.setContent(content);
    }
    setContainer(container) {
        this.container = container;
        if (container.getFormContext()) {
            this.setFormContext(container.getFormContext());
        }
    }
    setFormContext(value) {
        if (!value)
            throw new Error("cannot set edit context to null (base control)");
        super.setFormContext(value);
        this.content.setFormContext(value);
    }
    setContent(content) {
        this.content = content;
        this.content.tab = this;
        if (this.getFormContext()) {
            content.setFormContext(this.getFormContext());
        }
    }
    setHeader(header) {
        this.header = header;
        this.header.tab = this;
    }
    find(id) {
        return this.content.find(id);
    }
    add(control, index) {
        this.content.add(control, index);
    }
    getContainer() {
        return this.container;
    }
    remove(control) {
        var _a;
        (_a = this.content) === null || _a === void 0 ? void 0 : _a.remove(control);
    }
    getControls() {
        return this.content.getControls() || [];
    }
    getDesignValidationIssues() {
        return [];
    }
    getRuntimeValidationIssues() {
        return [];
    }
    renderEditUI() {
        return null;
    }
}
export class XTabContainer extends XBaseContainer {
    constructor() {
        super(...arguments);
        this.orientation = TabOrientation.Horizontal;
        this.tabs = [];
        this.selectedValue = "";
        this.innerMargin = 0;
        this.innerMarginTabHeader = 0;
        this.minWidthPxTabHeader = 0;
        this.fullWidth = false;
        this.centered = false;
        this.defaultTabContentHeight = null;
        this.defaultTabContentWidth = null;
        this.defaultTabContentBackground = "#fff";
        this.defaultTabContentInnerMargin = 0;
        this.defaultTabHeaderBackground = "#fff";
        this.defaultShowContentBorder = false;
        this.defaultContentBorderColor = "lightGray";
        this.defaultContentBorderRadius = 10;
        this.defaultContentBorderWidth = 2;
    }
    setOrder(id, order) { }
    setFormContext(value) {
        if (!value)
            return;
        super.setFormContext(value);
        if (this.tabs) {
            for (let tab of this.tabs) {
                // set edit context first
                tab.setFormContext(value);
            }
        }
    }
    getControls() {
        let controls = [];
        for (let col of this.tabs) {
            controls.push(...col.getControls());
        }
        return controls;
    }
    getCurrentTab() {
        for (let t of this.tabs) {
            if (t.header.title === this.selectedValue) {
                return t;
            }
        }
    }
    addTab(tab) {
        if (this.tabs.length === 0) {
            this.selectedValue = tab.header.title;
        }
        this.add(tab);
    }
    add(control, index) {
        var _a;
        if (control instanceof XTabContainerTab) {
            let tab = control;
            tab.setContainer(this);
            if (!index) {
                this.tabs.push(tab);
            }
            else {
                this.tabs.splice(index, 0, tab);
            }
        }
        else {
            (_a = this.getCurrentTab()) === null || _a === void 0 ? void 0 : _a.add(control, index);
        }
        if (this.getFormContext())
            control.setFormContext(this.getFormContext());
    }
    remove(control) {
        for (let col of this.tabs) {
            col.remove(control);
        }
    }
    find(id) {
        for (let tab of this.tabs) {
            if (tab.id === id)
                return tab;
            if (tab.content && tab.content.id === id)
                return tab.content;
            let con = tab.find(id);
            if (con)
                return con;
        }
        return null;
    }
    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);
    }
    getStorageData() {
        let resData = DataUtilities.cloneWithoutReact(this, ["_formContext", "_formRuntimeContext", "tabs"]);
        let tabs = [];
        for (let t of this.tabs) {
            tabs.push(t.getStorageData());
        }
        Reflect.set(resData, "__tabs", tabs);
        return resData;
    }
    setStorageData(data) {
        DataUtilities.spreadData(this, data, ["__tabs"]);
        let tabsArray = Reflect.get(data, "__tabs");
        if (tabsArray && tabsArray instanceof Array && tabsArray.length !== 0) {
            for (let tabData of tabsArray) {
                let tab = new XTabContainerTab();
                tab.setStorageData(tabData);
                this.addTab(tab);
            }
        }
    }
    handleChange(_event, newValue) {
        this.selectedValue = newValue;
        StateManager.changed(this);
    }
    render() {
        let styles = {};
        if (this.tabs.length === 0) {
            let tab = new XTabContainerTab();
            let tabHeader = new XTabContainerTabHeader();
            tabHeader.title = "test 1";
            let tabContent = new XTabContainerTabContent();
            tab.setHeader(tabHeader);
            tab.setContent(tabContent);
            let tab2 = new XTabContainerTab();
            let tabHeader2 = new XTabContainerTabHeader();
            tabHeader2.title = "test 2";
            let tabContent2 = new XTabContainerTabContent();
            tab2.setHeader(tabHeader2);
            tab2.setContent(tabContent2);
            this.addTab(tab);
            this.addTab(tab2);
        }
        if (this.orientation === TabOrientation.Horizontal) {
            styles.height = this.defaultTabContentHeight;
        }
        else {
            styles.width = this.defaultTabContentWidth;
            styles.flex = 1;
        }
        return (_jsx(TabContainerWrapper, Object.assign({ padding: this.getInnerMargin(), hasBorder: this.hasBorder(), borderColor: this.borderColor(), borderStyle: this.borderStyle(), borderWidth: this.borderWidth(), borderRadius: this.borderRadius(), backgroundColor: this.backgroundColor(), minHeight: this.tabs.length > 0 ? 1 : 75, orientation: this.orientation }, { children: _jsx(ObserveState, { listenTo: this, control: () => (_jsxs(TabContext, Object.assign({ value: this.selectedValue }, { children: [_jsx(TabList, Object.assign({ orientation: this.orientation, onChange: this.handleChange, variant: this.fullWidth ? "fullWidth" : "standard", centered: this.centered }, { children: this.tabs.map((t) => {
                                return (_jsx(StyledTab, { value: t.header.title, label: _jsx(TabHeaderWrapper, Object.assign({ padding: this.innerMarginTabHeader }, { children: t.header.title }), void 0) }, t.id));
                            }) }), void 0),
                        _jsx("div", Object.assign({ style: styles }, { children: this.tabs.map((t) => {
                                return (_jsx(StyledTabPanel, Object.assign({ value: t.header.title }, { children: t.content.render() }), t.id));
                            }) }), void 0)] }), void 0)) }, void 0) }), void 0));
    }
    renderEditUI() {
        var _a, _b, _c, _d, _e, _f;
        return (_jsxs(ChildFullWidthDiv, { children: [_jsx(PropertyEditorSelect, { editObject: this, label: "Orientation", propertyName: "orientation", updateCallback: this.controlUpdate, options: FormDesignConstants.TAB_ORIENTATION }, void 0),
                _jsx(Collapse, Object.assign({ in: this.orientation === TabOrientation.Horizontal }, { children: _jsxs(ChildFullWidthDiv, { children: [_jsx(PropertyEditorBoolean, { editObject: this, label: "Full Width For Tab Headers?", propertyName: "fullWidth", updateCallback: this.controlUpdate }, void 0),
                            _jsx(PropertyEditorBoolean, { editObject: this, label: "Center Tab Headers?", propertyName: "centered", updateCallback: this.controlUpdate }, void 0)] }, void 0) }), void 0),
                _jsx(PropertyEditorInteger, { editObject: this, label: "Inner Margin For Tab Header", propertyName: "innerMarginTabHeader", updateCallback: this.controlUpdate }, void 0),
                _jsx(PropertyEditorInteger, { editObject: this, label: "Inner Margin For Tab Content", propertyName: "defaultTabContentInnerMargin", updateCallback: this.controlUpdate }, void 0),
                _jsx(PropertyEditorInteger, { editObject: this, label: "Gap Between Controls", propertyName: "interControlSpacing", updateCallback: this.controlUpdate, parentDefaultValue: (_b = (_a = this.getFormContext()) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.defaultInterControlSpacing }, void 0),
                _jsx(PropertyEditorInteger, { editObject: this, label: "Inner Margin", propertyName: "paddingBetweenContainerAndtabs", updateCallback: this.controlUpdate, parentDefaultValue: (_d = (_c = this.getFormContext()) === null || _c === void 0 ? void 0 : _c.form) === null || _d === void 0 ? void 0 : _d.defaultInnerContainerMargin }, void 0),
                _jsx(PropertyEditorColor, { editObject: this, label: "Container Color", propertyName: "containerBackgroundColor", updateCallback: this.controlUpdate, parentDefaultValue: (_f = (_e = this.getFormContext()) === null || _e === void 0 ? void 0 : _e.form) === null || _f === void 0 ? void 0 : _f.defaultContainerBackgroundColor }, void 0),
                _jsx(PropertyEditorColor, { editObject: this, label: "Default Tab Content Color", propertyName: "defaultTabContentBackground", updateCallback: this.controlUpdate }, void 0),
                _jsx(PropertyEditorBoolean, { editObject: this, label: "Show Content Border", propertyName: "defaultShowContentBorder", updateCallback: this.controlUpdate }, void 0),
                _jsx(Collapse, Object.assign({ in: this.defaultShowContentBorder }, { children: _jsxs(ChildFullWidthDiv, { children: [_jsx(PropertyEditorInteger, { editObject: this, label: "Content Border Width", propertyName: "defaultContentBorderWidth", updateCallback: this.controlUpdate }, void 0),
                            _jsx(PropertyEditorInteger, { editObject: this, label: "Content Border Radius", propertyName: "defaultContentBorderRadius", updateCallback: this.controlUpdate }, void 0),
                            _jsx(PropertyEditorColor, { editObject: this, label: "Content Border Color", propertyName: "defaultContentBorderColor", updateCallback: this.controlUpdate }, void 0),
                            _jsx(PropertyEditorSelect, { editObject: this, label: "Content Border Style", propertyName: "defaultContentBorderStyle", updateCallback: this.controlUpdate, options: FormDesignConstants.BORDER_STYLES }, void 0)] }, void 0) }), void 0), this.renderBorderConfigUI(), _jsx(PropertyEditorList, { label: "Tabs", list: this.tabs.map((col, idx) => ({ name: `tabs ${idx + 1}`, item: col })), showDialogCancel: false, itemUI: (item) => ({
                        onComplete: (item) => {
                            if (item.content) {
                                item.content.setContainer(this);
                                Reflect.set(this.tabs, item.index, item.content);
                            }
                            else {
                                this.tabs.splice(item.index, 1);
                            }
                            this.controlUpdate();
                        },
                        onCancel: () => {
                            delete item.content;
                        },
                        ui: (_jsx(ChildFullWidthDiv, { children: item.content && (_jsxs(_Fragment, { children: [_jsx(PropertyEditorText, { editObject: item.content.header, propertyName: "title", updateCallback: this.controlUpdate, label: "Tab Title" }, void 0),
                                    _jsx(PropertyEditorInteger, { editObject: item.content.content, label: "Inner Margin", propertyName: "innerMargin", updateCallback: this.controlUpdate }, void 0),
                                    _jsx(PropertyEditorOptionWithButtonGroup, { editObject: item.content.content, label: "Override Border Settings", propertyName: "overrideFormBorderSettings", updateCallback: this.controlUpdate }, void 0),
                                    _jsx(Collapse, Object.assign({ in: item.content.content.overrideFormBorderSettings === DefaultOnOff.On }, { children: _jsxs(ChildFullWidthDiv, { children: [_jsx(PropertyEditorInteger, { editObject: item.content.content, label: "Border Width", propertyName: "containerBorderWidth", updateCallback: this.controlUpdate }, void 0),
                                                _jsx(PropertyEditorInteger, { editObject: item.content.content, label: "Border Radius", propertyName: "containerBorderRadius", updateCallback: this.controlUpdate }, void 0),
                                                _jsx(PropertyEditorColor, { editObject: item.content.content, label: "Border Color", propertyName: "containerBorderColor", updateCallback: this.controlUpdate }, void 0),
                                                _jsx(PropertyEditorSelect, { editObject: item.content, label: "Border Style", propertyName: "containerBorderStyle", updateCallback: this.controlUpdate, options: FormDesignConstants.BORDER_STYLES }, void 0)] }, void 0) }), void 0),
                                    _jsx(PropertyEditorColor, { editObject: item.content.content, label: "Tab Content Background Color", propertyName: "containerBackgroundColor", updateCallback: this.controlUpdate }, void 0)] }, void 0)) }, void 0)),
                    }), prototype: () => {
                        let tab = new XTabContainerTab();
                        let tabHeader = new XTabContainerTabHeader();
                        let tabContent = new XTabContainerTabContent();
                        tab.setHeader(tabHeader);
                        tab.setContent(tabContent);
                        return tab;
                    } }, void 0)] }, void 0));
    }
}
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", void 0)
], XTabContainer.prototype, "handleChange", null);
//# sourceMappingURL=XTabContainer.js.map