var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
import React from 'react';
import { connect } from 'react-redux';
import styled, { css } from 'react-emotion';
import { Spring } from 'react-spring';
import { DragDropContext } from 'react-beautiful-dnd';
import { updateObject, updateObjectParameter, updateObjectViewOption, updateOperation, createObject, deleteObject, undoComposition, duplicateObject, addOperation, removeOperation, reorderOperation, setActiveOperation, unsetActiveOperation, ungroup, convertToGroup, } from '../../actions/threed';
import { getSelectedObjects } from '../../reducers/threed/';
import PropertyInput from './PropertyInput';
import OperationsList from './OperationsList';
import DropDown from '../DropDown';
import Tooltip from '../Tooltip';
import { Icon, Input } from '@bitbloq/ui';
import config from '../../config/threed';
var Wrap = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n  display: flex;\n"], ["\n  display: flex;\n"])));
var Container = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n  width: 310px;\n  min-width: 310px;\n  overflow: hidden;\n  border-left: 1px solid #cfcfcf;\n  background-color: white;\n  display: flex;\n  flex-direction: column;\n"], ["\n  width: 310px;\n  min-width: 310px;\n  overflow: hidden;\n  border-left: 1px solid #cfcfcf;\n  background-color: white;\n  display: flex;\n  flex-direction: column;\n"])));
var Header = styled.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n  height: 50px;\n  padding: 0px 20px;\n  background-color: white;\n  border-bottom: 1px solid #cfcfcf;\n  display: flex;\n  align-items: center;\n  font-size: 1.1em;\n\n  img {\n    cursor: pointer;\n  }\n"], ["\n  height: 50px;\n  padding: 0px 20px;\n  background-color: white;\n  border-bottom: 1px solid #cfcfcf;\n  display: flex;\n  align-items: center;\n  font-size: 1.1em;\n\n  img {\n    cursor: pointer;\n  }\n"])));
var HeaderIcon = styled.div(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n  margin-right: 10px;\n  color: #4dc3ff;\n\n  svg {\n    width: 30px;\n    height: auto;\n  }\n"], ["\n  margin-right: 10px;\n  color: #4dc3ff;\n\n  svg {\n    width: 30px;\n    height: auto;\n  }\n"])));
var ObjectName = styled.div(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n  flex: 1;\n  display: flex;\n  align-items: center;\n  font-weigth: bold;\n  font-style: italic;\n  font-size: 13px;\n  cursor: pointer;\n\n  svg {\n    display: none;\n    margin-left: 10px;\n    width: 14px;\n    height: auto;\n  }\n\n  &:hover {\n    svg {\n      display: block;\n    }\n  }\n"], ["\n  flex: 1;\n  display: flex;\n  align-items: center;\n  font-weigth: bold;\n  font-style: italic;\n  font-size: 13px;\n  cursor: pointer;\n\n  svg {\n    display: none;\n    margin-left: 10px;\n    width: 14px;\n    height: auto;\n  }\n\n  &:hover {\n    svg {\n      display: block;\n    }\n  }\n"])));
var ObjectProperties = styled.div(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n  border-bottom: 1px solid #cfcfcf;\n  position: relative;\n  font-size: 13px;\n"], ["\n  border-bottom: 1px solid #cfcfcf;\n  position: relative;\n  font-size: 13px;\n"])));
var ParametersPanel = styled.div(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n  padding: 20px;\n"], ["\n  padding: 20px;\n"])));
var ParametersForm = styled.div(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n  flex: 1;\n"], ["\n  flex: 1;\n"])));
var ObjectButtons = styled.div(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n  display: flex;\n  padding: 0px 4px 10px 4px;\n"], ["\n  display: flex;\n  padding: 0px 4px 10px 4px;\n"])));
var OperationButton = styled.div(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: 50px;\n  border-radius: 3px;\n  background-color: #ebebeb;\n  flex: 1;\n  margin: 0px 2px;\n  border-bottom: 5px solid ", ";\n\n  svg {\n    width: 24px;\n    height: auto;\n  }\n"], ["\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: 50px;\n  border-radius: 3px;\n  background-color: #ebebeb;\n  flex: 1;\n  margin: 0px 2px;\n  border-bottom: 5px solid ", ";\n\n  svg {\n    width: 24px;\n    height: auto;\n  }\n"])), function (props) { return props.color; });
var NameInput = styled(Input)(templateObject_11 || (templateObject_11 = __makeTemplateObject(["\n  height: 16px;\n  padding: 6px 8px;\n"], ["\n  height: 16px;\n  padding: 6px 8px;\n"])));
var ContextButton = styled.div(templateObject_13 || (templateObject_13 = __makeTemplateObject(["\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 30px;\n  height: 30px;\n  border-radius: 4px;\n  background-color: white;\n  cursor: pointer;\n\n  ", " svg {\n    transform: rotate(90deg);\n  }\n"], ["\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 30px;\n  height: 30px;\n  border-radius: 4px;\n  background-color: white;\n  cursor: pointer;\n\n  ",
    " svg {\n    transform: rotate(90deg);\n  }\n"])), function (props) {
    return props.isOpen && css(templateObject_12 || (templateObject_12 = __makeTemplateObject(["\n      border: solid 1px #dddddd;\n      background-color: #e8e8e8;\n    "], ["\n      border: solid 1px #dddddd;\n      background-color: #e8e8e8;\n    "])));
});
var ContextMenu = styled.div(templateObject_14 || (templateObject_14 = __makeTemplateObject(["\n  background-color: white;\n  margin-top: 6px;\n  box-shadow: 0 3px 7px 0 rgba(0, 0, 0, 0.5);\n  border-radius: 4px;\n  border: solid 1px #cfcfcf;\n"], ["\n  background-color: white;\n  margin-top: 6px;\n  box-shadow: 0 3px 7px 0 rgba(0, 0, 0, 0.5);\n  border-radius: 4px;\n  border: solid 1px #cfcfcf;\n"])));
var ContextMenuOption = styled.div(templateObject_16 || (templateObject_16 = __makeTemplateObject(["\n  width: 220px;\n  display: flex;\n  align-items: center;\n  height: 34px;\n  border-bottom: 1px solid #ebebeb;\n  font-size: 14px;\n  cursor: pointer;\n\n  svg {\n    margin: 0px 14px;\n    width: 13px;\n    height: auto;\n  }\n\n  &:hover {\n    background-color: #ebebeb;\n  }\n\n  &:last-child {\n    border: none;\n  }\n\n  ", ";\n"], ["\n  width: 220px;\n  display: flex;\n  align-items: center;\n  height: 34px;\n  border-bottom: 1px solid #ebebeb;\n  font-size: 14px;\n  cursor: pointer;\n\n  svg {\n    margin: 0px 14px;\n    width: 13px;\n    height: auto;\n  }\n\n  &:hover {\n    background-color: #ebebeb;\n  }\n\n  &:last-child {\n    border: none;\n  }\n\n  ",
    ";\n"])), function (props) {
    return props.danger && css(templateObject_15 || (templateObject_15 = __makeTemplateObject(["\n      color: #d82b32;\n    "], ["\n      color: #d82b32;\n    "])));
});
var PropertiesPanel = /** @class */ (function (_super) {
    __extends(PropertiesPanel, _super);
    function PropertiesPanel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.state = {
            draggingOperations: false,
            contextMenuOpen: false,
            editingName: false,
        };
        _this.nameInputRef = React.createRef();
        _this.onObjectNameChange = function (object, name) {
            _this.props.updateObjectViewOption(object, 'name', name);
        };
        _this.onObjectParameterChange = function (object, parameter, value) {
            if (parameter.name === 'baseObject') {
                var newChildren = object.children.filter(function (c) { return c !== value; });
                newChildren.unshift(value);
                _this.props.updateObject(__assign({}, object, { children: newChildren }));
            }
            else if (parameter.isViewOption) {
                _this.props.updateObjectViewOption(object, parameter.name, value);
            }
            else {
                _this.props.updateObjectParameter(object, parameter.name, value);
            }
        };
        _this.onOperationParameterChange = function (object, operation, parameter, value) {
            var _a;
            if (parameter.setValue) {
                _this.props.updateOperation(object, parameter.setValue(operation, value));
            }
            else {
                _this.props.updateOperation(object, __assign({}, operation, (_a = {}, _a[parameter.name] = value, _a)));
            }
        };
        _this.onDragStart = function () {
            _this.setState({ draggingOperations: true });
        };
        _this.onDragEnd = function (result, object) {
            var destination = result.destination, source = result.source, draggableId = result.draggableId;
            var operation = object.operations.find(function (_a) {
                var id = _a.id;
                return id === draggableId;
            });
            _this.setState({ draggingOperations: false });
            if (!destination || !operation)
                return;
            _this.props.reorderOperation(object, operation, source.index, destination.index);
        };
        _this.onRenameClick = function () {
            _this.setState({ editingName: true });
        };
        _this.onDeleteClick = function () {
            var _a = _this.props, object = _a.object, deleteObject = _a.deleteObject;
            deleteObject(object);
        };
        _this.onDuplicateClick = function () {
            var _a = _this.props, object = _a.object, duplicateObject = _a.duplicateObject;
            duplicateObject(object);
        };
        _this.onUngroupClick = function () {
            var _a = _this.props, object = _a.object, ungroup = _a.ungroup;
            ungroup(object);
        };
        _this.onConvertToGroupClick = function () {
            var _a = _this.props, object = _a.object, convertToGroup = _a.convertToGroup;
            convertToGroup(object);
        };
        _this.onUndoClick = function () {
            var _a = _this.props, object = _a.object, undoComposition = _a.undoComposition;
            undoComposition(object);
        };
        return _this;
    }
    PropertiesPanel.prototype.componentDidUpdate = function (prevProps, prevState) {
        if (this.state.editingName && !prevState.editingName) {
            this.nameInputRef.current.focus();
        }
    };
    PropertiesPanel.prototype.onAddOperation = function (object, operation) {
        this.props.addOperation(object, operation.create());
    };
    PropertiesPanel.prototype.onRemoveOperation = function (object, operation) {
        this.props.removeOperation(object, operation);
    };
    PropertiesPanel.prototype.renderObjectPanel = function (object) {
        var _this = this;
        var _a = this.state, draggingOperations = _a.draggingOperations, contextMenuOpen = _a.contextMenuOpen, editingName = _a.editingName;
        var _b = this.props, setActiveOperation = _b.setActiveOperation, unsetActiveOperation = _b.unsetActiveOperation, advancedMode = _b.advancedMode, isTopObject = _b.isTopObject;
        var color = object.viewOptions.color;
        var typeConfig = config.objectTypes.find(function (s) { return s.name === object.type; }) || {};
        var baseParameters = typeConfig.parameters, icon = typeConfig.icon;
        var canUndo = typeConfig.canUndo, undoLabel = typeConfig.undoLabel, canUngroup = typeConfig.canUngroup, canConverToGroup = typeConfig.canConverToGroup;
        var parameters = baseParameters(object).slice();
        if (typeConfig.showBaseObject) {
            parameters.push({
                name: 'baseObject',
                label: 'Base object',
                type: 'select',
                options: object.children.map(function (child) { return ({
                    label: child.viewOptions.name,
                    value: child,
                }); }),
            });
        }
        if (!typeConfig.withoutColor) {
            parameters.push({
                name: 'color',
                label: 'Color',
                type: 'color',
                isViewOption: true,
            });
        }
        return (React.createElement(DragDropContext, { onDragStart: this.onDragStart, onDragEnd: function (result) { return _this.onDragEnd(result, object); } },
            React.createElement(Header, null,
                React.createElement(HeaderIcon, null, icon),
                editingName && (React.createElement(NameInput, { type: "text", innerRef: this.nameInputRef, value: object.viewOptions.name, onChange: function (e) { return _this.onObjectNameChange(object, e.target.value); }, onBlur: function () { return _this.setState({ editingName: false }); } })),
                !editingName && (React.createElement(ObjectName, { onClick: function () { return _this.setState({ editingName: true }); } },
                    object.viewOptions.name,
                    " ",
                    React.createElement(Icon, { name: "pencil" }))),
                React.createElement(DropDown, null,
                    function (isOpen) { return (React.createElement(ContextButton, { isOpen: isOpen },
                        React.createElement(Icon, { name: "ellipsis" }))); },
                    React.createElement(ContextMenu, null,
                        isTopObject && (React.createElement(ContextMenuOption, { onClick: this.onDuplicateClick },
                            React.createElement(Icon, { name: "duplicate" }),
                            " Duplicate")),
                        React.createElement(ContextMenuOption, { onClick: this.onRenameClick },
                            React.createElement(Icon, { name: "pencil" }),
                            " Rename"),
                        canUngroup && (React.createElement(ContextMenuOption, { onClick: this.onUngroupClick },
                            React.createElement(Icon, { name: "ungroup" }),
                            " Ungroup")),
                        canConverToGroup && (React.createElement(ContextMenuOption, { onClick: this.onConvertToGroupClick },
                            React.createElement(Icon, { name: "group" }),
                            " Convert to group")),
                        canUndo && (React.createElement(ContextMenuOption, { onClick: this.onUndoClick },
                            React.createElement(Icon, { name: "undo" }),
                            " ",
                            undoLabel)),
                        isTopObject && (React.createElement(ContextMenuOption, { danger: true, onClick: this.onDeleteClick },
                            React.createElement(Icon, { name: "trash" }),
                            " Delete"))))),
            React.createElement(ObjectProperties, null,
                React.createElement(ParametersPanel, null, parameters.map(function (parameter) { return (React.createElement(PropertyInput, { key: parameter.name, parameter: parameter, value: parameter.isViewOption
                        ? object.viewOptions && object.viewOptions[parameter.name]
                        : object.parameters && object.parameters[parameter.name], onChange: function (value) {
                        return _this.onObjectParameterChange(object, parameter, value);
                    } })); })),
                advancedMode && (React.createElement(ObjectButtons, null, config.objectOperations.map(function (operation) { return (React.createElement(Tooltip, { key: operation.name, content: operation.label }, function (tooltipProps) { return (React.createElement(OperationButton, __assign({}, tooltipProps, { color: operation.color, onClick: function () { return _this.onAddOperation(object, operation); } }), operation.icon)); })); })))),
            React.createElement(OperationsList, { operations: object.operations, advancedMode: advancedMode, onParameterChange: function (operation, parameter, value) {
                    return _this.onOperationParameterChange(object, operation, parameter, value);
                }, onParameterFocus: function (operation, parameter) {
                    if (parameter.activeOperation) {
                        setActiveOperation(parameter.activeOperation(object, operation));
                    }
                }, onParameterBlur: function (operation, parameter) {
                    if (parameter.activeOperation) {
                        unsetActiveOperation();
                    }
                }, onRemoveOperation: function (operation) {
                    return _this.onRemoveOperation(object, operation);
                } })));
    };
    PropertiesPanel.prototype.render = function () {
        var _this = this;
        var object = this.props.object;
        return (React.createElement(Spring, { from: { width: 0 }, to: { width: object ? 310 : 0 } }, function (style) { return (React.createElement(Wrap, { style: style },
            React.createElement(Container, null, object && _this.renderObjectPanel(object)))); }));
    };
    return PropertiesPanel;
}(React.Component));
var mapStateToProps = function (_a) {
    var threed = _a.threed;
    var topObjects = threed.scene.objects;
    var selectedObjects = getSelectedObjects(threed) || [];
    var object = selectedObjects.length === 1 ? selectedObjects[0] : null;
    return {
        object: object,
        advancedMode: threed.ui.advancedMode,
        isTopObject: topObjects.includes(object),
    };
};
var mapDispatchToProps = function (dispatch) { return ({
    updateObject: function (object) { return dispatch(updateObject(object)); },
    updateObjectParameter: function (object, parameter, value) {
        return dispatch(updateObjectParameter(object, parameter, value));
    },
    updateObjectViewOption: function (object, option, value) {
        return dispatch(updateObjectViewOption(object, option, value));
    },
    updateOperation: function (object, operation, parameter, value) {
        return dispatch(updateOperation(object, operation, parameter, value));
    },
    createObject: function (object) { return dispatch(createObject(object)); },
    deleteObject: function (object) { return dispatch(deleteObject(object)); },
    undoComposition: function (object) { return dispatch(undoComposition(object)); },
    ungroup: function (object) { return dispatch(ungroup(object)); },
    convertToGroup: function (object) { return dispatch(convertToGroup(object)); },
    duplicateObject: function (object) { return dispatch(duplicateObject(object)); },
    addOperation: function (object, operation) {
        return dispatch(addOperation(object, operation));
    },
    removeOperation: function (object, operation) {
        return dispatch(removeOperation(object, operation));
    },
    reorderOperation: function (object, operation, from, to) {
        return dispatch(reorderOperation(object, operation, from, to));
    },
    setActiveOperation: function (_a) {
        var object = _a.object, type = _a.type, axis = _a.axis, relative = _a.relative;
        return dispatch(setActiveOperation(object, type, axis, relative));
    },
    unsetActiveOperation: function () { return dispatch(unsetActiveOperation()); },
}); };
export default connect(mapStateToProps, mapDispatchToProps)(PropertiesPanel);
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16;
//# sourceMappingURL=PropertiesPanel.js.map