import { eqi18n, equtils, eqconsts, Query, Expression, ExprTag, DataKind, DataType, Column, SortDirection } from '@easyquery/core';
export function registerValueEditors($) {
    //----------------------------------
    //  ValueEditor base widget
    //----------------------------------
    $.widget("eqjs.ValueEditor", {
        _expr: { value: "", text: "" },
        _linkElement: null,
        options: {
            model: null,
            parentWidget: null,
            editor: null,
            onChange: null,
            emptyText: null
        },
        getModel: function () {
            return this.options.parentWidget ? this.options.parentWidget.getModel() : null;
        },
        getQuery: function () {
            return this.options.parentWidget ? this.options.parentWidget.getQuery() : null;
        },
        getContext: function () {
            return this.options.parentWidget ? this.options.parentWidget.getContext() : null;
        },
        getCondition: function () {
            return this.options.parentWidget && this.options.parentWidget.getCondition ? this.options.parentWidget.getCondition() : null;
        },
        getQueryPanel: function () {
            return this.options.parentWidget && this.options.parentWidget.getQueryPanel ? this.options.parentWidget.getQueryPanel() : null;
        },
        init: function (expr) {
            this._expr = expr;
            this._adjustValueExpr();
            this._adjustExprText();
            this.refresh();
        },
        getResText: function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            return eqi18n.getText.apply(this.getQueryPanel(), args);
        },
        _getEmptyText: function () {
            return this.options.emptyText || this.getResText('MsgEmptyScalarValue'); //'[enter value]';
        },
        _render: function () {
            this.clear();
            if (this.getModel() && this._expr) {
                this._renderCommonPart();
                this._renderEditor();
                var qp = this.getQueryPanel();
                if (qp && qp.options && qp.options.spreadValueElement) {
                    //let maxWidth = this.options.parentWidget.getMaxValueWidth();
                    //this.element.css('max-width', maxWidth);
                    this._linkElement.css('width', '100%');
                    this._linkElement.css('max-width', '100%');
                }
                var txt = this._getDisplayText();
                this._linkElement.text(txt);
                this._linkElement.attr("title", txt);
            }
        },
        _getClassesToAdd: function () {
            return 'eqjs-qp-condelement eqjs-qp-valueelement';
        },
        _renderCommonPart: function () {
            var self = this;
            self.element.addClass(self._getClassesToAdd());
            var cond = this.getCondition();
            if (!cond || (cond.enabled !== false && !cond.readOnly)) {
                self._linkElement = $('<a></a>', {
                    href: 'javascript:void(0)',
                    text: '-'
                }).appendTo(self.element);
                self._linkElement.click(function () {
                    self.showEditor();
                    return false;
                });
            }
            else {
                self._linkElement = $('<span></span>', {
                    text: '-'
                }).appendTo(self.element);
            }
        },
        showEditor: function () {
            if (this._beforeShowEditor()) {
                this._showEditor();
                if (this.options.parentWidget) {
                    this.options.parentWidget.makeActive();
                }
            }
        },
        _renderEditor: function () {
        },
        refresh: function () {
            this._render();
        },
        _beforeShowEditor: function () {
            return true;
        },
        _showEditor: function () {
        },
        _setOption: function (key, value) {
            if (arguments.length == 2) {
                this.options[key] = value;
                this._render();
                return this;
            }
            else {
                return this.options[key];
            }
        },
        clear: function () {
            if (this._linkElement)
                this._linkElement.unbind();
            this.element.removeClass();
            this.element.empty();
        },
        _setValueSilent: function (newValue) {
            var currentValue = this._getValue();
            var adjustedValue = this._adjustNewValue(newValue);
            var res = adjustedValue != currentValue
                ? this._validate(adjustedValue)
                : { result: true };
            if (res && res.result) {
                this._expr.value = adjustedValue;
                this._expr.text = newValue;
                this._adjustExprText();
                var txt = this._getDisplayText();
                this._linkElement.text(txt);
                this._linkElement.html(this._linkElement.html().replace(/ /g, '&nbsp'));
                this._linkElement.attr("title", txt);
                return true;
            }
            else {
                this._validationError(res);
            }
            return false;
        },
        _setValue: function (newValue) {
            var res = this._setValueSilent(newValue);
            if (res && this.options.onChange) {
                this.options.onChange(this._expr.value);
            }
            return res;
        },
        _validate: function (val) {
            return { result: true, message: "" };
        },
        _validationError: function (res) {
            var context = this.getContext();
            context.throwError({
                action: "ui.validation",
                "text": res.message
            });
        },
        _getValue: function () {
            return this._expr.value;
        },
        _getText: function () {
            return this._expr.text;
        },
        _isEmptyValue: function () {
            var v = this._getValue();
            return (typeof (v) === "undefined" || v === null || !v);
        },
        _adjustValueExpr: function () {
            var expr = this._expr;
            if (expr.value) {
                expr.value = this._adjustNewValue(expr.value);
            }
            if (expr.tag == ExprTag.EntityAttribute) {
                expr.kind = DataKind.Attribute;
                expr.value = this._expr.id;
            }
        },
        _adjustExprText: function () {
            var ev = this._expr.value;
            if (ev && !equtils.isObject(ev) && ev != '') { //if not null, not object and not empty
                this._expr.text = ev;
            }
            else {
                this._expr.text = '';
            }
        },
        _adjustNewValue: function (newValue) {
            return newValue;
        },
        _getDisplayText: function () {
            this._adjustExprText();
            if (this._expr.text && this._expr.text != '')
                return this._expr.text;
            else if (this._expr.value && this._expr.value != '')
                return this._expr.value;
            else
                return this._getEmptyText();
        }
    });
    $.widget("eqjs.ValueEditor_EDIT", $.eqjs.ValueEditor, {
        _numberDecimalSeparatorValue: '.',
        _numberListSeparatorValue: ',',
        _numberDecimalSeparatorDisplay: '.',
        _numberListSeparators: [',', ';'],
        _editBox: null,
        _editBoxClass: 'eqjs-qp-ve-editbox',
        _create: function () {
            var queryPanel = this.getQueryPanel();
            if (queryPanel) {
                if (queryPanel.options.numberDecimalSeparatorDisplay)
                    this._numberDecimalSeparatorDisplay = queryPanel.options.numberDecimalSeparatorDisplay || eqi18n.getLocaleSetting('decimalSeparator');
                if (queryPanel.options.numberListSeparators)
                    this._numberListSeparators = queryPanel.options.numberListSeparators;
            }
        },
        _adjustNewValue: function (newValue) {
            if (newValue.length > 0 && this._expr.kind == "List") {
                var reg = new RegExp("\\s*[" + this._numberListSeparators.join('') + "]\\s*", "i");
                var arrVal = newValue.split(reg);
                var arrLength = arrVal.length;
                for (var idx = 0; idx < arrLength; idx++) {
                    arrVal[idx] = this._adjustScalarValue(arrVal[idx]);
                }
                return arrVal.join(this._numberListSeparatorValue);
            }
            else {
                return this._adjustScalarValue(newValue);
            }
        },
        _adjustScalarValue: function (val) {
            var result = val.split(this._numberDecimalSeparatorDisplay).join(this._numberDecimalSeparatorValue);
            return result;
        },
        //        _adjustExprText: function () {
        //            //nothing to do
        //        },
        _renderEditor: function () {
            var self = this;
            self.dontProcessBlur = false;
            self._editBox = $('<input />', {
                'type': 'text',
                'class': self._editBoxClass,
                blur: function (e) {
                    if (self._editBox.is(':visible') && !self.dontProcessBlur) {
                        if (self._setValue(self._editBox.val())) {
                            self._editBox.hide();
                            self._linkElement.show();
                        }
                        else {
                            self.dontProcessBlur = true;
                            self._editBox.focus();
                            setTimeout(function () {
                                self.dontProcessBlur = false;
                            }, 200);
                        }
                        e.stopPropagation();
                        return false;
                    }
                },
                keydown: function (e) {
                    if (e.keyCode == 13) { // if - enter
                        if (self._editBox.is(':visible')) {
                            self.dontProcessBlur = true;
                            if (self._setValue(self._editBox.val())) {
                                self._editBox.hide();
                                self._linkElement.show();
                                self.dontProcessBlur = false;
                            }
                            else {
                                self._editBox.focus();
                                setTimeout(function () { self.dontProcessBlur = false; }, 200);
                            }
                            e.stopPropagation();
                            return false;
                        }
                    }
                    if (e.keyCode == 27) { // if - esc
                        self._editBox.hide();
                        self._linkElement.show();
                        e.stopPropagation();
                        return false;
                    }
                }
            }).appendTo(this.element).hide();
        },
        _checkScalarValue: function (val) {
            var parsedVal = +val;
            var expr = this._expr;
            if (isNaN(parsedVal) || (equtils.isNumericType(expr.dataType) && ($.trim(val) != val))) {
                return {
                    result: false,
                    message: '"' + val + '"' + this.getResText('ErrNotNumber')
                };
            }
            else if (equtils.isIntType(expr.dataType) && parsedVal != parseInt(val, 10)) {
                return {
                    result: false,
                    message: val + ' - ' + this.getResText('ErrIncorrectInteger')
                };
            }
            return { result: true, message: '' };
        },
        _validate: function (val) {
            var scalarRes;
            var expr = this._expr;
            if (equtils.isNumericType(expr.dataType)) {
                if (val.length > 0 && expr.kind === DataKind.List) {
                    var arrVal = val.split(/\s*,\s*/);
                    var arrLength = arrVal.length;
                    for (var idx = 0; idx < arrLength; idx++) {
                        scalarRes = this._checkScalarValue(arrVal[idx]);
                        if (!scalarRes || !scalarRes.result) {
                            return {
                                result: false,
                                message: this.getResText('ErrIncorrectNumberList')
                            };
                        }
                    }
                    return { result: true };
                }
                else {
                    return this._checkScalarValue(val);
                }
            }
            else {
                return { result: true };
            }
        },
        _getZIndex: function () {
            var queryPanel = this.getQueryPanel();
            return (queryPanel && queryPanel.options.isSubQuery) ? queryPanel.options.dialogZIndex + 1000 : 100000;
        },
        _showEditor: function () {
            var self = this;
            var width = self.element.width();
            self._linkElement.hide();
            self._editBox
                .val(self._getText())
                .css('min-width', width)
                .show()
                .focus();
        }
    });
    $.widget("eqjs.ValueEditor_DATETIME", $.eqjs.ValueEditor_EDIT, {
        _dateFormatInternal: 'yy-mm-dd',
        _dateFormatValue: 'mm/dd/yy',
        _dateFormatDisplay: 'd mm, yy',
        _dateValue: '',
        _timeFormatInternal: 'HH:mm',
        _timeFormatValue: 'HH:mm',
        _timeFormatDisplay: 'HH:mm',
        _yearRange: 'c-10:c+10',
        _create: function () {
            var queryPanel = this.getQueryPanel();
            var qpOptions = queryPanel ? queryPanel.options : {};
            this._dateFormatValue = this.options.dateFormatValue || qpOptions.dateFormatValue || this._dateFormatValue;
            this._dateFormatDisplay = this.options.dateFormatDisplay || qpOptions.dateFormatDisplay || eqi18n.getLocaleSetting('dateFormat');
            this._timeFormatValue = this.options.timeFormatValue || qpOptions.timeFormatValue || this._timeFormatValue;
            this._timeFormatDisplay = this.options.timeFormatDisplay || qpOptions.timeFormatDisplay || this._timeFormatDisplay;
            this._yearRange = this.options.yearRange || qpOptions.yearRange || this._yearRange;
            $.datepicker.setDefaults($.datepicker.regional[eqi18n.getCurrentLocale()]);
            $.timepicker.setDefaults($.timepicker.regional[eqi18n.getCurrentLocale()]);
        },
        _renderEditor: function () {
            var self = this;
            self._editBox = $('<input />', {
                'type': 'text',
                'class': 'eqjs-qp-ve-editbox'
            }).appendTo(self.element).hide();
            self._editBox.on('keydown', function (e) {
                if (e.keyCode == 27) {
                    self._editBox.val(self.lastValue);
                }
            });
            if (self._expr.dataType === DataType.Time) {
                self._editBox.timepicker({
                    onClose: function (dateText, inst) {
                        if (dateText != "") {
                            var model = self.getModel();
                            var pickerDate = self._editBox.datepicker('getDate');
                            var timeVal = self._convertTime(pickerDate, self._timeFormatInternal);
                            if (dateText != self.lastValue) {
                                self._setValue(timeVal);
                            }
                            self._editBox.hide();
                        }
                        else {
                            self._editBox.hide();
                            self._editBox.timepicker('hide');
                        }
                    }
                });
                if (self._timeFormatValue) {
                    self._editBox.timepicker("option", "timeFormat", self._timeFormatValue);
                }
                else {
                    self._timeFormatValue = self._editBox.datepicker("option", "timeFormat");
                }
            }
            else if (self._expr.dataType === DataType.Date) { //Date
                var model = this.getModel();
                self._editBox.datepicker({
                    changeMonth: true,
                    changeYear: true,
                    beforeShow: function () {
                        self._editBox.show();
                    },
                    onClose: function (dateText, inst) {
                        if (dateText != "") {
                            var model_1 = self.getModel();
                            var pickerDate = self._editBox.datepicker('getDate');
                            var dateVal = self._convertDate(pickerDate, self._dateFormatInternal);
                            if (dateText != self.lastValue) {
                                self._setValue(dateVal);
                            }
                            self._editBox.hide();
                        }
                        else {
                            self._editBox.hide();
                            self._editBox.datepicker('hide');
                        }
                    }
                });
                if (self._dateFormatValue) {
                    self._editBox.datepicker("option", "dateFormat", self._dateFormatValue);
                }
                else {
                    self._dateFormatValue = self._editBox.datepicker("option", "dateFormat");
                }
                if (self._yearRange) {
                    self._editBox.datepicker("option", "yearRange", self._yearRange);
                }
                else {
                    self._yearRange = self._editBox.datepicker("option", "yearRange");
                }
            }
            else if (self._expr.dataType === DataType.DateTime) { //DateTime
                self._editBox.datetimepicker({
                    changeMonth: true,
                    changeYear: true,
                    beforeShow: function () {
                        self._editBox.show();
                    },
                    onClose: function (dateText, inst) {
                        if (dateText != "") {
                            var lastVals = self.lastValue.split(' '); //inst.lastVal.split(' ');
                            var lastDate = '';
                            var lastTime = '';
                            lastDate = lastVals[0];
                            if (lastVals.length > 1) {
                                lastTime = lastVals[1];
                            }
                            var pickerDate = self._editBox.datepicker('getDate');
                            var dateVal = self._convertDate(pickerDate, self._dateFormatInternal);
                            var timeVal = self._convertTime(pickerDate, self._timeFormatInternal);
                            var resDate = '';
                            var resTime = '';
                            var origVals = self._expr.value.split(' ');
                            if (dateVal != self._convertDateString(lastDate, self._dateFormatValue, self._dateFormatInternal)) {
                                resDate = dateVal;
                            }
                            else {
                                resDate = origVals[0];
                            }
                            if (timeVal != self._convertTimeString(lastTime, self._timeFormatValue, self._timeFormatInternal)) {
                                resTime = timeVal;
                            }
                            else if (origVals.length > 1) {
                                resTime = origVals[1];
                            }
                            if (dateText != self.lastValue) {
                                self._setValue($.trim(resDate + " " + resTime));
                            }
                            self._editBox.hide();
                        }
                        else {
                            self._editBox.hide();
                            self._editBox.datepicker('hide');
                        }
                    }
                });
                if (self._dateFormatValue) {
                    self._editBox.datepicker("option", "dateFormat", self._dateFormatValue);
                }
                else {
                    self._dateFormatValue = self._editBox.datepicker("option", "dateFormat");
                }
                if (self._yearRange) {
                    self._editBox.datepicker("option", "yearRange", self._yearRange);
                }
                else {
                    self._yearRange = self._editBox.datepicker("option", "yearRange");
                }
                if (self._timeFormatValue) {
                    self._editBox.timepicker("option", "timeFormat", self._timeFormatValue);
                }
                else {
                    self._timeFormatValue = self._editBox.datepicker("option", "timeFormat");
                }
            }
        },
        _showEditor: function () {
            var self = this;
            var model = this.getModel();
            if (self._expr.dataType === DataType.Time) {
                var timeValue = this._expr.value; //self._getValue();
                var time = model.getTimeMacroValue(timeValue);
                if (time) {
                    timeValue = this._convertTime(time, this._timeFormatInternal);
                }
                self._editBox.val(this._convertTimeString(timeValue, this._timeFormatInternal, this._timeFormatValue));
            }
            else if (self._expr.dataType === DataType.Date) { //Date
                var dateValue = this._expr.value;
                var date = model.getDateMacroValue(dateValue);
                if (date) {
                    dateValue = this._convertDate(date, this._dateFormatInternal);
                }
                self._editBox.val(this._convertDateString(dateValue, this._dateFormatInternal, this._dateFormatValue));
            }
            else if (self._expr.dataType === DataType.DateTime) { //DateTime
                var dtValues = this._expr.value.split(' ');
                var dateTimeValue = this._expr.value;
                var dateValue = '';
                var timeValue = '';
                dateValue = dtValues[0];
                if (dtValues.length > 1) {
                    timeValue = dtValues[1];
                }
                var date = model.getDateMacroValue(dateValue);
                if (date) {
                    dateValue = this._convertDate(date, this._dateFormatInternal);
                }
                var time = model.getTimeMacroValue(timeValue);
                if (time) {
                    timeValue = this._convertTime(time, this._timeFormatInternal);
                }
                self._editBox.val(this._convertDateString(dateValue, this._dateFormatInternal, this._dateFormatValue) + " " + this._convertTimeString(timeValue, this._timeFormatInternal, this._timeFormatValue));
            }
            self.lastValue = self._editBox.val();
            var queryPanel = this.getQueryPanel();
            var zindex = (queryPanel && queryPanel.options.isSubQuery) ? queryPanel.options.dialogZIndex + 1000 : 100000;
            var l = self._linkElement.position().left;
            var t = self._linkElement.position().top;
            self._editBox
                .css({
                left: l,
                top: t,
                width: self._expr.dataType === DataType.DateTime ? "150px" : "115px",
                "min-width": self._linkElement.width(),
                position: 'absolute',
                zIndex: zindex
            })
                .show()
                .focus();
        },
        _adjustNewValue: function (newValue) {
            var model = this.getModel();
            if (this._expr.dataType === DataType.Date) {
                if (model && model.isDateMacro(newValue)) {
                    return newValue;
                }
                else {
                    return this._convertDateValueString(newValue, this._dateFormatInternal, this._dateFormatInternal);
                }
            }
            else if (this._expr.dataType === DataType.DateTime) {
                var dtValues = newValue.split(' ');
                var dateValue = '';
                var timeValue = '';
                dateValue = dtValues[0];
                if (dtValues.length > 1) {
                    timeValue = dtValues[1];
                }
                if (model && !model.isDateMacro(dateValue)) {
                    dateValue = this._convertDateValueString(dateValue, this._dateFormatInternal, this._dateFormatInternal);
                }
                if (timeValue == '') {
                    return $.trim(dateValue);
                }
                else {
                    if (model && !model.isTimeMacro(timeValue)) {
                        timeValue = this._convertTimeValueString(timeValue, this._timeFormatInternal, this._timeFormatInternal);
                    }
                    return $.trim(dateValue + " " + timeValue);
                }
            }
            else if (this._expr.dataType === DataType.Time) {
                if (model && model.isTimeMacro(newValue)) {
                    return newValue;
                }
                else {
                    return this._convertTimeValueString(newValue, this._timeFormatInternal, this._timeFormatInternal);
                }
            }
        },
        _adjustExprText: function () {
            try {
                if (this._expr.value && this._expr.value != '') {
                    if (this._expr.dataType === DataType.Date) {
                        this._expr.text = this._convertDateValueString(this._expr.value, this._dateFormatInternal, this._dateFormatDisplay);
                    }
                    else if (this._expr.dataType === DataType.DateTime) {
                        var dtValues = this._expr.value.split(' ');
                        var dateValue = this._expr.value;
                        var timeValue = "";
                        if (dtValues.length > 1) {
                            dateValue = dtValues[0];
                            timeValue = dtValues[1];
                        }
                        try {
                            dateValue = this._convertDateValueString(dateValue, this._dateFormatInternal, this._dateFormatDisplay);
                        }
                        catch (err) {
                            dateValue = '';
                        }
                        try {
                            timeValue = this._convertTimeValueString(timeValue, this._timeFormatInternal, this._timeFormatDisplay);
                        }
                        catch (err) {
                            timeValue = '';
                        }
                        this._expr.text = (dateValue == '' || timeValue == '') ? dateValue + timeValue : dateValue + " " + timeValue;
                    }
                    else if (this._expr.dataType === DataType.Time) {
                        this._expr.text = this._convertTimeValueString(this._expr.value, this._timeFormatInternal, this._timeFormatDisplay);
                    }
                }
                else {
                    this._expr.text = '';
                }
            }
            catch (err) {
                this._expr.text = '';
            }
        },
        _validate: function (val) {
            return { result: true, message: "" };
        },
        _convertDateValueString: function (value, from, to) {
            var model = this.getModel();
            var defValue = '${Today}';
            if (model && model.isDateMacro(value)) {
                var macroText = value.substring(2, value.length - 1);
                var res = this.getResText(macroText);
                return res ? res : defValue;
            }
            else {
                var res = this._convertDateString(value, from, to);
                return res ? res : defValue;
            }
        },
        _convertDateString: function (value, from, to) {
            try {
                var theDate = $.datepicker.parseDate(from, value);
                return this._convertDate(theDate, to);
            }
            catch (err) {
                return '';
            }
        },
        _convertDate: function (value, to) {
            return $.datepicker.formatDate(to, value);
        },
        _convertTime: function (value, to) {
            var time = {
                hour: value.getHours(),
                minute: value.getMinutes(),
                second: value.getSeconds(),
                millisec: value.getMilliseconds(),
                microsec: value.getMicroseconds(),
                timezone: value.getTimezoneOffset() * -1
            };
            return $.datepicker.formatTime(to, time);
        },
        _convertTimeValueString: function (value, from, to) {
            var model = this.getModel();
            if (model && ($.inArray(value, model.timeMacroList) >= 0)) {
                var macroText = value.substring(2, value.length - 1);
                var res = this.getResText(macroText);
                return res ? res : '';
            }
            else {
                var res = this._convertTimeString(value, from, to);
                return res ? res : '';
            }
        },
        _convertTimeString: function (value, from, to) {
            try {
                var theTime = $.datepicker.parseTime(from, value);
                return theTime ? $.datepicker.formatTime(to, theTime) : '';
            }
            catch (err) {
                return '';
            }
        }
    });
    $.widget("eqjs.ValueEditor_LIST", $.eqjs.ValueEditor, {
        _menuBlock: null,
        _menuItemsList: null,
        _emptyListText: '<empty list>',
        _showWhenReady: false,
        _getEmptyText: function () {
            if (this._menuItemsList && (this._menuItemsList.length > 0)) {
                return this.options.emptyText || this.getResText('MsgEmptyListValue'); //'[select value]';
            }
            else {
                return this.options.emptyText || this._emptyListText;
            }
        },
        _getListName: function () {
            return this.options.editor.name;
        },
        _renderEditor: function () {
            var self = this;
            self._fillMenuItemsList();
            self._renderMenuBlock();
        },
        _renderMenuBlock: function () {
            var self = this;
            var multiSelect = false;
            if (this._expr) {
                multiSelect = this._expr.kind === DataKind.List;
            }
            var queryPanel = this.getQueryPanel();
            var options = {
                "items": self._menuItemsList,
                "multiselect": multiSelect,
                "container": queryPanel ? queryPanel.options.menuContainer : null,
                onMenuItemSelected: function (evt, data) {
                    if (!multiSelect) {
                        self._setValue(data.menuItem.id);
                    }
                    else if (data.selectedItems) {
                        var selectedIds = [];
                        var selLength = data.selectedItems.length;
                        for (var i = 0; i < selLength; i++)
                            selectedIds.push(data.selectedItems[i].id);
                        self._setValue(selectedIds);
                    }
                    return false;
                }
            };
            if (queryPanel) {
                $.extend(options, queryPanel.options.menuOptions);
            }
            ;
            if (queryPanel && queryPanel.options.isSubQuery) {
                options['zIndex'] = queryPanel.options.dialogZIndex + 1000;
            }
            var menuId = self.options.parentWidget.element.attr('id');
            if (menuId) {
                options['id'] = menuId + '-EditorMenu';
            }
            if (queryPanel) {
                options['domWriteItemsId'] = queryPanel.options.domWriteItemsId;
            }
            ;
            options['buttons'] = {
                submit: eqi18n.getText('ButtonApply'),
                cancel: eqi18n.getText('ButtonCancel')
            };
            self._menuBlock = $('<div></div>')
                .hide()
                .appendTo(self.element)
                .PopupMenu(options);
        },
        _beforeShowEditor: function () {
            var listName = this._getListName();
            if (listName && listName.match(/{{.+?}}/)) {
                this._showWhenReady = true;
                this._renderEditor();
                return false;
            }
            else
                return true;
        },
        _showEditor: function () {
            var self = this;
            if (self._menuBlock) {
                this._menuBlock.PopupMenu('showMenu', { anchor: self._linkElement, selectedIds: self._getValueAsArray() });
            }
            else {
                this._showWhenReady = true;
            }
        },
        _getValueAsArray: function () {
            var self = this;
            if (self._expr.kind !== DataKind.List) {
                return [self._expr.value];
            }
            else {
                var res = self._expr.value.match(/"[^"\\]*(?:\\.[^"\\]*)*"|[^,]+/g);
                if (res) {
                    return $.map(res, function (a) {
                        if (a.charAt(0) == '"' && a.charAt(a.length - 1) == '"') {
                            a = a.substring(1, a.length - 1);
                            return a.replace(/\"/g, '"');
                        }
                        else {
                            return a;
                        }
                    });
                }
                else {
                    return [];
                }
            }
        },
        _adjustNewValue: function (newValue) {
            if ($.isArray(newValue)) {
                var arr = $.map(newValue, function (a) {
                    if (a.indexOf(',') >= 0) {
                        a = a.replace(/"/g, '\"');
                        return '"' + a + '"';
                    }
                    else {
                        return a;
                    }
                });
                return arr.join(',');
            }
            else {
                return newValue;
            }
        },
        _adjustExprText: function () {
            var self = this;
            var arrValues, arrTexts = [], match;
            if (self._expr.value && self._menuItemsList) {
                arrValues = self._getValueAsArray();
                self._expr.text = '';
                var arrLength = arrValues.length;
                var fillTexts_1 = function (menuItems) {
                    var item;
                    for (var idx = 0; idx < menuItems.length; idx++) {
                        item = menuItems[idx];
                        if (item.items) {
                            fillTexts_1(item.items);
                        }
                        else {
                            match = $.grep(arrValues, function (value) {
                                return (item.id == value);
                            });
                            if (match.length > 0) {
                                arrTexts.push(item.text);
                            }
                        }
                    }
                };
                fillTexts_1(self._menuItemsList);
                self._expr.text = arrTexts.join(',');
            }
            else {
                self._expr.text = '';
            }
        },
        _takeFirstItemInList: function () {
            if (this._menuItemsList && this._menuItemsList.length > 0) {
                this._setValueSilent(this._menuItemsList[0].id);
            }
        },
        _takeDefaultValue: function () {
            if (!this._menuItemsList)
                return;
            var itemLen = this._menuItemsList.length;
            for (var i = 0; i < itemLen; i++) {
                var item = this._menuItemsList[i];
                if (item.isDefault) {
                    this._setValueSilent(item.id);
                    break;
                }
            }
        },
        _fillMenuItemsList: function () {
            this._menuItemsList = this.options.editor.values;
            //this._takeFirstItemInList();
        }
    });
    $.widget("eqjs.ValueEditor_CUSTOMLIST", $.eqjs.ValueEditor_LIST, {
        _loaderElement: null,
        _renderEditor: function () {
            var self = this;
            this._linkElement.hide();
            if (!this._loaderElement) {
                this._loaderElement = $('<div></div>', {
                    'class': 'eqjs-qp-ve-loader'
                }).appendTo(self.element);
            }
            this._loaderElement.show();
            if (this._loading)
                return;
            this._loading = true;
            this._fillMenuItemsList(function () {
                self._loading = false;
                var txt = self._getDisplayText();
                self._linkElement.text(txt);
                self._linkElement.attr("title", txt);
                self._loaderElement.hide();
                self._linkElement.show();
                self._renderMenuBlock();
                if (self._isEmptyValue()) {
                    self._takeDefaultValue();
                }
                //self._takeFirstItemInList();
                if (self._showWhenReady) {
                    self._showWhenReady = false;
                    self._showEditor();
                }
            });
        },
        _fillMenuItemsList: function (onComplete) {
            var self = this, editor = this.options.editor, listName = this._getListName(), listRequestHandler = this.getContext().getListRequestHandler();
            var queryPanel = this.getQueryPanel();
            if (eqconsts.constLists[listName]) {
                self._menuItemsList = eqconsts.constLists[listName];
                if (onComplete) {
                    onComplete();
                }
            }
            else if (listName === "EntityTree") {
                self._menuItemsList = queryPanel.options.entitiesList;
                if (onComplete) {
                    onComplete();
                }
            }
            else if (listRequestHandler) {
                listRequestHandler({
                    "listName": listName,
                    "editorId": editor.id,
                    "value": self._getValue()
                }, function (list) {
                    self._menuItemsList = list;
                    if (onComplete) {
                        onComplete();
                    }
                });
            }
        }
    });
    $.widget("eqjs.ValueEditor_SQLLIST", $.eqjs.ValueEditor_CUSTOMLIST, {
        _fillMenuItemsList: function (onComplete) {
            var self = this;
            var context = this.getContext();
            var editor = this.options.editor;
            var listRequestHandler = context.getListRequestHandler();
            if (listRequestHandler) {
                var requestData = {
                    listName: "SQL",
                    editorId: editor.id,
                    value: self._getValue()
                };
                //requestData.sql = editor.sql;
                listRequestHandler(requestData, function (list) {
                    self._menuItemsList = list;
                    if (onComplete) {
                        onComplete();
                    }
                });
            }
        }
    });
    $.widget("eqjs.ValueEditor_SUBQUERY", $.eqjs.ValueEditor, {
        _dialogBlock: null,
        _queryPanelBlock: null,
        _columnElement: null,
        _colEntitiesList: null,
        _getEmptyText: function () {
            return this.getResText('MsgSubQueryValue'); //'[edit sub-query]';
        },
        _renderEditor: function () {
            var self = this;
            this._dialogBlock = $('<div></div>', {
                'class': 'eqjs-qp-ve-subquery'
            }).hide().appendTo(self.element);
            var parentPanel = this.getQueryPanel();
            var model = this.getModel();
            var exprType = this._expr.dataType;
            this._colEntitiesList = model.getEntitiesTreeWithFilter(function (item) {
                if (item.attributes && item.useInConditions) //if it's entity - return true
                    return true;
                return item.usedInCondition && (item.dataType === exprType);
            });
            var colEntitiesMenu = $('<div></div>')
                .hide()
                .appendTo(self._dialogBlock);
            var menuId = self.options.parentWidget.element.attr('id');
            if (menuId) {
                menuId += '-SubColumnMenu';
            }
            var colMenuOptions = $.extend({
                id: menuId,
                "items": self._colEntitiesList,
                "zIndex": parentPanel.options.dialogZIndex + 1000,
                domWriteItemsId: parentPanel.options.domWriteItemsId,
                isSubQuery: true
            }, parentPanel.options.menuOptions);
            colEntitiesMenu.PopupMenu(colMenuOptions);
            var columnBlock = $('<div></div>')
                .addClass('eqjs-qp-ve-subquery-column')
                .appendTo(self._dialogBlock);
            var columnTitle = $('<div></div>')
                .addClass('eqjs-qp-ve-subquery-column-title')
                .text(self.getResText('SubQueryColumnTitle')) //'Column:';
                .appendTo(columnBlock);
            var columnElementBlock = $('<div></div>')
                .addClass('eqjs-qp-ve-subquery-column-element')
                .appendTo(columnBlock);
            self._columnElement = $('<a></a>')
                .attr('href', "javascript:void(0)")
                .appendTo(columnElementBlock);
            self._columnElement.click(function (e) {
                colEntitiesMenu.PopupMenu('showMenu', {
                    anchor: self._columnElement,
                    selectedIds: null,
                    itemSelectedCallback: function (evt, data) {
                        return self._columnElementMenuClick(evt, data);
                    }
                });
            });
            var queryPanelCaptionBlock = $('<div></div>')
                .addClass('eqjs-qp-ve-subquery-qp-caption')
                .text(self.getResText('SubQueryQueryPanelCaption')) //'Conditions';
                .appendTo(self._dialogBlock);
            self._queryPanelBlock = $('<div class="eqjs-qp-ve-subquery-qp"></div>').appendTo(self._dialogBlock);
            var qpId = self.options.parentWidget.element.attr('id');
            if (qpId) {
                self._queryPanelBlock.attr('id', qpId + '-SubQueryPanel');
            }
            self._dialogBlock.dialog({
                autoOpen: false,
                draggable: false,
                resizable: false,
                title: self.getResText('SubQueryDialogTitle'),
                dialogClass: 'eq-js-dialog',
                closeText: "X",
                modal: true,
                width: parentPanel.options.subQueryDialogWidth,
                minHeight: parentPanel.options.subQueryDialogHeight,
                zIndex: parentPanel.options.dialogZIndex,
                buttons: [
                    {
                        name: 'eqjs-subquery-button-ok',
                        text: self.getResText('ButtonOK'),
                        click: function () {
                            $(this).dialog("close");
                            var query = self.getQuery();
                            query.fireChangedEvent({
                                "author": self.getQueryPanel(),
                                "changeType": "condition.changed",
                                "condition": self.getCondition(),
                                "what": "value"
                            });
                        }
                    },
                    {
                        name: 'eqjs-subquery-button-cancel',
                        text: self.getResText('ButtonCancel'),
                        click: function () {
                            $(this).dialog("close");
                        }
                    }
                ],
                open: function () {
                    $('.ui-widget-overlay').addClass('eq-js-dialog-overlay');
                    $('body').css('overflow', 'hidden');
                },
                beforeClose: function () {
                    $('.ui-widget-overlay').removeClass('eq-js-dialog-overlay');
                    $('body').css('overflow', 'auto');
                },
                close: function (event, ui) {
                    self._queryPanelBlock.QueryPanel('destroy');
                }
            });
        },
        _columnElementMenuClick: function (evt, data) {
            var self = this;
            var attrid = data.menuItem.data('id');
            this._setResultAttributeId(attrid);
            return false;
        },
        _setResultAttributeId: function (attrId) {
            var attrObj = this.getModel().getAttributeById(attrId);
            if (attrObj) {
                var subQuery = this.getSubQuery();
                var cols = subQuery.getColumns();
                var column = void 0;
                if (cols.length > 0) {
                    column = cols[0];
                    column.expr.id = attrId;
                    column.expr.dataType = attrObj.dataType;
                    ;
                }
                else {
                    column = new Column();
                    column.sorting = SortDirection.None;
                    column.sortIndex = -1;
                    var expr = new Expression();
                    expr.id = attrId;
                    expr.tag = ExprTag.EntityAttribute;
                    expr.kind = DataKind.Attribute;
                    expr.dataType = attrObj.dataType;
                    column.expr = expr;
                    cols.push(column);
                }
                var parentQuery = this.getQuery();
                var parentPanel = this.getQueryPanel();
                parentQuery.fireChangedEvent({
                    "author": parentPanel,
                    "changeType": "subQuery.column.change",
                    "column": column
                });
                this._columnElement.text(this._getAttributeText(attrObj));
                this._okButtonEnable(true);
            }
        },
        _getAttributeText: function (attribute) {
            var self = this;
            if (!attribute)
                return self.getResText('SubQueryEmptyColumn');
            var attrText = eqi18n.getText('Attributes', attribute.id);
            if (!attrText)
                attrText = attribute.caption;
            var parentPanel = this.getQueryPanel();
            var format = parentPanel.options.attrElementFormat;
            if (!format)
                return attrText;
            var result = format.replace(new RegExp("{attr}", 'g'), attrText);
            var entityPath = self.getModel().getFullEntityPathByAttr(attribute.id, '.');
            result = result.replace(new RegExp("{entity}", 'g'), entityPath);
            return result;
        },
        _showEditor: function () {
            var self = this;
            var parentQuery = this.getQuery();
            var parentPanel = this.getQueryPanel();
            self._queryPanelBlock.empty();
            var subQuery = this._expr.query;
            if (!subQuery) {
                subQuery = new Query(parentQuery.getModel());
                this._expr.query = subQuery;
            }
            //subQuery.clientListRequestHandler = parentQuery.clientListRequestHandler;
            //subQuery.serverListRequestHandler = parentQuery.serverListRequestHandler;
            subQuery.addChangedCallback(function (event) {
                var mqep = $.extend({}, event.data);
                mqep.author = parentPanel;
                mqep.changeType = "subQuery." + mqep.changeType;
                parentQuery.fireChangedEvent(mqep);
            });
            var subOptions = $.extend({}, parentPanel.options);
            subOptions.isSubQuery = true;
            subOptions.showAddRow = true;
            subOptions.menuContainer = document.body;
            subOptions.menuOptions.isSubQuery = true;
            subOptions.entitiesListFilter = function (listItems, listOptions) {
                if (parentPanel.options.entitiesListFilter) {
                    var subQueryPanelListOptions = listOptions || {};
                    subQueryPanelListOptions.isSubQuery = true;
                    parentPanel.options.entitiesListFilter(listItems, subQueryPanelListOptions);
                }
            };
            self._queryPanelBlock.QueryPanel(subOptions);
            self._queryPanelBlock.QueryPanel("setContext", this.getContext());
            self._queryPanelBlock.QueryPanel("setQuery", subQuery);
            var attrId = null;
            var cols = subQuery.getColumns();
            ;
            if (cols.length == 0) {
                var condition = this.getCondition();
                if (condition.expressions.length > 0) {
                    var attrExpr = condition.expressions[0];
                    attrId = (attrExpr.tag == ExprTag.EntityAttribute || attrExpr.kind == DataKind.Attribute) ? attrExpr.id : null;
                }
            }
            else {
                attrId = cols[0].expr.id;
            }
            if (attrId) {
                this._setResultAttributeId(attrId);
            }
            else {
                this._columnElement.text(this.getResText("SubQueryEmptyColumn"));
            }
            self._dialogBlock.dialog('open');
        },
        getSubQuery: function () {
            return this._queryPanelBlock.QueryPanel("getQuery");
        },
        _okButtonEnable: function (enabled) {
            var buttonOk = this._dialogBlock.next(".ui-dialog-buttonpane").find("[name='eqjs-subquery-button-ok']");
            if (buttonOk) {
                if (enabled) {
                    buttonOk.button("enable");
                }
                else {
                    buttonOk.button("disable");
                }
            }
        },
        _getDisplayText: function () {
            return this._getEmptyText();
        }
    });
    $.widget("eqjs.PredicateLinkType", $.eqjs.ValueEditor_LIST, {
        _predicate: null,
        options: {
            queryPanel: null
        },
        getCondition: function () {
            return this._predicate;
        },
        init: function (predicate) {
            this._predicate = predicate;
            this.refresh();
        },
        _render: function () {
            this.clear();
            if (this._predicate) {
                this._renderCommonPart();
                if (this._predicate.enabled !== false && !this._predicate.readOnly) {
                    this._renderEditor();
                }
                this._linkElement.text(this._getDisplayText());
            }
        },
        _showEditor: function () {
            var self = this;
            self._menuBlock.PopupMenu('showMenu', { anchor: self._linkElement }); //, self._predicate.linkType);
        },
        _fillMenuItemsList: function () {
            this._menuItemsList = eqconsts.predicateLinkTypeList;
        },
        _setValue: function (newValue) {
            this._predicate.linkType = equtils.strToLinkType(newValue);
            this._linkElement.text(this._getDisplayText());
            if (this.options.onChange) {
                this.options.onChange(newValue);
            }
            return true;
        },
        _beforeShowEditor: function () {
            return true;
        },
        _getClassesToAdd: function () {
            return 'eqjs-qp-predelement eqjs-qp-predvalueelement';
        },
        _getDisplayText: function () {
            var self = this, result = this._getEmptyText();
            if (typeof this._predicate.linkType != "undefined") {
                $.each(eqconsts.predicateLinkTypeList, function () {
                    if (this.id === equtils.linkTypeToStr(self._predicate.linkType)) {
                        result = this.text;
                    }
                });
            }
            return result;
        }
    });
}
//# sourceMappingURL=eq.valueeditor.js.map