import { eqi18n, ExprTag } from '@easyquery/core';
export function registerEntitiesPanelWidget($) {
    $.widget("eqjs.EntitiesPanel", {
        _rootEntityBlock: null,
        _entityTreeBlock: null,
        _query: null,
        _progressBlock: null,
        _queryObserverId: null,
        options: {
            /// <option name="queryPanelId" type="String" default="QueryPanel">
            /// <summary>Gets or sets an ID of the query panel on the same page that will be used to add conditions to</summary>
            /// </option>
            queryPanelId: "QueryPanel",
            /// <option name="columnsPanelId" type="String" default="ColumnsPanel">
            /// <summary>Gets or sets an ID of the columns panel on the same page that will be used to add columns to</summary>
            /// </option>
            columnsPanelId: "ColumnsPanel",
            /// <option name="showToolbar" type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether entities panel should show a toolbar with buttons at the bottom</summary>
            /// </option>
            showToolbar: true,
            /// <option type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether entities panel should show the "Select all" button on the toolbar</summary>
            /// </option>
            showSelectAllButton: false,
            /// <option type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether entities panel should show the "Select none" button on the toolbar</summary>
            /// </option>
            showClearSelectionButton: true,
            /// <option name="showAddColumnButton" type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether entities panel should show the "Add column" button on the toolbar</summary>
            /// </option>
            showAddColumnButton: true,
            /// <option name="showAddConditionButton" type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether entities panel should show the "Add condition" button on the toolbar</summary>
            /// </option>
            showAddConditionButton: true,
            /// <option name="showCheckboxes" type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether tree nodes in entities panel should contain checkboxes that allow to select/deselect the nodes</summary>
            /// </option>
            showCheckboxes: true,
            /// <option name="showTooltips" type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether description property of the attribute/entity should be displayed as tooltip on hover</summary>
            /// </option>
            showTooltips: true,
            /// <option name="clickableAttributes" type="Integer" default="0">
            /// <summary>
            /// Gets or sets a value defining what should happen when user clicks on the attribute node. Values:
            ///   0 - nothing happen. Default behaviour.
            ///   1 - attibute is added to conditions.
            ///   2 - attribute is added to columns.
            /// "draggableAttributes" option should be set to "false" in order to get values 1 and 2 worked.
            /// </summary>
            /// </option>
            clickableAttributes: 0,
            /// <option name="draggableAttributes" type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether attributes may be dragged to be droppen at query panel or columns panel</summary>
            /// </option>
            draggableAttributes: true,
            /// <option name="showAttributes" type="PlainObject" default="{ usedInConditions: true, usedInColumns: true, usedInSorting: false }">
            /// <summary>Gets or sets a value defining which attributes from the model should be shown in the tree. Each attribute in the model has "Use in conditions", "Use in columns", "Use in sorting" properties. This option allows to filter all the attributes by these properties values.</summary>
            /// </option>
            showAttributes: { usedInConditions: true, usedInColumns: true, usedInSorting: false },
            /// <option name="showFilterBox" type="Boolean" default="false">
            /// <summary>Gets or sets a value indicating whether filtef box should be show to allow filtering of visible entities/attributes</summary>
            /// </option>
            showFilterBox: false,
            /// <option name="filterBoxMode" type="Integer" default="0">
            /// <summary>
            /// Gets or sets a value defining how the search is performed in EntitiesPanel. Values:
            ///   0 - checks if node name contains the filter text. Default behaviour.
            ///   1 - checks if node name starts with the filter text.
            /// </summary>
            /// </option>
            filterBoxMode: 0,
            /// <option name="showIndicatorOnLoad" type="Boolean" default="true">
            /// <summary>Gets or sets a value indicating whether a progress indicator should appear while th emodel is loading</summary>
            /// </option>
            showIndicatorOnLoad: true,
            /// <option name="attrPlacement" type="Integer" default="0">
            /// <summary>
            /// Defines where to display attributes in the tree:
            /// 0 - attributes are displayed after entities
            /// 1 - attributes are displayed before entities
            /// 2 - attributes and entities are mixed, and displayed in alphabetical order. In this case the "sortEntities" option value dosn't matter.
            /// </summary>
            /// </option>
            attrPlacement: 0,
            /// <option name="sortEntities" type="Integer" default="false">
            /// <summary>
            /// Defines whether entities and attributes should be sorted alphabetically. If false, they are displayed as listed in the model.
            /// </summary>
            /// </option>
            sortEntities: false,
            /// <option name="autoClearSelection" type="Integer" default="false">
            /// <summary>
            /// Defines whether all selections will be cleared automatically after "add columns" or "add conditions" operation.
            /// </summary>
            /// </option>
            autoClearSelection: true,
            syncWithColumns: false,
            /// <option name="entityRenderedCallback" type="function" default="null">
            /// <summary>
            /// The callback that is called when the entity node has been rendered. It allows you to make any changes you need to the markup of the node.
            /// Parameters:
            ///     entNode - jQuery object that represents the node div
            /// For example, if you need to add some class:
            /// <code>
            /// entityRenderedCallbackHandler: function (entNode) {
            ///    entNode.addClass("some-cool-class");
            /// }
            /// </code>
            /// </summary>
            /// </option>
            entityRenderedCallback: null,
            /// <option name="attributeRenderedCallback" type="function" default="null">
            /// <summary>
            /// The callback that is called when the attribute node has been rendered. It allows you to make any changes you need to the markup of the node.
            /// Parameters:
            ///     attrNode - jQuery object that represents the node div
            /// For example, if you need to add some class:
            /// <code>
            /// attributeRenderedCallbackHandler: function (attrNode) {
            ///    attrNode.addClass("some-cool-class");
            /// }
            /// </code>
            /// </summary>
            /// </option>
            attributeRenderedCallback: null
        },
        getSelf: function () {
            return this;
        },
        getModel: function () {
            var query = this.getQuery();
            return query ? query.getModel() : null;
        },
        getQuery: function () {
            return this._query;
        },
        setQuery: function (query) {
            this._setQueryObserver(true); //removing old query observer
            this._query = query;
            this._setQueryObserver();
            this.refresh();
        },
        _setQueryObserver: function (remove) {
            var self = this;
            var query = this.getQuery();
            var queryObserver = function (event) {
                if (self.options.syncWithColumns) {
                    //if something has changed, and that is related to columns
                    if (event.data && event.data.author !== self &&
                        event.data.changeType && event.data.changeType.indexOf("condition") < 0) {
                        self.refreshCheckedStateByColumns();
                    }
                }
            };
            if (query) {
                if (remove && self._queryObserverId) {
                    query.removeChangedCallback(self._queryObserverId);
                }
                else {
                    self._queryObserverId = query.addChangedCallback(queryObserver);
                }
            }
        },
        refreshCheckedStateByColumns: function () {
            var self = this;
            var attrNode, query = self.getQuery(), columns = query.getColumns(), colLen = columns.length, i = 0, col, attrInput, entNode, entChildren, entInput;
            self._deselectAll();
            for (; i < colLen; i++) {
                col = columns[i];
                if (col.expr.tag == ExprTag.EntityAttribute) {
                    attrNode = self._rootEntityBlock.find('.eqjs-ep-entity-attr[data-id="' + col.expr.id + '"]');
                    attrInput = attrNode.find("input");
                    attrInput.prop("checked", true);
                    entChildren = attrNode.parent(); //getting entity-children node
                    entChildren.show();
                    entNode = entChildren.prev(); //getting entity node (previous to entity-children div)
                    entInput = entNode.find("input"); //getting entity node input
                    entInput.prop("checked", true);
                }
            }
        },
        _create: function () {
            var self = this;
        },
        _renderProgressBlock: function () {
            this._progressBlock = $('<div class="eqjs-progress-win8"><div class="wBall" id="wBall_1"><div class="wInnerBall"></div></div><div class="wBall" id="wBall_2"><div class="wInnerBall"></div></div><div class="wBall" id="wBall_3"><div class="wInnerBall"></div></div><div class="wBall" id="wBall_4"><div class="wInnerBall"></div></div><div class="wBall" id="wBall_5"><div class="wInnerBall"></div></div></div>');
        },
        _render: function () {
            var self = this;
            this._clear();
            var model = this.getModel();
            this.element.addClass('eqjs-ep-panel');
            this._dragParentDiv = $('<div></div>')
                .appendTo(this.element)
                .css("height", "0");
            this._rootEntityBlock = $('<div></div>');
            if (model != null && !model.isEmpty()) {
                var entTree = model.getEntitiesTree({
                    addUIC: self.options.showAttributes.usedInConditions,
                    addUIR: self.options.showAttributes.usedInColumns,
                    addUIS: self.options.showAttributes.usedInSorting,
                    attrPlacement: self.options.attrPlacement,
                    sortEntities: self.options.sortEntities,
                    includeRootData: true
                });
                this._entityTreeBlock = this.element.append(this._renderEntity(entTree, this._rootEntityBlock, 0)); //model.getRootEntity()
            }
            if (this.options.showFilterBox) {
                this._createFilterBox();
            }
            else {
                this._rootEntityBlock.css('top', '0');
            }
            if (this.options.showToolbar && !this.options.syncWithColumns) {
                this._createToolPanel();
            }
            else {
                this._rootEntityBlock.css('bottom', '0');
            }
            this._renderProgressBlock();
        },
        _renderEntity: function (entity, block, offset) {
            var self = this;
            var defaultClass = 'eqjs-ep-entity', entityBlock, entityNode = $('<div></div>', { 'class': defaultClass + '-node' }), entityChildren = $('<div></div>', { 'class': defaultClass + '-children' }), nodeLabel = $('<label></label>', { 'class': defaultClass + '-node-label' }), nodeInput = $('<input />', { 'type': 'checkbox' }), nodeToggleButton = $('<a></a>', { 'href': 'javascript:void(0)', 'class': defaultClass + '-node-button' }), attrNode, attrLabel, attrInput, i, ent, attr, caption, emptyBlock = $('<div></div>'), curOffset = offset;
            var isAttributeInTree = function (attrId, entityBlock) {
                var res = entityBlock.find('.' + defaultClass + '-attr[data-id="' + attrId + '"]');
                return res.length > 0;
            };
            if (block) {
                entityBlock = block;
                entityBlock.html('').addClass(defaultClass);
            }
            else {
                entityBlock = $('<div></div>', { 'class': defaultClass });
            }
            if (entity.id && entity.id != "") {
                nodeLabel.text(entity.text).appendTo(entityNode); //caption
                if (self.options.showCheckboxes) {
                    nodeLabel.prepend(nodeInput);
                }
                nodeToggleButton.prependTo(entityNode);
                if (self.options.showTooltips && entity.description) {
                    nodeLabel.attr('title', entity.description);
                }
                for (var i_1 = 0; i_1 < curOffset; i_1++) {
                    entityNode.prepend($('<div></div>', { 'class': defaultClass + '-offset' }));
                }
                entityBlock.append(entityNode);
                entityChildren.hide();
                curOffset++;
            }
            var itemsLength = entity.items ? entity.items.length : 0;
            for (var i_2 = 0; i_2 < itemsLength; i_2++) {
                var item = entity.items[i_2];
                if (item.isEntity) {
                    entityChildren.append(self._renderEntity(item, null, curOffset));
                }
                else {
                    if (!item.lookupAttr || !(isAttributeInTree(item.lookupAttr, entityChildren) || isAttributeInTree(item.lookupAttr, this._rootEntityBlock))) {
                        attrLabel = $('<label></label>', {
                            'text': item.text,
                            'class': defaultClass + '-attr-label'
                        });
                        if (self.options.showCheckboxes) {
                            attrInput = $('<input />', { 'type': 'checkbox' });
                            attrLabel.prepend(attrInput);
                            attrInput.change(function () {
                                if (self.options.syncWithColumns) {
                                    var ColumnsPanel = $("#" + self.options.columnsPanelId);
                                    var b = $(this).prop("checked");
                                    var anode = $(this).parent().parent(); //getting attribute node
                                    var attrId = anode.data("id");
                                    if (b) {
                                        ColumnsPanel.ColumnsPanel("addNewColumn", attrId);
                                    }
                                    else {
                                        ColumnsPanel.ColumnsPanel("removeColumnByAttrId", attrId);
                                    }
                                }
                            });
                        }
                        if (self.options.showTooltips && item.description) {
                            attrLabel.attr('title', item.description);
                        }
                        for (var j = 0; j < curOffset + 1; j++) {
                            attrLabel.prepend($('<div></div>', { 'class': defaultClass + '-offset' }));
                        }
                        attrNode = $('<div></div>').attr('class', function () {
                            var className = defaultClass + '-attr ';
                            if (entityNode.html().length == 0) {
                                className += defaultClass + '-attr-root';
                            }
                            return className;
                        }).html(attrLabel).attr('data-id', item.id);
                        if (self.options.draggableAttributes) {
                            attrNode.addClass('draggable');
                            attrNode.draggable({
                                containment: "document",
                                cursor: "auto",
                                helper: "clone",
                                scope: "entityAttr",
                                revert: "invalid",
                                distance: 10,
                                connectToSortable: ".ui-sortable",
                                cursorAt: { bottom: 20, left: 10 },
                                start: function (event, ui) {
                                    ui.helper.find("input").hide();
                                    var label = ui.helper.find("label");
                                    label.css("max-width", "400px")
                                        .css("overflow", "hidden")
                                        .css("text-overflow", "ellipsis");
                                },
                                appendTo: self._dragParentDiv
                            });
                        }
                        if (self.options.clickableAttributes == 1) {
                            attrNode.click(function () {
                                var QueryPanelWidget = $("#" + self.options.queryPanelId);
                                QueryPanelWidget.QueryPanel("addNewConditionIntoActivePredicate", $(this).data('id'));
                            });
                        }
                        else if (self.options.clickableAttributes == 2) {
                            attrNode.click(function () {
                                var ColumnsPanelWidget = $("#" + self.options.columnsPanelId);
                                ColumnsPanelWidget.ColumnsPanel("addNewColumn", $(this).data('id'));
                            });
                        }
                        if (this.options.attributeRenderedCallback) {
                            this.options.attributeRenderedCallback(attrNode);
                        }
                        entityChildren.append(attrNode);
                    }
                }
            }
            if (entityChildren.html().length) {
                entityBlock.append(entityChildren);
                nodeToggleButton.click(function (event) {
                    entityChildren.toggle();
                    $(this).toggleClass(defaultClass + '-node-button-open');
                    event.preventDefault();
                });
            }
            if (entityChildren) {
                entityChildren.find('> .eqjs-ep-entity-attr > label > input').click(function (e) {
                    if ($(this).prop('checked') && !(nodeInput.prop('checked'))) {
                        nodeInput.prop('checked', true);
                    }
                    else if (entityChildren.find('input:checked').length == 0) {
                        nodeInput.prop('checked', false);
                    }
                    e.stopPropagation();
                });
            }
            nodeInput.click(function (e) {
                var nodeChecked = $(this).prop('checked');
                if (nodeChecked) {
                    entityChildren.find('label input').prop('checked', true);
                }
                else {
                    entityChildren.find('label input').prop('checked', false);
                }
                if (self.options.syncWithColumns) {
                    var attrs = [];
                    var attrNodes = entityChildren.find("div.eqjs-ep-entity-attr");
                    attrNodes.each(function () {
                        attrs.push($(this).data("id"));
                    });
                    var ColumnsPanel = $("#" + self.options.columnsPanelId);
                    if (nodeChecked) {
                        ColumnsPanel.ColumnsPanel("addNewColumn", attrs);
                    }
                    else {
                        ColumnsPanel.ColumnsPanel("removeColumnByAttrId", attrs);
                    }
                }
                e.stopPropagation();
            });
            if (block != this._rootEntityBlock && this.options.entityRenderedCallback) {
                this.options.entityRenderedCallback(entityBlock);
            }
            return entityBlock;
        },
        expandAll: function () {
            this._rootEntityBlock.children().find('.eqjs-ep-entity-children').show();
            this._rootEntityBlock.find('.eqjs-ep-entity-node-button').addClass('eqjs-ep-entity-node-button-open');
        },
        collapseAll: function () {
            this._rootEntityBlock.children().find('.eqjs-ep-entity-children').hide();
            this._rootEntityBlock.find('.eqjs-ep-entity-node-button').removeClass('eqjs-ep-entity-node-button-open');
        },
        _checkFilterText: function (value) {
            var filterText = this.filterBoxInput.val();
            if (filterText == "")
                return true;
            if (this.options.filterBoxMode == 0 && value.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
                return true;
            if (this.options.filterBoxMode == 1 && value.toLowerCase().indexOf(filterText.toLowerCase()) == 0)
                return true;
            return false;
        },
        _checkFilterAttribute: function (attr) {
            var attrChecked = $(attr).find('label input').prop("checked");
            if (attrChecked) {
                return true;
            }
            var attrCaption = $(attr).find('label').text();
            if (this._checkFilterText(attrCaption)) {
                return true;
            }
            var entityNode = $(attr).parent().parent().find('.eqjs-ep-entity-node');
            var entityCaption = entityNode.find('label').text();
            if (this._checkFilterText(entityCaption)) {
                return true;
            }
            return false;
        },
        _createFilterBox: function () {
            var self = this;
            var defClass = 'eqjs-ep-filter-box';
            self.filterBoxBlock = $('<div></div>', { 'class': defClass }),
                self.filterBoxInput = $('<input></input>', { 'class': defClass + "-input" });
            self.filterBoxInput.keydown(function (e) {
                if (e.keyCode == 27) { // if - esc
                    self.filterBoxInput.val('');
                    self.filterBoxInput.trigger('input', null);
                    e.stopPropagation();
                    return false;
                }
            });
            self.filterBoxInput.on('input', function (e) {
                var attrs = self.element.find('.eqjs-ep-entity-attr');
                $.each(attrs, function (idx, attr) {
                    if (self._checkFilterAttribute(attr)) {
                        $(attr).show();
                    }
                    else {
                        $(attr).hide();
                    }
                });
                var entities = self.element.find('>.eqjs-ep-entity').find('.eqjs-ep-entity');
                entities.forEach(function (entity) {
                    var attrs = $(entity).find('.eqjs-ep-entity-attr').filter(function (idx, item) {
                        return $(item).css("display") !== "none";
                    });
                    if (attrs.length == 0) {
                        $(entity).hide();
                    }
                    else {
                        $(entity).show();
                    }
                });
                if (self.filterBoxInput.val() == '')
                    self.collapseAll();
                else
                    self.expandAll();
            });
            self.filterBoxBlock.append(self.filterBoxInput);
            self.element.prepend(self.filterBoxBlock);
        },
        _createToolPanel: function () {
            var self = this;
            var defClass = 'eqjs-ep-tool-panel', toolPanelBlock = $('<div></div>', { 'class': defClass }), toolSelectAll = $('<div></div>', { 'class': defClass + '-select-all', 'title': 'Select all' }), toolDeselectAll = $('<div></div>', { 'class': defClass + '-deselect-all', 'title': 'Clear selection' }), toolAddColumns = $('<div></div>', { 'class': defClass + '-add-columns', 'title': 'Add column' }), toolAddCond = $('<div></div>', { 'class': defClass + '-add-cond', 'title': 'Add condition' }), toolLeftBlock = $('<div></div>', { 'class': defClass + '-left-side' }), toolRightBlock = $('<div></div>', { 'class': defClass + '-right-side' });
            var model = self.getModel();
            if (this.options.showSelectAllButton) {
                toolSelectAll.attr("title", eqi18n.getText("ButtonSelectAll"));
                toolLeftBlock.append(toolSelectAll);
                toolSelectAll.click(function () {
                    self._selectAll();
                });
            }
            if (this.options.showClearSelectionButton) {
                toolDeselectAll.attr("title", eqi18n.getText("ButtonDeselectAll"));
                toolLeftBlock.append(toolDeselectAll);
                toolDeselectAll.click(function () {
                    self._deselectAll();
                });
            }
            if (this.options.showAddColumnButton) {
                toolAddColumns.attr("title", eqi18n.getText("ButtonAddColumns"));
                toolRightBlock.append(toolAddColumns);
                toolAddColumns.click(function () {
                    var attrElements = self.element.find(".eqjs-ep-entity-attr");
                    var attrList = [];
                    var attrId, attribute;
                    var query = self.getQuery();
                    query.fireProcessEvent({
                        source: self,
                        status: "start"
                    });
                    for (var i = 0; i < attrElements.length; i++) {
                        var attrElem = $(attrElements[i]);
                        var input = attrElem.find("input").first();
                        if (input.prop("checked")) {
                            attrId = attrElem.data('id');
                            if (model.checkAttrProperty(attrId, "usedInResult")) {
                                attrList.push(attrId);
                            }
                        }
                    }
                    var columnsPanel = $("#" + self.options.columnsPanelId);
                    columnsPanel.ColumnsPanel("addNewColumn", attrList);
                    if (self.options.autoClearSelection) {
                        self._deselectAll();
                    }
                    query.fireProcessEvent({
                        source: self,
                        status: "finish"
                    });
                });
            }
            if (this.options.showAddConditionButton) {
                toolAddCond.attr("title", eqi18n.getText("ButtonAddConditions"));
                toolRightBlock.append(toolAddCond);
                toolAddCond.click(function () {
                    var attrElements = self.element.find(".eqjs-ep-entity-attr");
                    var attrList = [];
                    var attrId, attribute;
                    var query = self.getQuery();
                    query.fireProcessEvent({
                        source: self,
                        status: "start"
                    });
                    for (var i = 0; i < attrElements.length; i++) {
                        var attrElem = $(attrElements[i]);
                        var input = attrElem.find("input").first();
                        if (input.prop("checked")) {
                            attrId = attrElem.data('id');
                            if (model.checkAttrProperty(attrId, "usedInCondition")) {
                                attrList.push(attrId);
                            }
                        }
                    }
                    var queryPanel = $("#" + self.options.queryPanelId);
                    queryPanel.QueryPanel("addNewCondition", attrList);
                    if (self.options.autoClearSelection) {
                        self._deselectAll();
                    }
                    query.fireProcessEvent({
                        source: self,
                        status: "finish"
                    });
                });
            }
            toolPanelBlock.append(toolLeftBlock, toolRightBlock);
            this.element.append(toolPanelBlock);
        },
        _selectAll: function () {
            this._entityTreeBlock.find('input').prop('checked', true);
        },
        _deselectAll: function () {
            this._entityTreeBlock.find('input').prop('checked', false);
        },
        _setOption: function (key, value) {
            if (arguments.length == 2) {
                this.options[key] = value;
                this._render();
                return this;
            }
            else {
                return this.options[key];
            }
        },
        _clear: function () {
            this.element.html('');
        },
        /// <method name="refresh">
        /// <summary>Re-renders the panel</summary>
        /// </method>
        refresh: function () {
            this._render();
            if (this.options.syncWithColumns) {
                this.refreshCheckedStateByColumns();
            }
        },
        resize: function () {
            this._render();
        },
        startLoading: function () {
            if (this.options.showIndicatorOnLoad) {
                this.element.append(this._progressBlock);
            }
        },
        finishLoading: function () {
            if (this.options.showIndicatorOnLoad) {
                this.element.find(this._progressBlock).remove();
            }
        }
    });
}
//# sourceMappingURL=eq.entitiespanel.js.map