////Exemplo de formatter
//objeto.coluna.formatter = function (row, cell, value, columnDef, dataContext) {
//    return "<button>Ação</button>";
//};


function GridInlogOverrideFuncions() {
    this.AtualizarGrid = null;
    this.SelecionarGrid = null;
    this.AtualizarGridFiltrada = null;
    this.OnSortGrid = null;
    this.OnClickGrid = null;
}

function GridInlog(obj, target, idColumnPiker, functions) {
    var mSelf = this;

    mSelf.columns = ko.toJS(obj.columns);
    mSelf.Data = obj.Data;
    mSelf.options = ko.toJS(obj.options);

    mSelf.DataFiltrado = ko.observableArray();
    mSelf.DataSelecionado = ko.observable();

    mSelf.grid = null;
    mSelf.columnpicker = null;

    mSelf.GeraColunaCheckBox = obj.GeraColunaCheckBox;
    mSelf.ListaItensSelecionados = ko.observableArray();

    // init grid
    mSelf.Init = function () {

        ko.mapping.fromJS(mSelf.Data(), {}, mSelf.DataFiltrado);

        if (functions)
            for (var func in functions) {
                if (func != null && functions[func] != null)
                    mSelf[func] = functions[func];
            }

        ko.utils.arrayForEach(mSelf.columns, function (col) {
            if (col.width == null)
                delete col.width;

            if (col.formatter == null)
                col.formatter = formatter;
            else if (!$.isFunction(col.formatter)) {
                col.template = col.formatter;
                col.formatter = formatterEspc;
            }
        });

        mSelf.CarregarGrid();

        setTimeout(function () { mSelf.AtualizarGrid(); }, 5000);
    };

    //recupera item da grid
    mSelf.ProcurarItem = function (valor, propriedade) {
        return ko.utils.arrayFilter(mSelf.Data(), function (item) {
            return item[propriedade]() == valor;
        });
    }

    mSelf.AtualizarItemGrid = function (obj, propriedade) {
        var itemGrid = ko.utils.arrayFirst(mSelf.Data(), function (item) {
            return item[propriedade]() == obj[propriedade];
        });
        mSelf.AtualizarDadosPorEvento(itemGrid, obj);
    }

    // atulização grid de 5 em 5 sigundos e marca intem selecionado se tiver
    mSelf.AtualizarGrid = function () {
        mSelf.grid.invalidate();
        mSelf.grid.render();
        //setTimeout(function () { mSelf.AtualizarGrid(); }, 5000);

        if (mSelf.DataSelecionado() != undefined && mSelf.DataSelecionado() != null) {
            var index = mSelf.DataFiltrado().indexOf(mSelf.DataSelecionado());
            mSelf.SelecionarGrid(index);
        }

        mSelf.RecuperaItensSelecionados();
    };

    // marca item selecionado da grid
    mSelf.SelecionarGrid = function (index) {
        $(".slick-row").removeClass("ui-state-active");
        $(".ordem-html-" + index).parent().parent().addClass("ui-state-active");
    };

    // atuliza grid de acordo com filtro
    mSelf.AtualizarGridFiltrada = function (filtro) {
        if (filtro) {
            mSelf.DataFiltrado.removeAll();

            ko.utils.arrayForEach(filtro, function (item) {
                mSelf.DataFiltrado.push(item);
            });

        }
        mSelf.grid.invalidate();
        mSelf.grid.render();
    };

    // atuliza database grid
    mSelf.AtualizarDataBase = function (data) {
        if (data) {
            mSelf.Data.removeAll();
            ko.utils.arrayForEach(data(), function (item) {
                mSelf.Data.push(item);
            });
            mSelf.AtualizarGridFiltrada(data());
        }
    };

    mSelf.GetDistinctValues = function (coluna) {
        if (coluna === "Colaboradores") {
            return mSelf.DataFiltrado().map(x => x[coluna]()).flat();
        } else return ko.utils.arrayMap(mSelf.DataFiltrado(),
            (item) => item[coluna]() ? item[coluna]().toString() : "");
    };

    //Resetar grid de acordo com database
    mSelf.ResetarGrid = function () {
        mSelf.DataFiltrado.removeAll();
        ko.utils.arrayForEach(mSelf.Data(), function (item) {
            mSelf.DataFiltrado.push(item);
        });
        mSelf.grid.invalidate();
        mSelf.grid.render();
    };

    //Adicionar item grid
    mSelf.AdicionarItemGrid = function (item) {
        mSelf.Data.push(item);
        mSelf.grid.invalidate();
        mSelf.grid.render();
    }

    //Adicionar item grid
    mSelf.AdicionarItemGridDatas = function (item) {
        mSelf.Data.push(item);
        mSelf.DataFiltrado.push(item);
        mSelf.grid.invalidate();
        mSelf.grid.render();
    }

    //Adicionar item grid
    mSelf.AdicionarListaItensGrid = function (lista) {
        ko.utils.arrayPushAll(mSelf.Data, lista);
        mSelf.grid.invalidate();
        mSelf.grid.render();
    }

    //Remover item grid
    mSelf.RemoverItemGrid = function (valor) {
        var codigo = ko.isObservable(valor.Codigo) ? valor.Codigo() : valor.Codigo;
        mSelf.DataFiltrado.remove(function (item) {
            return item.Codigo() == codigo;
        });
        mSelf.Data.remove(function (item) {
            return item.Codigo() == codigo;
        });

        mSelf.grid.invalidate();
        mSelf.grid.render();
    }

    //Evento Atualizar dados item grid
    mSelf.AtualizarDadosPorEvento = function (data, evento, itens) {
        if (itens) {
            $.each(itens, function (index, value) {
                if (value != null && evento[value] != null)
                    data[value](evento[value]);
            });
        } else {
            for (var item in data) {
                if (item != null && evento[item] != null)
                    data[item](evento[item]);
            }
        }
    };

    // Função para alterar o formato do valor das células
    function formatter(row, cell, value, columnDef, dataContext) {
        var item;
        if (ko.isObservable(value))
            item = value();
        else
            item = value;

        if (cell == 1) {
            return "<input type='hidden' class='ordem-html-" + row + "'/>" + item;
        }
        return item;
    }

    // Função formater usada quando o usuario define o mesmo no CSHARP
    function formatterEspc(row, cell, value, columnDef, dataContext) {
        var item;
        if (ko.isObservable(value))
            item = value();
        else
            item = value;

        var template = columnDef.template;
        while (template.indexOf("{value}") > -1) {
            template = template.replace("{value}", item);
        }
        return template;
    }

    // carrega a grid
    mSelf.CarregarGrid = function () {
        $(function () {
            // Função que mostra os valores das células na grid
            $(function () {

                if (mSelf.GeraColunaCheckBox()) {
                    mSelf.columns[0].clickCheckBoxRow = mSelf.ClickCheckBoxRow;
                    mSelf.columns[0].clickTodosCheckBoxRow = mSelf.ClickTodosCheckBoxRow;

                    var checkboxSelector = new Slick.CheckboxSelectColumn(mSelf.columns[0]);
                    mSelf.columns[0].formatter = checkboxSelector.checkboxSelectionFormatter;
                }
                mSelf.grid = new Slick.Grid("#" + target, mSelf.DataFiltrado(), mSelf.columns, mSelf.options);

                if (mSelf.GeraColunaCheckBox()) {
                    mSelf.grid.setSelectionModel(new Slick.RowSelectionModel({ selectActiveRow: false }));
                    mSelf.grid.registerPlugin(checkboxSelector);
                }

                mSelf.columnpicker = new Slick.Controls.ColumnPicker(mSelf.columns, mSelf.grid, mSelf.options, idColumnPiker);

                mSelf.grid.onSort.subscribe(function (e, args) {
                    // evento sort grid
                    mSelf.OnSortGrid(e, args);
                });

                mSelf.grid.onClick.subscribe(function (e, args) {

                    if ($(e.target).is(':checkbox'))
                        return;

                    // seta data selecionado
                    mSelf.DataSelecionado(mSelf.DataFiltrado()[args.row]);
                    mSelf.SelecionarGrid(args.row);

                    // evento click grid
                    mSelf.OnClickGrid(e, args);
                });
            });

            $("#mapa, #inlog-map").css({ "bottom": "264px" });

            $(".footerbar-grid").toggle(function () {
                var h = $("footer").outerHeight();
                $(".sidebar, #mapa, #inlog-map").css({ "bottom": "43px" });
            }, function () {
                $("#mapa, #inlog-map").css({ "bottom": "264px" });
            });

            $(".main-footer").resizable({
                alsoResize: ".grid-footer, .slick-viewport, .wrap-grid, #myGrid",
                animate: false,
                minHeight: 171,
                handles: "n",
                stop: function (event, ui) {
                    mSelf.grid.resizeCanvas();

                    const h = $("footer").outerHeight();
                    $(".sidebar, #mapa, #inlog-map").css({ "bottom": +h + "px" });
                }
            });
        });
    };

    // evento sort grid
    mSelf.OnSortGrid = function (e, args) {
        var cols = args.sortCols;

        mSelf.DataFiltrado().sort(function (dataRow1, dataRow2) {
            for (var i = 0, l = cols.length; i < l; i++) {
                var result;

                var field = cols[i].sortCol.id;
                var sign = cols[i].sortAsc ? 1 : -1;

                var value1 = dataRow1[field], value2 = dataRow2[field];

                value1(value1() == null ? "" : value1());
                value2(value2() == null ? "" : value2());

                if (field == "DataHoraInicioDisplay" || field == "DataHoraFimDisplay" || field == "Abertura")
                    return sorterDate(value1(), value2(), sign);

                if (field == "Fotos")
                    return sorterFoto(dataRow1, dataRow2, sign);

                if (!value1 && !value2)
                    return 0;

                result = (value1() == value2() ? 0 : (value1() > value2() ? 1 : -1)) * sign;

                if (result != 0) {
                    return result;
                }
            }
            return 0;
        });

        mSelf.grid.invalidate();
        mSelf.grid.render();

        if (!$(e.target).is(":checkbox"))
            mSelf.RecuperaItensSelecionados();
    }

    function sorterDate(value1, value2, sign) {
        var date_a = new Date(parseInt(value1.substring(6, 10)), parseInt(value1.substring(3, 5)) - 1, parseInt(value1.substring(0, 2)), parseInt(value1.substring(11, 13)), parseInt(value1.substring(14, 16)));
        var date_b = new Date(parseInt(value2.substring(6, 10)), parseInt(value2.substring(3, 5)) - 1, parseInt(value2.substring(0, 2)), parseInt(value2.substring(11, 13)), parseInt(value2.substring(14, 16)));
        var diff = date_a.getTime() - date_b.getTime();
        return sign * (diff === 0 ? 0 : (date_a > date_b ? 1 : -1));
    }

    function sorterFoto(dataRow1, dataRow2, sign) {
        var value1 = dataRow1["QuantidadeApontamentos"], value2 = dataRow2["QuantidadeApontamentos"];
        return (value1() == value2() ? 0 : (value1() > value2() ? 1 : -1)) * sign;
    }

    // evento clique grid
    mSelf.OnClickGrid = function (e, args) {

    };

    mSelf.ClickCheckBoxRow = function (e, args) {

        var item = args.grid.getDataItem(args.row);
        var elementChecked = $($(args.grid.getCellNode(args.row, 0)).children()[0]).is(":checked")

        if (elementChecked) {
            if (mSelf.ListaItensSelecionados.indexOf(item.Codigo()) == -1)
                mSelf.ListaItensSelecionados.push(item.Codigo());
        }
        else {
            if (mSelf.ListaItensSelecionados.indexOf(item.Codigo()) >= 0)
                mSelf.ListaItensSelecionados.remove(item.Codigo());
        }
    };

    mSelf.ClickTodosCheckBoxRow = function (e, args) {

        var itens = args.grid.getSelectedRows();

        if (itens.length > 0) {
            ko.utils.arrayForEach(itens, function (item) {
                var obj = args.grid.getDataItem(item);
                if (mSelf.ListaItensSelecionados.indexOf(obj.Codigo()) == -1)
                    mSelf.ListaItensSelecionados.push(obj.Codigo());
            });
        }
        else {
            mSelf.ListaItensSelecionados.removeAll();
        }
    };

    mSelf.RecuperaItensSelecionados = function () {
        mSelf.grid.getSelectionModel().setSelectedRanges([]);
        if (mSelf.ListaItensSelecionados() && mSelf.ListaItensSelecionados().length > 0) {
            var lengthRowsGrid = mSelf.grid.getDataLength();
            var indiceRow;
            var rows = [];
            for (indiceRow = 0; indiceRow <= lengthRowsGrid; indiceRow++) {
                var dataItem = mSelf.grid.getDataItem(indiceRow);
                var cellCheckBox = mSelf.grid.getCellNode(indiceRow, 0);
                $($(cellCheckBox).children()[0]).removeAttr("checked");

                if (dataItem) {
                    if (mSelf.ListaItensSelecionados().indexOf(dataItem.Codigo()) >= 0) {
                        $($(cellCheckBox).children()[0]).attr("checked", "checked");
                        rows.push(indiceRow);
                    }
                }
            }
            mSelf.grid.getSelectionModel().setSelectedRows(rows);
        }
    };

    // inicia a função para carregar a grid
    mSelf.Init();
}