"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAvailableVisualization = exports.TileBuilder = void 0;
const clsx_1 = __importDefault(require("clsx"));
const React = __importStar(require("react"));
const react_grid_layout_1 = __importDefault(require("react-grid-layout"));
const tileContainer_1 = require("./tileContainer");
const immer_1 = __importDefault(require("immer"));
const tiles_1 = __importDefault(require("./tiles"));
const style = __importStar(require(".tileBuilder.module.scss"));
const keyboardKeys_1 = require("keyboardKeys");
// TODO: Create Functional Component with Hooks
class TileBuilder extends React.Component {
    constructor(props) {
        super(props);
        this.gridLayoutContentRef = React.createRef();
        this.onLayoutChange = (newLayout) => {
            // create the reduced layout to give back to the consumer to be able to save it without any changes 
            const newTiles = (0, immer_1.default)(this.props.tiles, (draft) => {
                for (let idx = 0; idx < newLayout.length; idx++) {
                    const tile = newLayout[idx];
                    draft[idx].layout = {
                        i: tile.i,
                        x: tile.x || 0,
                        y: tile.y || 0,
                        h: tile.h || 1,
                        w: tile.w || 1,
                        minW: tile.minW || 1,
                        minH: tile.minH || 1,
                        maxW: tile.maxW || Infinity,
                        maxH: tile.maxH || Infinity
                    };
                }
            });
            if (this.props.onChange) {
                this.props.onChange(newTiles);
            }
        };
        this.onClickHandler = (e) => {
            if (!!e && !!e.target) {
                const target = e.target.attributes['data-key'];
                if (target) {
                    e.stopPropagation();
                    this.setState({ actionsexpanded: target.value });
                }
                else {
                    this.setState({ actionsexpanded: -1 });
                }
            }
        };
        this.selectSize = (size, id) => {
            const newTiles = (0, immer_1.default)(this.props.tiles, (draft) => {
                const tileDraft = draft[id];
                tileDraft.layout.h = size.h;
                tileDraft.layout.w = size.w;
            });
            if (this.props.onChange) {
                this.props.onChange(newTiles);
            }
        };
        this.onTileMove = (direction, id) => {
            const newTiles = (0, immer_1.default)(this.props.tiles, (draft) => {
                const tileDraft = draft[id];
                switch (direction) {
                    case keyboardKeys_1.Keys.ArrowDown:
                        ++tileDraft.layout.y;
                        break;
                    case keyboardKeys_1.Keys.ArrowRight:
                        ++tileDraft.layout.x;
                        break;
                    case keyboardKeys_1.Keys.ArrowUp:
                        // avoid to go below the x = 0
                        tileDraft.layout.y = Math.max(0, tileDraft.layout.y - 1);
                        break;
                    case keyboardKeys_1.Keys.ArrowLeft:
                        tileDraft.layout.x = Math.max(0, tileDraft.layout.x - 1);
                        break;
                }
            });
            if (this.props.onChange) {
                this.props.onChange(newTiles);
            }
        };
        // get the injected props;
        const { configuration: injectedConfig, configuration: { editable, cols, defaultTileDimension, containerPadding, className, disabled } } = this.props;
        // set the default state
        this.state = {
            actionsexpanded: -1
        };
        // create the default props
        const padding = containerPadding || 20;
        const defaultConfiguration = {
            className: undefined,
            cols: 12,
            rowHeight: 200,
            width: 2520,
            margin: [padding, padding],
            containerPadding: [padding, padding],
            onResizeStart: undefined,
            onResize: undefined,
            onResizeStop: undefined,
            onDragStart: undefined,
            onDrag: undefined,
            onDragStop: undefined,
            isDraggable: true,
            isResizable: true,
            preventCollision: false,
            compactType: 'vertical',
            useCSSTransforms: true,
        };
        // set the width of TileBuilder based on the cols * defaultTileDimension + margin
        const width = cols * defaultTileDimension + ((cols + 1) * padding);
        const configuration = {
            isDraggable: editable && !disabled,
            isResizable: editable && !disabled,
            width,
            rowHeight: defaultTileDimension,
            onLayoutChange: this.onLayoutChange,
            className
        };
        this.tileBuilderConfiguration = Object.assign({}, defaultConfiguration, injectedConfig, configuration);
    }
    render() {
        const { tiles: tileProps, tileStates, render, onTileDelete, onTileEdit, onSelectVisualization, configuration: { editable, className, disabled } } = this.props;
        // React Grid Layout prop
        let layout = [];
        // Tile Properties
        const tilesElement = [];
        for (let tileId = 0; tileId < tileProps.length; tileId++) {
            const tileProperties = tileProps[tileId];
            const tileState = tileStates && tileStates[tileId];
            // needed to preserve the layout of all the tiles and pass to the GridLayout as first level property
            // support the case where the dashboard is generated automatically
            // device first scenario and import DCM creating a default dashboard
            let tileLayout = fallBackLayout(tileId);
            if (tileProperties.layout && tileProperties.layout.w) {
                tileLayout = tileProperties.layout;
            }
            // adding the tile id = index at this level because we are not saving the index as tile id, 
            // we are relying on the index of the array of tile 
            // the onLayoutChange function won't be affected by the id management
            layout.push({ ...tileLayout, i: tileId.toString() });
            const isTileConfigurable = !!tiles_1.default[tileProperties.type] && !!tiles_1.default[tileProperties.type].panelConfiguration;
            const props = {
                key: tileId,
                id: tileId,
                selectSize: this.selectSize,
                actionsexpanded: this.state.actionsexpanded === tileId,
                actionexplandedhandler: this.onClickHandler,
                props: tileProperties,
                state: tileState,
                render,
                editable,
                isTileConfigurable,
                availableSize: tileProperties.availableSize,
                onTileDelete,
                onTileEdit,
                onTileMove: this.onTileMove,
                onSelectVisualization,
                availableVisualization: getAvailableVisualization(tileProperties),
                disabled
            };
            tilesElement.push(<tileContainer_1.TileContainer {...props}/>);
        }
        return (<div className={(0, clsx_1.default)(style['tile-builder'], style['grid-layout-container'], className)} onClick={this.onClickHandler}>
                <react_grid_layout_1.default ref={this.gridLayoutContentRef} {...this.tileBuilderConfiguration} className={(0, clsx_1.default)('grid-layout-content', className)} layout={layout}>
                    {tilesElement}
                </react_grid_layout_1.default>
            </div>);
    }
}
exports.TileBuilder = TileBuilder;
const fallBackLayout = (i) => {
    return {
        i,
        x: 0,
        y: 0,
        h: 1,
        w: 1
    };
};
function getAvailableVisualization({}) {
    const availableViz = [];
    // TODO: add logic
    return availableViz;
}
exports.getAvailableVisualization = getAvailableVisualization;
//# sourceMappingURL=tileBuilder.jsx.map