$(function () {
    $.validator.addMethod("validateCompany", function (value, element) {
        if ($("#isdefault").is(':checked')) {
            return true;
        }
        return Number($("#clientcompanyid").val()) > 0;
    });

    $.validator.addMethod("validateContact", function (value, element) {
        if (Number($("#clientuserid").val()) > 0 && !Number($("#clientcompanyid").val()) > 0)
            return false;
        return true;
    });

    $.validator.addMethod("validateExecutor", function (value, element) {
        return fieldHasValues($("#executorsgroupids").val()) || fieldHasValues($("#executorsuserids").val())
    });


    if ($("#name").size()) {
        $("#name").rules("add", {
            required: true
        });
    }

    if ($("#client").size()) {
        $("#client").rules("add", {
            validateCompany: true,
            messages: {
                validateCompany: FormResources.FieldRequired
            }
        });
    }

    if ($("#clientcontact").size()) {
        $("#clientcontact").rules("add", {
            validateContact: true,
            messages: {
                validateContact: CompanyResources.NoCompanySelected
            }
        });
    }

    $("#executorsgroupids").rules("add", {
        validateExecutor: true,
        messages: {
            validateExecutor: ExecutorGroupResources.NoGroupsSelected
        }
    });

    $("#executorsuserids").rules("add", {
        validateExecutor: true,
        messages: {
            validateExecutor: UserResources.NoUsersSelected
        }
    });

    $("#isdefault").on("click", function () {
        if ($("#isdefault").is(":checked")) {
            $("#cid").removeClass("required");
            $("#name").removeClass("required");
            $("#nl").removeClass("required");
            $("#name").rules("remove", "required");
            $("#cli").fadeOut("fast", function () {
                $("#any").fadeIn("fast");
            });
            $("#name").fadeOut("fast", function () {
                $("#default-name").fadeIn("fast");
            });
        } else {
            $("#cid").addClass("required");
            $("#name").addClass("required");
            $("#nl").addClass("required");
            $("#name").rules("add", {
                required: true
            });
            $("#any").fadeOut("fast", function () {
                $("#cli").fadeIn("fast");
            });
            $("#default-name").fadeOut("fast", function () {
                $("#name").fadeIn("fast");
            });
        }
    })

    if ($("#isdefault").is(":checked")) {
        $("#cid").removeClass("required");
        $("#nl").removeClass("required");
        $("#name").rules("remove", "required");
        $("#cli").fadeOut("fast", function () {
            $("#any").fadeIn("fast");
        });
        $("#name").fadeOut("fast", function () {
            $("#default-name").fadeIn("fast");
        });
    }

});

Client = {
    clearCompany: function clearCompany() {
        $("#client").val("");
        $("#clientcompanyid").val("");
        $('#companyplaceholder').fadeOut('fast', function () { $('#companyeditor').fadeIn('fast') });
        this.clearUser();
        return false;
    },
    selectCompany: function selectCompany() {
        dlg = openDialog('company.ivp/select?cbmode=Client');
        dlg.callback = Client.companiesCallback;
        return false;
    },
    companiesCallback: function companiesCallback(result) {
        var ids = result["selectedIds"];
        var names = result["selectedNames"];
        $("#client").val(names["id" + ids[0]]);
        $("#clientcompanyid").val(ids[0]);
    },
    clearUser: function clearUser() {
        $("#clientuserid").val("");
        $("#clientcontact").val("");
        $('#contactplaceholder').fadeOut('fast', function () { $('#contacteditor').fadeIn('fast') });
        return false;
    },
    selectUser: function selectUser() {
        var companyId = $("#clientcompanyid").val();
        if (Number(companyId) > 0) {
            dlg = openDialog('user.ivp/select?cbmode=Client&reset=true&tb_mode=companyuser&tb_companyid=' + companyId);
            dlg.callback = Client.usersCallback;
            return false;
        }
        alert(CompanyResources.NoCompanySelected);
        return false;
    },
    usersCallback: function usersCallback(result) {
        var ids = result["selectedIds"];
        var names = result["selectedNames"];
        $("#clientcontact").val(names["id" + ids[0]]);
        $("#clientuserid").val(ids[0]);
    }
};

Own = {
    selectUser: function selectUser() {
        dlg = openDialog('user.ivp/select?cbmode=Own&reset=true&tb_mode=ALLUSERS');
        dlg.callback = Own.usersCallback;
        return false;
    },
    usersCallback: function usersCallback(result) {
        var ids = result["selectedIds"];
        var current = numberArrayFromString($("#executorsuserids").val());
        var newItems = [];
        if (current.length > 0) {
            newItems = filterNewItems(current, ids);
            $("#executorsuserids").val(newItems.concat(current).join(','));
        } else {
            newItems = ids;
            $("#executorsuserids").val(ids.join(','));
        }
        var names = result["selectedNames"];
        appendExecutorRow($("#ex"), newItems, names, Own.removeExecutor);
    },
    removeExecutor: function removeExecutor(id) {
        $("#executorsuserids").val(removeItemId($("#executorsuserids").val(), id));
    },
    selectUserGroup: function selectUserGroup() {
        dlg = openDialog('executorgroup/select?cbmode=Own');
        dlg.callback = Own.userGroupCallback;
        return false;
    },
    userGroupCallback: function userGroupCallback(result) {
        var ids = result["selectedIds"];
        var current = numberArrayFromString($("#executorsgroupids").val());
        var newItems = [];
        if (current.length > 0) {
            newItems = filterNewItems(current, ids);
            $("#executorsgroupids").val(newItems.concat(current).join(','));
        } else {
            newItems = ids;
            $("#executorsgroupids").val(ids.join(','));
        }
        var names = result["selectedNames"];
        appendExecutorRow($("#exgr"), newItems, names, Own.removeUserGroup);
    },
    removeUserGroup: function removeUserGroup(id) {
        $("#executorsgroupids").val(removeItemId($("#executorsgroupids").val(), id));
    },
};

function removeItemId(str, id) {
    var parsed = parseInt(id);
    if (isNaN(id))
        return str;
    return numberArrayFromString(str).filter(function (item) {
        return item != parsed;
    }).join(',');
}


function appendExecutorRow(exTable, exIds, exNames, removeCallback) {
    deleteButton = `<a class="delexec" href="#" onclick="return removeExecutor(this, Own.${removeCallback.name})"> <img src="img/buttons/trash.gif" title=${CommonResources.Remove}></a>`;
    $table = $(exTable);
    for (var i = 0; i < exIds.length; i++) {
        $table.append(`<tr><td class="hidden">${exIds[i]}</td><td>${deleteButton}</td><td class="width100">${exNames['id' + exIds[i]]}</td></tr>`)
    }
}

function removeExecutor(that, callback) {
    if (!confirm(TableResources.SureDeleteRecords)) return false;
    $that = $(that);
    var row = $that.parents("tr");
    var cols = $(row[0]).children("td");

    var id = $(cols[0]).text().trim();
    $(row[0]).fadeOut("fast", function () {
        $(row[0]).remove();
    });

    if (callback !== undefined && callback !== null)
        callback(id);
    return false;
}

function numberArrayFromString(splitString) {
    return splitString.split(",").map(function (value) {
        return parseInt(value);
    }).filter(function (item) {
        return !isNaN(item);
    });
}

function joinArraysDistinct(lhs, rhs) {
    if ((typeof (lhs) === 'object' && Array.isArray(lhs))
        && (typeof (rhs) === 'object' && Array.isArray(rhs))) {
        return lhs.concat(rhs.filter(function (item) {
            return lhs.indexOf(item) < 0;
        }));
    }
    throw new TypeError('Both operands must be an array');
}

function filterNewItems(oldItems, newItems) {
    if ((typeof (oldItems) === 'object' && Array.isArray(oldItems))
        && (typeof (newItems) === 'object' && Array.isArray(newItems))) {
        return newItems.filter(function (item) {
            var parsed = parseInt(item);
            return !isNaN(parsed) && oldItems.indexOf(parsed) < 0;
        });
    }
    throw new TypeError('Both operands must be an array');
}

function fieldHasValues(str) {
    return numberArrayFromString(str).length > 0;
}
