//#region Исполнители
function ExecutorsItemData(observer) {
    var that = this;

    var args = [];
    args.push(observer);
    args.push({
        group: 'taskexecutors',
        name: 'taskexecutors',
        selector: '#executorids',
        useDefaultEvent: true,
        initConflictAfterSubmit: {
            //compareEqualsCurrentWithSubmitValue: false,
            canConflict: false
        },
    });
    ItemData.apply(this, args);

    if (this.IsOnForm() && this.TaskRightsDisplayType() != ItemDataHelper.TaskRightsDisplayType.None) {

        $('#addexecutor').devbridgeAutocomplete({
            serviceUrl: 'Task/FindExecutors/' + $('#serviceid').val(),
            autoQueryOnEmptyField: true,
            minChars: 1,
            rightOrientation: true,
            containerClass: 'autocomplete-suggestions executorsearchContainer',
            width: '400',
            maxWidth: '400',
            widthImportant: true,
            params: {
                deadline: function () { return $('#deadline').val(); },
                executorgroupid: function () { return ($('#executorsfromexecutorgroup') && $('#executorsfromexecutorgroup').val() == 'True' && $('#executorgroupid')) ? $('#executorgroupid').val() : '' }
            },
            autoClearInputOnSelect: true,
            //onSelect: addUser,
            formatDivClassResult: function (suggestion) {
                var classCss = 'executorSearch';
                if (suggestion.data.firstAdded)
                    classCss += ' topBorder';
                return classCss;
            },
            onSelect: function (suggestion) {
                if (suggestion.data.isAddToService) {
                    setTimeout(function () {
                        if (suggestion.data.roleInService) {
                            alertDialog(TaskResources.UserNotOnService, TaskResources.AddUserOnService.replace('{0}', suggestion.data.systemRoleName), function () {
                                that.addUserOnServiceAndTask(suggestion);
                            });
                        }
                        else {
                            $.ajax({
                                url: base + 'task/GetServiceRoles',
                                data: { serviceid: $('#serviceid').val() },
                                type: 'POST',
                                success: function (response) {
                                    if (response != null && response.roles != null && response.roles.length > 0) {
                                        var roles = '<select id="addUserWithRole" class="px200">'
                                        for (var i = 0; i < response.roles.length; i++) {
                                            var selected = i == 0 ? ' selected="true"' : '';
                                            roles += '<option value="' + response.roles[i].Id + '"' + selected + '>' + response.roles[i].Name + '</option>';
                                        }
                                        roles += '</select>';
                                        alertDialog(TaskResources.UserNotOnService, TaskResources.AddUserOnService.replace('{0}', roles), function () {
                                            that.addUserOnServiceAndTask(suggestion, true);
                                        });
                                    }
                                    else {
                                        alertDialog(CommonResources.Error, TaskResources.ExecRolesOnServiceNotFound);
                                    }
                                },
                                error: function (XMLHttpRequest, textStatus, errorThrown) {
                                    alertDialog(CommonResources.Error, TaskResources.ErrorWhenGetRolesList);
                                }
                            });

                        }
                    }, 0);
                }
                else {
                    that.addExecutor(suggestion);
                }
            },
            formatResult: function (suggestion, currentValue) {
                var pattern = '(' + currentValue.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + ')';
                var isarchive = suggestion.data.isAddToService ? " archivecategory" : "";
                var createValue = suggestion.data.iscreatecategory ? ' "' + currentValue + '"' : "";
                var cValue = '<span class="ac-value' + isarchive + '">' + suggestion.value + createValue
                    .replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>')
                    .replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/"/g, '&quot;')
                    .replace(/&lt;(\/?strong)&gt;/g, '<$1>') + '</span>';
                return cValue;
            }
        });

    }
}
ExecutorsItemData.prototype = Object.create(ItemData.prototype);

ExecutorsItemData.prototype.InitTaskRightsDisplayType = function () {
    this.taskRightsDisplayType = ItemDataHelper.TaskRightsDisplayType[$('#executorstaskrightsdisplaytype').attr(ItemData.taskRightsDisplayTypeKey)] || ItemDataHelper.TaskRightsDisplayType.None;
}

ExecutorsItemData.prototype.GetBlockTitle = function () {
    return $('[taskexecutorsstitle]').clone().children().remove().end().text();
}
ExecutorsItemData.prototype.GetCurrentVal = function () {
    return $(this._options.selector).val() || [];
}
ExecutorsItemData.prototype.IsChanged = function () {
    var cur = this.GetCurrentVal();
    var old = this.GetOldValue();
    //if (cur == '' && old == '') {
    //    return false;
    //}
    //if ((cur == '' && old != '') || (cur != '' && old == '')) {
    //    return true;
    //}
    //var result = cur.length != old.length || cur.sort().toString() != old.sort().toString();
    //return result;
    var result = ItemDataHelper.ArraysIsEquals(cur, old);
    return !result;
}
//part2 - пользовательская
ExecutorsItemData.prototype.Append2 = function (userConnectionId, userId, userName, data, existUserConnectionId) {
    var $parent = $('[taskexecutorsstitle]').parent();
    $parent.find('span.taskFormHub-blockInfo').remove();
    var $span = this.GetSpanTemplate(userConnectionId, userId);
    $parent.append($span);
    this.Highlight();
}
//удалить инфу о всех юзерах которые изменили блок
//вызывает при дисконекте
ExecutorsItemData.prototype.ResetAll = function () {
    this.usersEditThisBlock = [];
    var $parent = $('[taskexecutorsstitle]').parent();
    //удалить текущий span
    $parent.find('span.taskFormHub-blockInfo').remove();
    this.Unhighlight();
}
//part2 - пользовательская
ExecutorsItemData.prototype.Reset2 = function (userConnectionId, userId, userName) {
    var $parent = $('[taskexecutorsstitle]').parent();
    //удалить текущий span
    $parent.find('span.taskFormHub-blockInfo').remove();
    //если есть еще пользователи которые редактируют блок
    if (this.usersEditThisBlock.length > 0 && this.TaskRightsDisplayType() != ItemDataHelper.TaskRightsDisplayType.None) {
        //сделать новый span
        var $span = this.GetSpanTemplate(userConnectionId, userId);
        $parent.append($span);
        //подстветить
        this.Highlight();
    }
    else {
        this.Unhighlight();
    }
}
//функция подсветки блока
ExecutorsItemData.prototype.Highlight = function () {
    $('#executors [executorshighlight]').addClass('taskFormHub-highlightBlock');
}

//функция убирает подсветку блока
ExecutorsItemData.prototype.Unhighlight = function () {
    $('#executors [executorshighlight]').removeClass('taskFormHub-highlightBlock');
}
ExecutorsItemData.prototype.InitConflictAfterSubmit = function (submitData) {

    if (this.TaskRightsDisplayType() == ItemDataHelper.TaskRightsDisplayType.None)
        return false;

    var that = this;
    var $parent = $('[taskexecutorsstitle]').parent();
    //удалить старую инфу
    this.isConflict = false;
    this.$conflictMessageElement = undefined;
    $parent.find('[conflict-block="' + this._options.name + '"]').remove();

    if (submitData != null) {

        var submitArray = submitData.map(function (p) { return p.UserId; });
        var curArray = that.GetCurrentVal();
        var oldArray = that.GetOldValue();
        //var myEditedArray = $(curArray).not(oldArray).get();
        var myAddedArray = curArray.filter(function (item) { return oldArray.indexOf(item) < 0 });
        var myRemovedArray = oldArray.filter(function (item) { return curArray.indexOf(item) < 0 });

        //конфликт возможен только когда в настройках стоит "Один исполнитель"
        //if (this.IsChanged() && $('#oneexecutoronticket').val() == "True") {       
        if (this.IsChanged() && !ItemDataHelper.ArraysIsEquals(curArray, submitArray) && $('#oneexecutoronticket').val() == "True") {
            
            var $conflictMessage = $(this.tmpl_conflictMessageBase({ blockName: this._options.name }));

            var selectorType = that.GetSelectorType();

            $conflictMessage.find('a').click(function (e) {
                e.preventDefault();

                var $content = $('<div style="background-color:#f7f9fa"></div>');

                var c =
                        '<div>\
                            <label>\
                                <input type="radio" name="conflictradioresolve-' + that._options.name + '" value="1" checked />' + TaskFormHubResources.ConflictDialogContent_UseOldValue + '\
                            </label>';
                if (curArray.length == 0) {
                    c += '<div name="conflictradioresolve-' + that._options.name + '-value1" emptyvalue>' + TaskFormHubResources.ConflictDialogContent_Executors_Empty + '</div>'
                }
                else {
                    var $opt = $(that._options.selector).find('option:selected');
                    c += '<div name="conflictradioresolve-' + that._options.name + '-value1" conflictvalue="' + $opt.attr('value') + '">';
                    c += $('#executors li[userid="' + $opt.attr('value') + '"] a:first').text();
                    c += '</div>';
                }
                c +=    '</div><hr>\
                        <div>\
                            <label>\
                                <input type="radio" name="conflictradioresolve-' + that._options.name + '" value="0" />' + TaskFormHubResources.ConflictDialogContent_UseNewValue + '\
                            </label>';
                if (submitData.length == 0) {
                    c += '<div name="conflictradioresolve-' + that._options.name + '-value0" emptyvalue>' + TaskFormHubResources.ConflictDialogContent_Executors_Empty + '</div>'
                }
                else {
                    c += '<div name="conflictradioresolve-' + that._options.name + '-value0" conflictvalue=\'' + JSON.stringify(submitData[0]) + '\'>';
                    c += submitData[0].UserName;
                    c += '</div>'
                }
                c += '</div>';

                $content.append(c);

                GLOBAL_taskFormHubDialog.openDialog($content, {
                    title: that.GetBlockTitle(),
                    buttons: {
                        Cancel: function () {
                            GLOBAL_taskFormHubDialog.closeDialog();
                        },
                        Ok: function () {
                            var $content = GLOBAL_taskFormHubDialog.getContent();
                            var checkedVal = $content.find('[name="conflictradioresolve-' + that._options.name + '"]:checked').val();
                            //если оставили то ничего не делаем
                            if (checkedVal == 1) {
                            }
                            else {
                                //удаляем всех выбранных
                                var $select = $(that._options.selector);
                                $select.find('option').remove();
                                $('#executors').find('li').remove();

                                var $resolvecontent = $content.find('[name="conflictradioresolve-' + that._options.name + '-value0"]');
                                if ($resolvecontent.is('[emptyvalue]')) {
                                    that.SetOldValue();
                                    that.SendBlockChange();
                                }
                                else {
                                    var conflictvalue = JSON.parse($resolvecontent.attr('conflictvalue'));
                                    var promises = [];
                                    var categoryIds = conflictvalue.CategoryIds ? conflictvalue.CategoryIds.split(';') : [];
                                    $.each(categoryIds, function (c) {
                                        promises.push(_addUserToList(conflictvalue.UserId, conflictvalue.UserName, conflictvalue.CompanyName, "#executors", undefined, conflictvalue.UserHashId, true, "GLOBAL_taskFormHubObserver.getBlocks()['taskexecutors'].removeUser(this," + conflictvalue.UserId + "); return false;", c));
                                    });
                                    if (!categoryIds)
                                    {
                                        promises.push(_addUserToList(conflictvalue.UserId, conflictvalue.UserName, conflictvalue.CompanyName, "#executors", undefined, conflictvalue.UserHashId, true, "GLOBAL_taskFormHubObserver.getBlocks()['taskexecutors'].removeUser(this," + conflictvalue.UserId + "); return false;"));
                                    }
                                    $.when.apply($, promises)
                                        .done(function () {
                                            that.SetOldValue();
                                            that.SendBlockChange();
                                        });
                                }
                            }

                            //удаляем инфу о конфликте
                            that.isConflict = false;
                            that.$conflictMessageElement = undefined;
                            $parent.find('[conflict-block="' + that._options.name + '"]').remove();

                            GLOBAL_taskFormHubDialog.closeDialog();
                        }
                    }
                });
            });

            this.isConflict = true;
            this.$conflictMessageElement = $conflictMessage;
            $parent.append($conflictMessage);

            return true;
        }
        else {
            //удаляем инфу о конфликте
            that.isConflict = false;
            that.$conflictMessageElement = undefined;
            $parent.find('[conflict-block="' + that._options.name + '"]').remove();

            var $select = $(this._options.selector);
            var promises = [];
            var serverUsers = [];
            $.each(submitData, function (k, v) {
                serverUsers.push(v.UserId);
                var categoryIds = v.CategoryIds ? v.CategoryIds.split(';') : [];
                $.each(categoryIds, function (i, c) {
                    promises.push(_addUserToList(v.UserId, v.UserName, v.CompanyName, "#executors", undefined, v.UserHashId, true, "GLOBAL_taskFormHubObserver.getBlocks()['taskexecutors'].removeUser(this," + v.UserId + "); return false;", c).promise());
                });
                if (!categoryIds)
                {
                    promises.push(_addUserToList(v.UserId, v.UserName, v.CompanyName, "#executors", undefined, v.UserHashId, true, "GLOBAL_taskFormHubObserver.getBlocks()['taskexecutors'].removeUser(this," + v.UserId + "); return false;").promise());
                }
            });
            $.when.apply($, promises).then(function (result) {
                if (curArray.length) {
                    for (var i = 0; i < curArray.length; i++) {
                        var curItem = curArray[i];
                        //if (serverUsers.indexOf(curItem) == -1 && myEditedArray.indexOf(curItem) == -1) {
                        if (serverUsers.indexOf(curItem) == -1 && myAddedArray.indexOf(curItem) == -1 && myRemovedArray.indexOf(curItem) == -1) {
                            $('#executors').find('li[userid="' + curArray[i] + '"]').remove();//.addClass('archive changed');
                            $select.find('option[value="' + curArray[i] + '"]').remove();//.attr('selected', false);
                        }
                    }
                }

                var $notconflictMessage = $(that.tmpl_notconflictMessageBase({ blockName: that._options.name }));
                //добавить новую инфу
                $parent.append($notconflictMessage);

                //в старое значение запишем новые данные, но без тех что мы лично добавили
                //иначе наши изменения не сохранятся...
                //that.SetOldValue($(that.GetCurrentVal()).not(myEditedArray).get());
                that.SetOldValue($(ItemDataHelper.ArraysMergeDistinct(that.GetCurrentVal(), myRemovedArray)).not(myAddedArray).get());
                that.SendBlockChange();
            });

            return false;
        }
    }

    return false;
}
ExecutorsItemData.prototype.AppendNotConflict = function () { }
ExecutorsItemData.prototype.AppendNotConflictUpdate = function () { }
ExecutorsItemData.prototype.AppendConflict1 = function () { }
ExecutorsItemData.prototype.AppendConflict2 = function () { }

ExecutorsItemData.prototype.assignSelfExecutor = function () {
    var that = this;
  
    var taskId = $("#id").val();
    $.ajax({
        url: 'Task/CanAssignSelfExecutor',
        data: { taskId: taskId },
        type: 'POST'
    }).done(function(result) {
        if (result.canAssignSelfExecutor) {
            $.getJSON('Task/GetCurrenUserData', { json: "json" }, function (data) {
                _addUserToList(data.Id, data.Name, data.CompanyName, "#executors", undefined, data.HashId, true, "GLOBAL_taskFormHubObserver.getBlocks()['taskexecutors'].removeUser(this," + data.Id + "); return false;", undefined, -1)
                    .done(function (result) {
                        that.SendBlockChange();
                    });
            });
        }
    });
}

ExecutorsItemData.prototype.reassignExecutors = function (userid, few) {
    var that = this;
    that.removeAllExecutorsButNotThis(userid);
    if ($('#executors li[userid=' + userid + ']').length)
        $('#executorids option[value="' + userid + '"]').attr('selected', true);
    else
        that.assignSelfExecutor(few);

    that.SendBlockChange();

    return false;
}
ExecutorsItemData.prototype.addExecutor = function (suggestion) {
    var that = this;
    var name = suggestion.value;
    var company = suggestion.data.companyName;
    var id = suggestion.data.id;
    _addUserToList(id, name, company, '#executors', undefined, undefined, true, "GLOBAL_taskFormHubObserver.getBlocks()['taskexecutors'].removeUser(this," + id + "); return false;", undefined, -1)
       .done(function (result) {
           that.SendBlockChange();
       });
}
ExecutorsItemData.prototype.removeUser = function (athis, id) {
    var that = this;
    removeUser(athis, id);
    this.SendBlockChange();
}
ExecutorsItemData.prototype.selectExecutors = function () {
    var that = this;

    var url = 'taskuser.ivp/selectexecutors?targetBlock=ExecutorsItemData&tb_serviceid=' + $('#serviceid').val();
    if ($('#deadline').val() != '') {
        url += '&tb_deadline=' + $('#deadline').val();
    }
    if ($('#executorsfromexecutorgroup') && $('#executorsfromexecutorgroup').val() == 'True' && $('#executorgroupid') && $('#executorgroupid').val() != '') {
        url += '&tb_executorgroupid=' + $('#executorgroupid').val();
    }

    dlg = openDialog(url, 'selectusers', { width: 900, height: 650 });
    dlg.callback = ExecutorsItemData.selectExecutorsCallback;
    return false;
}
ExecutorsItemData.selectExecutorsCallback = function (result) {
    var that = GLOBAL_taskFormHubObserver.getBlocks()['taskexecutors'];
    var uids = result["selectedIds"];
        var names = result["selectedNames"];
        var companies = result["selectedCompanies"];
        var promises = [];
        uids.forEach(function (id) {
            var un = names['id' + id];
            var cn = companies['id' + id];
            promises.push(_addUserToList(id, un, cn, '#executors', undefined, undefined, true, "GLOBAL_taskFormHubObserver.getBlocks()['taskexecutors'].removeUser(this," + id + "); return false;", undefined, -1).promise());
        });
        $.when.apply($, promises).then(function (result) {
            that.SendBlockChange();
        });
}
ExecutorsItemData.prototype.addUserOnServiceAndTask = function (suggestion, withRole) {
    var that = this;

    params = new Array();
    params[params.length] = { name: 'serviceid', value: $('#serviceid').val() };
    params[params.length] = { name: 'uids', value: suggestion.data.id };
    if (withRole)
        params[params.length] = { name: 'rids', value: $('#addUserWithRole').val() };
    $.ajax({
        url: base + 'serviceuser.ivp/AddUsers',
        data: params,
        type: 'POST',
        success: function (response) {
            if (response != null) {
                var result = $.parseJSON(response)
                if (result != null && result.IsOK != null) {
                    if (result.IsOK) {
                        //addExecutor($('#addexecutor'), suggestion);
                        that.addExecutor(suggestion);
                        $('#addexecutor').autocomplete('clearCache');
                    }
                    else if (result.Description != null) {
                        alertDialog(CommonResources.Error, result.Description);
                    }
                    else {
                        return false;
                    }
                }
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alertDialog(CommonResources.Error, TaskResources.CantAddExecutor);
        }
    });
}
ExecutorsItemData.prototype.removeAllExecutorsButNotThis = function (id, dontshowdeleted) {
    var that = this;

    $('#executors input[type="checkbox"]').each(function (i, e) { $(e).removeAttr('checked'); });
    $('#executors #executorids option').each(function (i, e) { $(e).removeAttr('selected'); });
    $('#executors ul.many li').each(function (i, e) {
        if ($(e).attr("userid") == id)
            $(e).removeClass('archive');
        else {
            if (dontshowdeleted)
                $(e).remove();
            else if (!$(e).hasClass('empty')) {
                $(e).addClass('archive changed');
                $(e).attr("data-groupids", "")
                $(e).attr("data-categoryids", "")
                $(e).data("groupids", "")
                $(e).data("categoryids", "")
                $(e).attr("groupids", "")
                $(e).attr("categoryids", "")
            }
        }
    });
    $('input#hexecutorids').remove();
    that.SendBlockChange();
}
ExecutorsItemData.prototype.removeAllExecutors = function (dontshowdeleted) {
    var that = this;

    $('#executors input[type="checkbox"]').each(function (i, e) { $(e).removeAttr('checked'); });
    $('#executors #executorids option').each(function (i, e) { $(e).removeAttr('selected'); });
    if (dontshowdeleted)
        $('#executors ul').empty();
    else
        $('#executors ul.many li').each(function (i, e) {
            if (!$(e).hasClass('empty')) {
                $(e).addClass('archive changed');
                $(e).attr("data-groupids", "")
                $(e).attr("data-categoryids", "")
                $(e).data("groupids", "")
                $(e).data("categoryids", "")
                $(e).attr("groupids", "")
                $(e).attr("categoryids", "")
            }
        });

    $('input#hexecutorids').remove();

    that.SendBlockChange();
}

ExecutorsItemData.prototype.BlockChange = function () {
    this.SendBlockChange();
}
//#endregion