import { eqi18n, equtils, Expression, DataType, DataKind, SortDirection, ExprTag } from '@easyquery/core';
export function registerColumnWidgets($) {
    $.widget("eqjs.ColumnRow", {
        _column: null,
        _baseExprBlock: null,
        _captionEditorBlock: null,
        _buttonsBlock: null,
        //        _enableButton: null,
        _columnTypeButton: null,
        _deleteButton: null,
        _keepShowingButtons: false,
        _isMouseOverBlock: false,
        _sortingButton: null,
        _panelCssPrefix: 'eqjs-qc',
        _classesToAdd: '',
        _active: false,
        options: {
            columnsPanel: null
        },
        getColumnsPanel: function () {
            return this.options.columnsPanel;
        },
        getQuery: function () {
            return this.options.columnsPanel ? this.options.columnsPanel.getQuery() : null;
        },
        getModel: function () {
            var query = this.getQuery();
            return query ? query.getModel() : null;
        },
        getColumn: function () {
            return this._column;
        },
        isModelNullOrEmpty: function () {
            var model = this.getModel();
            return !model || model.isEmpty();
        },
        _initCssPrefixes: function () {
        },
        init: function (column) {
            var self = this;
            this._initCssPrefixes();
            self._column = column;
            self.element.get(0).column = column;
            self.refresh();
        },
        _render: function () {
            this._clear();
            if (!this.isModelNullOrEmpty() && this._column) {
                this._refreshByColumn();
                this._initButtons();
                if (this.options.columnsPanel.options.activeColumn == this._column) {
                    this.makeActive();
                }
            }
        },
        _fireColumnChange: function (changeType, column) {
            var self = this;
            column = column || self._column;
            var query = this.getQuery();
            query.fireChangedEvent({
                "author": self.options.columnsPanel,
                "changeType": "column." + changeType,
                "column": column
            });
        },
        refresh: function () {
            this._render();
        },
        _setOption: function (key, value) {
            if (arguments.length == 2) {
                this.options[key] = value;
                if (key === "disabled") {
                    this._column.enabled = !value;
                }
                this._render();
                return this;
            }
            else {
                if (key === "disabled") {
                    return this._column.enabled === false;
                }
                else {
                    return this.options[key];
                }
            }
        },
        _clear: function () {
            this.element.unbind();
            this.element.html('');
            this.element.removeClass();
        },
        _refreshByColumn: function () {
        },
        remove: function () {
            var self = this;
            if (!self.options.columnsPanel) {
                return;
            }
            self.options.columnsPanel.removeColumn(self._column);
        },
        _getButtonsContainer: function () {
            return this.element;
        },
        _getUIS: function () {
            return this.getModel().checkAttrProperty(this._column.expr.id, "usedInSorting");
        },
        _initButtons: function () {
            var self = this;
            var query = this.getQuery();
            var columnsPanel = this.getColumnsPanel();
            var btnSortPlaceholder = $("<div></div>")
                .addClass('eqjs-button-placeholder')
                .addClass(self._panelCssPrefix + '-button-placeholder')
                .addClass(self._panelCssPrefix + '-colelement')
                .addClass(self._panelCssPrefix + '-sortbutton-placeholder');
            var imgSortPlaceholder = $("<div></div>")
                .addClass(self._panelCssPrefix + '-colelement')
                .addClass(self._panelCssPrefix + '-sortimage-placeholder');
            self._sortingImage = $("<div></div>")
                .addClass(self._panelCssPrefix + '-img-sorting')
                //.attr('title', EQ.core.getText('ButtonSorting'))
                .appendTo(imgSortPlaceholder);
            if (columnsPanel.options.isColumnsBar) {
                imgSortPlaceholder.prependTo(self.element);
            }
            else {
                btnSortPlaceholder.prependTo(self.element);
            }
            self._sortingButton = $('<div></div>')
                .addClass('eqjs-column-sortbutton')
                .appendTo(btnSortPlaceholder);
            var container = self._getButtonsContainer();
            if (!container || self._column.readOnly)
                return;
            self._buttonsBlock = $("<div></div>")
                .addClass("eqjs-column-buttonsBlock")
                .addClass(self._panelCssPrefix + '-buttonsBlock')
                .appendTo(container);
            if (columnsPanel.options.isColumnsBar) {
                btnSortPlaceholder.appendTo(self._buttonsBlock);
            }
            var btnPlaceholder = $("<div></div>")
                .addClass('eqjs-button-placeholder')
                .addClass(self._panelCssPrefix + '-button-placeholder')
                .addClass(self._panelCssPrefix + '-typebutton-placeholder')
                .appendTo(self._buttonsBlock);
            self._columnTypeButton = $("<div></div>")
                .addClass("eqjs-button")
                .addClass("eqjs-column-button")
                .addClass("eqjs-column-button-type")
                .attr('title', eqi18n.getText('ButtonToAggr'))
                .appendTo(btnPlaceholder);
            btnPlaceholder = $("<div></div>")
                .addClass('eqjs-button-placeholder')
                .addClass(self._panelCssPrefix + '-button-placeholder')
                .addClass(self._panelCssPrefix + '-deletebutton-placeholder')
                .appendTo(self._buttonsBlock);
            self._deleteButton = $("<div></div>")
                .addClass("eqjs-button")
                .addClass("eqjs-column-button")
                .addClass("eqjs-column-button-delete")
                .attr('title', eqi18n.getText('ButtonDelete'))
                .appendTo(btnPlaceholder)
                .click(function () {
                self.remove();
                return false;
            });
            self._sortingButton
                .attr('title', eqi18n.getText('ButtonSorting'))
                .click(function (event) {
                self._keepShowingButtons = true;
                var menu = self._getUIS() ? self.options.columnsPanel.options.sortMenu : self.options.columnsPanel.options.moveMenu;
                menu.PopupMenu('showMenu', {
                    anchor: self._sortingButton,
                    selectedIds: null,
                    itemSelectedCallback: function (evt, data) {
                        function strToSortDirection(str) {
                            if (str == 'None') {
                                return SortDirection.None;
                            }
                            else if (str == "Ascending") {
                                return SortDirection.Ascending;
                            }
                            else if (str == "Descending") {
                                return SortDirection.Descending;
                            }
                        }
                        if (data.menuItem.id == 'None' || data.menuItem.id == "Ascending" || data.menuItem.id == "Descending") {
                            self._column.sorting = strToSortDirection(data.menuItem.id);
                            self._column.sortIndex = query.getColumnSortIndex(self._column);
                            columnsPanel.refresh();
                            self._fireColumnChange("change");
                        }
                        else {
                            self.options.columnsPanel.moveColumn(self._column, data.menuItem.id);
                        }
                    },
                    menuClosedCallback: function () {
                        self._keepShowingButtons = false;
                        if (!self._isMouseOverBlock) {
                            self._sortingButton.trigger('mouseleave');
                        }
                    }
                });
                return false;
            });
            var sortButtonCssPrefix = 'eqjs-column-sortbutton';
            self._sortingButton.addClass("eqjs-button");
            if (self._column.sorting === SortDirection.None) {
                self._sortingButton.addClass(sortButtonCssPrefix + '-none');
                self._sortingImage.addClass(sortButtonCssPrefix + '-none');
            }
            if (columnsPanel.options.isColumnsBar) {
                self._sortingButton.addClass(sortButtonCssPrefix + '-none');
            }
            self._sortingButton.hover(function (e) {
                $(e.target).addClass(sortButtonCssPrefix + '-active');
            }, function (e) {
                $(e.target).removeClass(sortButtonCssPrefix + '-active');
            });
            if (self._column.sorting === SortDirection.Ascending) {
                if (!columnsPanel.options.isColumnsBar) {
                    self._sortingButton
                        .addClass(sortButtonCssPrefix + '-asc')
                        .attr('title', eqi18n.getText('ButtonSorting'));
                }
                self._sortingImage
                    .addClass(sortButtonCssPrefix + '-asc');
                //.attr('title', EQ.core.getText('ButtonSorting'));
            }
            else if (self._column.sorting === SortDirection.Descending) {
                if (!columnsPanel.options.isColumnsBar) {
                    self._sortingButton
                        .addClass(sortButtonCssPrefix + '-desc')
                        .attr('title', eqi18n.getText('ButtonSorting'));
                }
                self._sortingImage
                    .addClass(sortButtonCssPrefix + '-desc');
                //.attr('title', EQ.core.getText('ButtonSorting'));
            }
            //            (self.options.disabled) ? self._enableButton.removeClass('enabled') : self._enableButton.addClass('enabled');
            var buttonCssPrefix = this._panelCssPrefix + '-button';
            container.find('[class*=' + buttonCssPrefix + ']').hover(function (e) {
                $(e.target).addClass(buttonCssPrefix + '-active');
            }, function (e) {
                $(e.target).removeClass(buttonCssPrefix + '-active');
            });
            container.bind('mouseenter', function (event) {
                self._isMouseOverBlock = true;
                self._enterButtonBlock();
                event.stopPropagation();
                return false;
            })
                .bind('mouseleave', function (event) {
                self._isMouseOverBlock = false;
                if (!self._keepShowingButtons) { //&& self._buttonsBlock.is(':visible')) {
                    self._leaveButtonBlock();
                }
                event.stopPropagation();
                return false;
            });
            self._setupButtonListeners();
            self._hideButtons();
            self._adjustButtonsVisibility();
        },
        _setupButtonListeners: function () {
        },
        _adjustButtonsVisibility: function () {
        },
        _enterButtonBlock: function () {
            this._showButtons();
        },
        _leaveButtonBlock: function () {
            if (this.options.columnsPanel.options.alwaysShowButtons != true && (!this._active || this.options.columnsPanel.options.accentActiveColumn != true)) {
                this._hideButtons();
            }
        },
        _showButtons: function () {
        },
        _hideButtons: function () {
            this._columnTypeButton.hide();
            //            this._columnTypeButton.css('background-image', 'none');
            this._deleteButton.hide();
            //            this._deleteButton.css('background-image', 'none');
            if (this._column.sorting === SortDirection.None) {
                this._sortingButton.hide();
                //                this._sortingButton.css('background-image', 'none');
            }
            var columnsPanel = this.getColumnsPanel();
            if (columnsPanel.options.isColumnsBar) {
                this._buttonsBlock.hide();
            }
        },
        internalActivate: function () {
            this._active = true;
            this.adjustActiveClass();
            this._hideButtons();
            this._adjustButtonsVisibility();
        },
        internalDeactivate: function () {
            this._active = false;
            this.adjustActiveClass();
            this._hideButtons();
            this._adjustButtonsVisibility();
        },
        adjustActiveClass: function () {
            if (this._active && this.options.columnsPanel.options.accentActiveColumn) {
                this.element.addClass("active");
            }
            else {
                this.element.removeClass("active");
            }
        },
        isActive: function () {
            return this._active;
        },
        makeActive: function () {
            var columnsPanel = this.getColumnsPanel();
            if (columnsPanel)
                columnsPanel.setActiveColumnWidget(this);
        },
        makeInactive: function () {
            var columnsPanel = this.getColumnsPanel();
            if (columnsPanel)
                columnsPanel.deactivateColumnWidget();
        }
        /*
                setActiveColumnWidget: function () {
                    this.options.columnsPanel.setActiveColumnWidget(this);
                }
        */
    });
    $.widget("eqjs.ColumnRow_" + ExprTag.EntityAttribute, $.eqjs.ColumnRow, {
        _baseAttr: null,
        _menuFunctionsBlock: null,
        _paramsBlock: null,
        _initCssPrefixes: function () {
            this._panelCssPrefix = this.options.columnsPanel._getCssPrefix();
            this._classesToAdd = this._panelCssPrefix + '-row ' + this._panelCssPrefix + '-row-column-entattr';
        },
        _baseExprMenuClick: function (evt, data) {
            var self = this;
            var attrid = data.menuItem.data('id');
            var model = self.getModel();
            var attrobj = model.getAttributeById(attrid);
            self._column.expr.id = attrid;
            self._column.caption = '';
            self.refresh();
            self._fireColumnChange("change");
            return false;
        },
        _getBaseExpr: function () {
            var self = this;
            var baseExpr = null;
            if (self._column.enabled !== false && !self._column.readOnly) {
                baseExpr = $('<a></a>')
                    .attr('href', "javascript:void(0)")
                    .text(self._getAttributeText(self._baseAttr))
                    .attr('title', self._getAttributeText(self._baseAttr))
                    .click(function (e) {
                    e.preventDefault();
                    self.options.columnsPanel.options.entitiesMenu.PopupMenu('showMenu', {
                        anchor: baseExpr,
                        selectedIds: null,
                        itemSelectedCallback: function (evt, data) {
                            return self._baseExprMenuClick(evt, data);
                        }
                    });
                });
            }
            else
                baseExpr = $('<span></span>')
                    .text(self._getAttributeText(self._baseAttr))
                    .attr('title', self._getAttributeText(self._baseAttr));
            return baseExpr;
        },
        _fillBaseBlock: function (baseBlock) {
            var self = this;
            baseBlock.addClass(this._panelCssPrefix + '-expr-block');
            self._baseExprBlock = $('<div></div>')
                .addClass(this._panelCssPrefix + '-colelement')
                .addClass(this._panelCssPrefix + '-attrelement')
                .appendTo(baseBlock);
            //var baseAttrId = this._column.expr.id;
            var baseExpr = self._getBaseExpr();
            baseExpr.appendTo(self._baseExprBlock);
            if (self._column.params && self._column.params.length > 0) { // there are some parameters 
                self._paramsBlock = $('<div></div>')
                    .addClass(this._panelCssPrefix + '-params-block')
                    .appendTo(baseBlock);
                self._fillParamsBlock(self._paramsBlock);
            }
            ;
            if (!self._column.readOnly) {
                self._createFunctionMenu();
            }
            ;
        },
        _fillParamsBlock: function (paramsBlock) {
            var self = this;
            $('<span>(</span>')
                .addClass("eqjs-qc-colelement")
                .addClass("eqjs-qp-valueelement")
                .appendTo(paramsBlock);
            self._column.params.forEach(function (item, idx, arr) {
                var paramElement = $('<div></div>');
                paramElement.appendTo(paramsBlock);
                self._createParamEditor(paramElement, item);
                if (idx < arr.length - 1) {
                    $('<span>,&nbsp</span>')
                        .addClass("eqjs-qc-colelement")
                        .addClass("eqjs-qp-valueelement")
                        .appendTo(paramsBlock);
                }
                ;
            });
            $('<span>)</span>')
                .addClass("eqjs-qc-colelement")
                .addClass("eqjs-qp-valueelement")
                .appendTo(paramsBlock);
        },
        _getParamEditor: function (param) {
            var self = this;
            var model = self.getModel();
            var attribute = self._getAttribute();
            var editor = {};
            if (param && param.editor && param.editor.type !== DataType.Unknown) {
                editor = $.extend({}, param.editor);
            }
            else if (param && (param.dataType == DataType.Date || param.dataType == DataType.DateTime || param.dataType == DataType.Time)) {
                editor.type = "DATETIME";
            }
            else {
                editor.type = 'EDIT';
            }
            return editor;
        },
        _createParamEditor: function (element, param) {
            var self = this;
            var editor = self._getParamEditor(param);
            param.kind = DataKind.Scalar;
            if (editor) {
                var funcBody = "element.ValueEditor_" + editor.type + "({parentWidget:self, editor: editorObj, onChange:paramChangedCallback, emptyText: emptyTxt}); " +
                    "element.ValueEditor_" + editor.type + "('init', expr);";
                var addWidget = new Function("self, element, expr, editorObj, paramChangedCallback, emptyTxt", funcBody);
                var paramChangedCallback = function () {
                    self._fireColumnChange("change", self._column);
                };
                addWidget(this, element, param, editor, paramChangedCallback, "<" + param.caption + ">");
            }
        },
        _refreshByColumn: function () {
            if (!this._column || this.isModelNullOrEmpty())
                return;
            var self = this;
            self._baseAttr = self._getAttribute();
            self.element.addClass(self._classesToAdd);
            if (self._column.readOnly)
                this.element.addClass('eqjs-qp-readonly');
            var baseBlock = $('<div></div>')
                .appendTo(self.element);
            self._fillBaseBlock(baseBlock);
            if (self.options.columnsPanel.options.accentActiveColumn) {
                self.element.click(function () {
                    if (self._active) {
                        self.makeInactive();
                    }
                    else {
                        self.makeActive();
                    }
                });
            }
            if (!self._column.caption || self._column.caption == '') {
                self._column.caption = self._getDefaultCaption();
            }
            if (self.options.columnsPanel.options.showColumnCaptions) {
                if (!self._column.readOnly) {
                    this._captionEditorBlock = $('<div></div>');
                    this._captionEditorBlock.appendTo(this.element);
                    var captionChanged = function () {
                        self._column.captionChanged = true;
                        self._fireColumnChange("change");
                    };
                    this._captionEditorBlock.ColumnRow_CaptionEditor({ parentWidget: self, cssClassPrefix: this._panelCssPrefix });
                    this._captionEditorBlock.ColumnRow_CaptionEditor('init', self._column, self._column.caption, captionChanged); //self._getDefaultCaption()
                }
                else {
                    var captionElement = $('<span></span>')
                        .addClass(this._panelCssPrefix + '-colelement')
                        .addClass(this._panelCssPrefix + '-captionelement')
                        .text(self._column.caption) //self._getDefaultCaption())
                        .attr('title', self._column.caption)
                        .appendTo(this.element);
                }
            }
            self.adjustActiveClass();
        },
        _getDefaultTitleText: function (attr) {
            var columnsPanel = this.options.columnsPanel;
            var format = columnsPanel.options.titleElementFormat || columnsPanel.options.attrElementFormat;
            var model = this.getModel();
            return model.getAttributeText(attr, format);
        },
        _getDefaultCaption: function () {
            return this._getDefaultTitleText(this._baseAttr);
        },
        _getAttribute: function () {
            return this.getModel().getAttributeById(this._column.expr.id);
        },
        _getAttributeText: function (attr) {
            var self = this;
            if (!attr)
                return '';
            var model = this.getModel();
            var format = self.options.columnsPanel.options.attrElementFormat;
            return model.getAttributeText(attr, format);
        },
        _adjustButtonsVisibility: function () {
            var self = this;
            self._columnTypeButton
                .removeClass('aggregated')
                .attr('title', eqi18n.getText('ButtonToAggr'));
            if (this.options.columnsPanel.options.alwaysShowButtons || (this.options.columnsPanel.options.accentActiveColumn && this._active)) {
                this._showButtons();
            }
        },
        _changeTypeToAggr: function (funcId) {
            var self = this;
            if (!funcId)
                funcId = self._menuFunctionsBlock.PopupMenu('option', 'items')[0].id;
            var id = self._column.expr.id;
            self._column.caption = '';
            var expr = new Expression();
            expr.tag = ExprTag.AggregateFunction;
            expr.func = funcId;
            expr.distinct = false;
            var arg = new Expression();
            arg.id = id;
            arg.tag = ExprTag.EntityAttribute;
            expr.args.push(arg);
            self._column.expr = expr;
            var column = self._column;
            var isActive = self._active;
            self.destroy();
            self._clear();
            self.element["ColumnRow_" + ExprTag.AggregateFunction]({ columnsPanel: self.options.columnsPanel });
            self.element["ColumnRow_" + ExprTag.AggregateFunction]('init', column);
            self._fireColumnChange("change");
            if (isActive) {
                self.options.columnsPanel._activeColumn = null;
                self.element["ColumnRow_" + ExprTag.AggregateFunction]('makeActive');
            }
        },
        _changeTypeToCustomSql: function () {
            var self = this;
            var attrId = self._column.expr.id;
            self._column.caption = '';
            var sqlText = '';
            var model = self.getModel();
            if (model) {
                sqlText = model.getAttributeById(attrId).sqlExpr;
            }
            var customSqlExpr = new Expression();
            customSqlExpr.tag = ExprTag.CustomSql;
            customSqlExpr.sql = sqlText;
            customSqlExpr.baseAttrId = attrId;
            this._column.expr = customSqlExpr;
            var column = self._column;
            var isActive = self._active;
            self.destroy();
            self._clear();
            self.element["ColumnRow_" + ExprTag.CustomSql]({ columnsPanel: self.options.columnsPanel });
            self.element["ColumnRow_" + ExprTag.CustomSql]('init', column);
            self._fireColumnChange("change");
            if (isActive) {
                self.options.columnsPanel._activeColumn = null;
                self.element["ColumnRow_" + ExprTag.CustomSql]('makeActive');
            }
            ;
            self.element["ColumnRow_" + ExprTag.CustomSql]('showSqlEditor');
        },
        _createFunctionMenu: function () {
            var self = this;
            var items = [];
            var funcs = self.getModel().getAggrFunctions();
            var toInclude = true;
            var funcAllowed = true;
            var item = null;
            var attribute = self._getAttribute();
            var funcCaption;
            var funcsLen = funcs.length;
            for (var idx = 0; idx < funcsLen; idx++) {
                if (!funcs[idx])
                    continue;
                toInclude = true;
                if (funcs[idx].id === 'SUM' || funcs[idx].id === 'AVG') {
                    toInclude = $.inArray(attribute.dataType, [DataType.Autoinc, DataType.Byte, DataType.Currency, DataType.Float, DataType.Int32,
                        DataType.Int64, DataType.Word]) >= 0;
                }
                else if (funcs[idx].id === 'MIN' || funcs[idx].id === 'MAX') {
                    toInclude = $.inArray(attribute.dataType, [DataType.Autoinc, DataType.BCD, DataType.Byte, DataType.Currency, DataType.Date, DataType.DateTime, DataType.Time,
                        DataType.Float, DataType.Int32, DataType.Int64, DataType.Word]) >= 0;
                }
                if (self._column.expr.func === funcs[idx].id && !toInclude) {
                    funcAllowed = false;
                }
                if (toInclude) {
                    funcCaption = self.getModel().getAggrFunctionCaption(funcs[idx].id);
                    item = {
                        id: funcs[idx].id,
                        text: funcCaption
                    };
                    items.push(item);
                }
            }
            if (!funcAllowed) {
                self._column.expr.func = items[0].id;
            }
            //Add "Custom Expression" menu
            var columnsPanel = self.options.columnsPanel;
            if (columnsPanel.areCustomExpressionsAllowed()) {
                item = {
                    id: 'CustomSqlDivider',
                    text: '---'
                };
                items.push(item);
                funcCaption = eqi18n.getText('CustomExpression');
                item = {
                    id: 'CUSTOMSQL',
                    text: funcCaption
                };
                items.push(item);
            }
            self._menuFunctionsBlock = $('<div></div>')
                .hide()
                .appendTo(self.element);
            var menuId = self.element.attr('id');
            if (menuId) {
                menuId += '-FunctionsMenu';
            }
            var menuOptions = {
                items: items,
                id: menuId,
                domWriteItemsId: self.options.columnsPanel.options.domWriteItemsId
            };
            equtils.assign(menuOptions, self.options.columnsPanel.options.menuOptions);
            self._menuFunctionsBlock.PopupMenu(menuOptions);
            return self._menuFunctionsBlock;
        },
        _showButtons: function () {
            if (this.options.columnsPanel.options.allowAggrColumns != false) {
                this._columnTypeButton.show();
            }
            else {
                this._columnTypeButton.attr('title', '');
            }
            this._deleteButton.show();
            this._sortingButton.show();
            var columnsPanel = this.getColumnsPanel();
            if (columnsPanel.options.isColumnsBar && !this.element.hasClass("ui-sortable-helper")) {
                this._buttonsBlock.show();
            }
        },
        _setupButtonListeners: function () {
            var self = this;
            if (self._columnTypeButton) {
                self._columnTypeButton.click(function (e) {
                    if (self.options.columnsPanel.options.allowAggrColumns !== false && self._column.enabled !== false) {
                        self._keepShowingButtons = true;
                        self._menuFunctionsBlock.PopupMenu('showMenu', {
                            anchor: self._columnTypeButton,
                            selectedIds: null,
                            itemSelectedCallback: function (evt, data) {
                                if (data.menuItem.id == "CUSTOMSQL") {
                                    self._changeTypeToCustomSql();
                                }
                                else {
                                    self._changeTypeToAggr(data.menuItem.id);
                                }
                                return false;
                            },
                            menuClosedCallback: function () {
                                self._keepShowingButtons = false;
                                if (!self._isMouseOverBlock) {
                                    self._columnTypeButton.trigger('mouseleave');
                                }
                            }
                        });
                    }
                    ;
                    return false;
                });
            }
        }
    });
    $.widget("eqjs.ColumnRow_" + ExprTag.AggregateFunction, $.eqjs["ColumnRow_" + ExprTag.EntityAttribute], {
        _displayFormatParser: {
            formatStr: '',
            pos: 0,
            //exprNum: 0,
            token: 'text',
            tokenText: '',
            start: function (s) {
                this.formatStr = s;
                this.pos = 0;
                //this.exprNum = 0;
                this.tokenText = '';
            },
            skipSpaces: function () {
                while (this.pos < this.formatStr.length && this.formatStr.charAt(this.pos) === ' ')
                    this.pos++;
            },
            next: function () {
                this.skipSpaces();
                if (this.pos >= this.formatStr.length)
                    return false;
                var npos = 0;
                if (this.formatStr.charAt(this.pos) === '{') {
                    npos = this.formatStr.indexOf('}', this.pos);
                    if (npos < 0)
                        return false;
                    this.tokenText = this.formatStr.substring(this.pos, npos + 1);
                    if (this.tokenText.indexOf('{expr') === 0 || this.tokenText.indexOf('{attr') === 0) {
                        this.token = 'expression';
                    }
                    this.pos = npos + 1;
                }
                else if (this.formatStr.charAt(this.pos) === '[' && this.pos < this.formatStr.length - 1 && this.formatStr.charAt(this.pos + 1) === '[') {
                    this.pos += 2;
                    npos = this.formatStr.indexOf(']]', this.pos);
                    this.token = 'function';
                    this.tokenText = this.formatStr.substring(this.pos, npos);
                    this.pos = npos + 2;
                }
                else {
                    this.token = 'text';
                    var npos1 = this.formatStr.indexOf('{', this.pos);
                    if (npos1 < 0)
                        npos1 = this.formatStr.length;
                    var npos2 = this.formatStr.indexOf('[[', this.pos);
                    if (npos2 < 0)
                        npos2 = this.formatStr.length;
                    npos = Math.min(npos1, npos2);
                    this.tokenText = $.trim(this.formatStr.substring(this.pos, npos));
                    this.pos = npos;
                }
                return true;
            }
        },
        _initCssPrefixes: function () {
            this._panelCssPrefix = this.options.columnsPanel._getCssPrefix();
            this._classesToAdd = this._panelCssPrefix + '-row ' + this._panelCssPrefix + '-row-column-aggr';
        },
        _parseDisplayFormat: function (format) {
            if (!format)
                return [];
            var result = [];
            var parser = this._displayFormatParser;
            parser.start(format);
            while (parser.next()) {
                if (parser.token === 'function') {
                    result.push({ type: 1, text: parser.tokenText });
                }
                else if (parser.token === 'expression') {
                    result.push({ type: 2 });
                }
                else if (parser.token === 'text') {
                    result.push({ type: 3, text: parser.tokenText });
                }
            }
            return result;
        },
        _baseExprMenuClick: function (evt, data) {
            var self = this;
            var attrid = data.menuItem.data('id');
            var attrobj = self.getModel().getAttributeById(attrid);
            self._column.expr.args[0].id = attrid;
            self._column.caption = '';
            self.refresh();
            self._fireColumnChange("change");
            return false;
        },
        _fillBaseBlock: function (baseBlock) {
            var self = this;
            baseBlock.addClass(this._panelCssPrefix + '-expr-block ' + this._panelCssPrefix + '-expr-block-aggr');
            var baseExpr, functionLink;
            var functionBlock = $('<div></div>')
                .addClass(this._panelCssPrefix + '-colelement')
                .addClass(this._panelCssPrefix + '-aggrfuncelement');
            if (self._column.enabled !== false && !self._column.readOnly) {
                functionLink = $('<a></a>', {
                    href: 'javascript:void(0)'
                }).appendTo(functionBlock);
                self._createFunctionMenu();
            }
            else
                functionLink = $('<span></span>').appendTo(functionBlock);
            var format = self.getModel().getAggrFunctionFormat(self._column.expr.func);
            if (!format || format === '')
                return;
            var arrFormat = self._parseDisplayFormat(format);
            if (arrFormat.length === 0)
                return;
            var item = null;
            var arrLength = arrFormat.length;
            for (var idx = 0; idx < arrLength; idx++) {
                item = arrFormat[idx];
                if (item.type === 1) {
                    functionLink.text(item.text);
                    functionBlock.appendTo(baseBlock);
                    if (self._column.enabled !== false) {
                        functionLink.click(function (e) {
                            self._menuFunctionsBlock.PopupMenu('showMenu', {
                                anchor: functionLink,
                                selectedIds: null,
                                itemSelectedCallback: function (evt, data) {
                                    self._column.expr.func = data.menuItem.id;
                                    self._column.caption = '';
                                    self.refresh();
                                    self._fireColumnChange("change");
                                    return false;
                                }
                            });
                            return false;
                        });
                    }
                }
                else if (item.type === 2) {
                    self._baseAttr = self._getAttribute();
                    baseExpr = this._getBaseExpr();
                    self._baseExprBlock = $('<div></div>')
                        .addClass(this._panelCssPrefix + '-colelement')
                        .addClass(this._panelCssPrefix + '-attrelement')
                        .appendTo(baseBlock);
                    baseExpr.appendTo(self._baseExprBlock);
                }
                else if (item.type === 3) {
                    var textBlock = $('<span></span>')
                        .addClass(this._panelCssPrefix + '-colelement')
                        .text(item.text)
                        .attr('title', item.text)
                        .appendTo(baseBlock);
                }
            }
        },
        _getDefaultCaption: function () {
            return this._getDefaultTitleText(this._baseAttr) + ' ' + this.getModel().getAggrFunctionCaption(this._column.expr.func);
        },
        _getAttribute: function () {
            return this.getModel().getAttributeById(this._column.expr.args[0].id);
        },
        _setupButtonListeners: function () {
            var self = this;
            self._columnTypeButton.click(function () {
                if (self._column.enabled !== false) {
                    self._changeTypeToSimple();
                }
                return false;
            });
        },
        _adjustButtonsVisibility: function () {
            var self = this;
            self._columnTypeButton
                .addClass('aggregated')
                .attr('title', eqi18n.getText('ButtonToSimple'));
            if (this.options.columnsPanel.options.alwaysShowButtons || (this.options.columnsPanel.options.accentActiveColumn && this._active)) {
                this._showButtons();
            }
        },
        _changeTypeToSimple: function () {
            var self = this;
            var id = self._column.expr.args[0].id;
            self._column.caption = '';
            var expr = new Expression();
            expr.tag = ExprTag.EntityAttribute;
            expr.id = id;
            this._column.expr = expr;
            var column = self._column;
            var isActive = self._active;
            self.destroy();
            self._clear();
            self.element["ColumnRow_" + ExprTag.EntityAttribute]({ columnsPanel: self.options.columnsPanel });
            self.element["ColumnRow_" + ExprTag.EntityAttribute]('init', column);
            self._fireColumnChange("change");
            if (isActive) {
                self.options.columnsPanel._activeColumn = null;
                self.element["ColumnRow_" + ExprTag.EntityAttribute]('makeActive');
            }
        },
        _getUIS: function () {
            var arg = this._column.expr.args[0];
            if (arg) {
                var model = this.getModel();
                return model.checkAttrProperty(arg.id, "usedInSorting");
            }
            else {
                return true;
            }
        }
    });
    //----------------------------------
    //  ColumnRow_CUSTOMSQL widget
    //----------------------------------
    $.widget("eqjs.ColumnRow_" + ExprTag.CustomSql, $.eqjs["ColumnRow_" + ExprTag.EntityAttribute], {
        _fillBaseBlock: function (baseBlock) {
            var self = this;
            baseBlock.addClass(this._panelCssPrefix + '-expr-block');
            self._baseExprBlock = $('<div></div>')
                .addClass(this._panelCssPrefix + '-colelement')
                .addClass(this._panelCssPrefix + '-attrelement')
                .appendTo(baseBlock);
            var sqlChanged = function () {
                self._fireColumnChange("change");
            };
            self._column.captionChanged = false;
            self._baseExprBlock.ColumnRow_CustomSqlExprEditor({ parentWidget: self, cssClassPrefix: this._panelCssPrefix });
            self._baseExprBlock.ColumnRow_CustomSqlExprEditor('init', self._column, self._getDefaultValue(), sqlChanged);
        },
        showSqlEditor: function () {
            this._baseExprBlock.ColumnRow_CustomSqlExprEditor('showEditor');
        },
        _getDefaultValue: function () {
            var val = this._column.expr.sql;
            return val;
        },
        _getDefaultCaption: function () {
            return "Custom SQL Column";
        },
        _adjustButtonsVisibility: function () {
            var self = this;
            self._columnTypeButton
                .addClass('aggregated')
                .attr('title', eqi18n.getText('ButtonToSimple'));
            if (this.options.columnsPanel.options.alwaysShowButtons || (this.options.columnsPanel.options.accentActiveColumn && this._active)) {
                this._showButtons();
            }
        },
        _setupButtonListeners: function () {
            var self = this;
            self._columnTypeButton.click(function () {
                if (self._column.enabled !== false) {
                    self._changeTypeToSimple();
                }
                return false;
            });
        },
        _changeTypeToSimple: function () {
            var self = this;
            var id = self._column.expr.baseAttrId;
            self._column.caption = '';
            var expr = new Expression();
            expr.tag = ExprTag.EntityAttribute;
            expr.id = id;
            self._column.expr = expr;
            var column = self._column;
            var isActive = self._active;
            self.destroy();
            self._clear();
            self.element["ColumnRow_" + ExprTag.EntityAttribute]({ columnsPanel: self.options.columnsPanel });
            self.element["ColumnRow_" + ExprTag.EntityAttribute]('init', column);
            self._fireColumnChange("change");
            if (isActive) {
                self.options.columnsPanel._activeColumn = null;
                self.element["ColumnRow_" + ExprTag.EntityAttribute]('makeActive');
            }
        },
        _getUIS: function () {
            return true;
        }
    });
    //----------------------------------
    //  ColumnRow_CaptionEditor widget
    //----------------------------------
    $.widget("eqjs.ColumnRow_CaptionEditor", $.eqjs.ValueEditor_EDIT, {
        _column: null,
        _defaultValue: '',
        _editBoxClass: 'eqjs-qc-ce-editbox',
        _onChange: null,
        options: {
            cssClassPrefix: 'eqjs-qc'
        },
        init: function (column, defaultValue, changeCallback) {
            this._editBoxClass = this.options.cssClassPrefix + '-ce-editbox';
            this._expr.value = column.caption;
            this._expr.text = column.caption;
            this._column = column;
            this._defaultValue = defaultValue;
            this._onChange = changeCallback;
            this.refresh();
        },
        _render: function () {
            this.clear();
            if (this._column) {
                this._renderCommonPart();
                this._renderEditor();
                this._linkElement.text(this._getDisplayText());
                this._linkElement.attr('title', this._getDisplayText());
            }
        },
        _renderCommonPart: function () {
            var self = this;
            self.element.addClass(self._getClassesToAdd());
            self._linkElement = $('<a></a>', {
                href: 'javascript:void(0)',
                text: '-'
            }).appendTo(self.element);
            self._linkElement.click(function () {
                self._showEditor();
                return false;
            });
        },
        _getClassesToAdd: function () {
            return this.options.cssClassPrefix + '-colelement ' + this.options.cssClassPrefix + '-captionelement';
        },
        _setValue: function (newValue) {
            if (!newValue || newValue == '')
                this._column.caption = this._defaultValue;
            else
                this._column.caption = newValue;
            this.updateLink();
            if (this._onChange) {
                this._onChange(newValue);
            }
            return true;
        },
        updateLink: function () {
            this._linkElement.text(this._column.caption);
            this._linkElement.attr('title', this._column.caption);
        },
        _getValue: function () {
            return this._column.caption;
        },
        _getText: function () {
            return this._column.caption;
        },
        _getDisplayText: function () {
            return this._column.caption;
        },
        _getZIndex: function () {
            return 100000;
        }
    });
    //----------------------------------
    //  ColumnRow_CustomSqlExprEditor widget
    //----------------------------------
    $.widget("eqjs.ColumnRow_CustomSqlExprEditor", $.eqjs.ValueEditor_EDIT, {
        _column: null,
        _defaultValue: '',
        _editBoxClass: 'eqjs-qc-ce-editbox',
        _onChange: null,
        options: {
            cssClassPrefix: 'eqjs-qc',
            parentWidget: null
        },
        getColumnsPanel: function () {
            return this.options.parentWidget != null ? this.options.parentWidget.getColumnsPanel() : null;
        },
        init: function (column, defaultValue, changeCallback) {
            this._editBoxClass = this.options.cssClassPrefix + '-ce-editbox';
            this._expr.value = column.expr.sql;
            this._expr.text = column.expr.sql;
            this._column = column;
            this._defaultValue = defaultValue;
            this._onChange = changeCallback;
            this.refresh();
        },
        _render: function () {
            this.clear();
            if (this._column) {
                this._renderCommonPart();
                this._renderEditor();
                this._linkElement.text(this._getDisplayText());
                this._linkElement.attr('title', this._getDisplayText());
            }
        },
        _renderCommonPart: function () {
            var self = this;
            self.element.addClass(self._getClassesToAdd());
            self._linkElement = $('<a></a>', {
                href: 'javascript:void(0)',
                text: '-'
            }).appendTo(self.element);
            self._linkElement.click(function () {
                self._showEditor();
                return false;
            });
        },
        _getClassesToAdd: function () {
            return this.options.cssClassPrefix + '-colelement ' + this.options.cssClassPrefix + '-attrelement';
        },
        _setValue: function (newValue) {
            if (!newValue || newValue == '')
                this._column.expr.sql = this._defaultValue;
            else
                this._column.expr.sql = newValue;
            this._linkElement.text(this._getDisplayText());
            this._linkElement.attr('title', this._column.expr.sql);
            if (this._onChange) {
                this._onChange(newValue);
            }
            return true;
        },
        _getValue: function () {
            return this._column.expr.sql;
        },
        _getText: function () {
            return this._column.expr.sql;
        },
        _getDisplayText: function () {
            var columnsPanel = this.getColumnsPanel();
            var cet = columnsPanel != null ? columnsPanel.options.customExpressionText : 0;
            if (cet == 1) {
                return eqi18n.getText('MsgCustomSql');
            }
            else if (cet == 2) {
                return this._column.caption;
            }
            else {
                if (this._column.expr.sql != '') {
                    return this._column.expr.sql;
                }
                else {
                    return eqi18n.getText('MsgEmptyCustomSql');
                }
            }
        },
        _getZIndex: function () {
            return 100000;
        }
    });
}
//# sourceMappingURL=eq.column.js.map