@model DataTablesModel

@functions
{
    string GetUrl(DataUrl dataUrl)
    {
        return !string.IsNullOrEmpty(dataUrl?.ActionName) && !string.IsNullOrEmpty(dataUrl.ControllerName)
            ? Url.Action(dataUrl.ActionName, dataUrl.ControllerName, dataUrl.RouteValues)
            : !string.IsNullOrEmpty(dataUrl.Url)
                ? $"{(dataUrl.Url.StartsWith("~/", StringComparison.Ordinal) ? Url.Content(dataUrl.Url) : dataUrl.Url).TrimEnd('/')}" + (!dataUrl.TrimEnd ? "/" : "")
                : string.Empty;
    }

    string ReplaceName(string str)
    {
        return str.Replace("-", "_");
    }
}

@{
    //the locale which MomentJS should use
    var locale = CultureInfo.CurrentCulture.Name;

    //Model name for js function names
    var model_name = ReplaceName(Model.Name);

    //dom
    var buttonsPanel = "";
    var infoPanel = "<'col-lg-4 col-xs-12'<'float-lg-right text-center'i>>";

    if (Model.RefreshButton && !Model.IsChildTable)
    {
        buttonsPanel = "<'col-lg-1 col-xs-12'<'float-lg-right text-center data-tables-refresh'B>>";
        infoPanel = "<'col-lg-3 col-xs-12'<'float-lg-right text-center'i>>";
    }

    var dom = "<'row'<'col-md-12't>>" +
              "<'row margin-t-5'" +
                "<'col-lg-5 col-xs-12'<'float-lg-left'p>>" +
                "<'col-lg-3 col-xs-12'<'text-center'l>>" +
                infoPanel +
                buttonsPanel +
              ">";

    if (!string.IsNullOrEmpty(Model.Dom))
    {
        dom = Model.Dom;
    }

    //check using MasterCheckBox
    var isMasterCheckBoxUsed = Model.ColumnCollection.Any(x => x.IsMasterCheckBox);
}

@if (!string.IsNullOrEmpty(Model.HeaderCallback))
{
    <text>
        headerCallback: function (thead, data, start, end, display) {
        return @(Model.HeaderCallback)(thead, data, start, end, display);
    },
    </text>
}
@if (!string.IsNullOrEmpty(Model.FooterCallback))
{
    <text>
    footerCallback: function (tfoot, data, start, end, display) {
        return @(Model.FooterCallback)(tfoot, data, start, end, display);
    },
    </text>
}
@if (!string.IsNullOrEmpty(Model.DrawCallback))
{
    <text>
    drawCallback: function (settings) {
    return @(Model.DrawCallback)(settings);
    },
    </text>
}
@if (Model.Processing)
{
    <text>
    processing: @Model.Processing.ToString().ToLowerInvariant(),
    </text>
}
@if (Model.ServerSide)
{
    <text>
    serverSide: @Model.ServerSide.ToString().ToLowerInvariant(),
    </text>
}
@if (!string.IsNullOrEmpty(Model.RowIdBasedOnField))
{
    <text>
    rowId: function (item) {
    var rowId = '';
    if (item.hasOwnProperty('@(Model.RowIdBasedOnField)'))
    {
        if(item.@(Model.RowIdBasedOnField)){
            var val = item.@(Model.RowIdBasedOnField).replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
            rowId = 'row_' + val;
        } else return;
    }
    return rowId;
    },
    </text>
}
@if (Model.Data != null)
{
    <text>
    data: @Html.Raw(Model.Data.ToString()),
    </text>
}
else
{
    <text>
    ajax:
    {
        url: "@Html.Raw(GetUrl(Model.UrlRead))",
        type: "POST",
        dataType: "json",
        dataSrc: "Data",
        beforeSend: function() {
        @if (isMasterCheckBoxUsed)
        {
            <text>
            clearMasterCheckbox('#@Model.Name');
            </text>
        }
        },
        data: function(data) {
            @if (Model.Filters != null)
            {
                foreach (var filter in Model.Filters)
                {
                    if (filter.Type == typeof(string))
                    {
                        if (Model.IsChildTable && !string.IsNullOrEmpty(filter.ParentName))
                        {
                            <text>
                            data.@filter.Name = row.data().@filter.ParentName;
                            </text>
                            continue;
                        }

                        if (!string.IsNullOrEmpty(filter.ModelName))
                        {
                            <text>
                            data.@filter.Name = $('#@(filter.ModelName)_@filter.Name').val();
                            </text>
                        }
                        else
                        {
                            <text>
                            data.@filter.Name = $('#@filter.Name').val();
                            </text>
                        }
                        continue;
                    }
                    if (filter.Type == typeof(bool))
                    {
                        <text>
                        data.@filter.Name = $('#@filter.Name').is(':checked');
                        </text>
                        continue;
                    }
                    if (filter.Type == typeof(int))
                    {
                        if (int.TryParse(@filter.Value.ToString(), out int val))
                        {
                            <text>
                            data.@filter.Name = @val;
                            </text>
                        }
                        continue;
                    }
                    if (filter.Type == typeof(DateTime?))
                    {
                        <text>
                        data.@filter.Name = $('#@filter.Name').val();
                        </text>
                        continue;
                    }
                }
            }
            addAntiForgeryToken(data);
            return data;
        }
    },
    </text>
}
scrollX: true,
info: @Model.Info.ToString().ToLowerInvariant(),
paging: @Model.Paging.ToString().ToLowerInvariant(),
pagingType: '@Model.PagingType',
language: @await Html.PartialAsync("_GridLocalization"),
pageLength: @Model.Length,
@if (!string.IsNullOrEmpty(Model.LengthMenu))
{
    <text>
    lengthMenu: [@Model.LengthMenu],
    </text>
}
else
{
    <text>
    lengthChange: false,
    </text>
}
ordering: @Model.Ordering.ToString().ToLowerInvariant(),
@if (Model.RefreshButton)
{
    <text>
    buttons: [{
        name: 'refresh',
        text: '<i class="fas fa-sync-alt" style="padding-left: 5px"></i>',
        action: function() {
            @if (Model.ServerSide)
            {
                <text>
                updateTable('#@Model.Name', @isMasterCheckBoxUsed.ToString().ToLowerInvariant());
                </text>
            }
            else
            {
                <text>
                updateTableSrc('#@Model.Name', @isMasterCheckBoxUsed.ToString().ToLowerInvariant());
                </text>
            }
        }
    }],
    </text>
}
dom: '@JavaScriptEncoder.Default.Encode(dom)',
columns: [    
    @for (int i = 0; i < Model.ColumnCollection.Count; i++)
    {
        var column = Model.ColumnCollection[i];
        <text>
        {            
            @if (!string.IsNullOrEmpty(column.Title) && !column.IsMasterCheckBox)
            {
                <text>
                title: '@JavaScriptEncoder.Default.Encode(column.Title)',
                </text>
            }
            else
            {
                if (!string.IsNullOrEmpty(column.Title) && column.IsMasterCheckBox)
                {
                    <text>
                    title: '<div class="checkbox"><label><input class="mastercheckbox" type="checkbox" />@JavaScriptEncoder.Default.Encode(column.Title)</label></div>',
                    </text>
                }
                else
                {
                    if (string.IsNullOrEmpty(column.Title) && column.IsMasterCheckBox)
                    {
                        <text>
                        title: '<input class="mastercheckbox" type="checkbox"/>',
                        </text>
                    }
                }
            }
            width: '@column.Width',
            visible: @column.Visible.ToString().ToLowerInvariant(),
            searchable: @column.Searchable.ToString().ToLowerInvariant(),
            @if (column.AutoWidth)
            {
                <text>
                autoWidth: @column.AutoWidth.ToString().ToLowerInvariant(),
                </text>
            }
            @if (!string.IsNullOrEmpty(column.ClassName))
            {
                <text>
                className: '@column.ClassName',
                </text>
            }
            @if ((Model.UrlUpdate != null) || (Model.ChildTable?.UrlUpdate != null))
            {
                <text>
                createdCell: function (td, cellData, rowData, row, col) {
                   $(td).attr('data-columnname', '@column.Data');
                },
                </text>
            }
            @if (column.Encode && column.Render == null)
            {
                <text>
                render: function (data, type, row, meta) {
                    return escapeHtml(data);
                },
                </text>
            }
            @switch (column.Render)
            {
                case RenderLink link:
                    <text>
                    render: function (data, type, row, meta) {
                        var textRenderer = $.fn.dataTable.render.text().display;
                        @if (!string.IsNullOrEmpty(link.Title))
                        {
                            <text>
                            return '<a href="@GetUrl(link.Url)' + textRenderer(row.@link.Url.DataId) + '">@JavaScriptEncoder.Default.Encode(link.Title)</a>';
                            </text>
                        }
                        else
                        {
                            <text>
                            return '<a href="@GetUrl(link.Url)' + textRenderer(row.@link.Url.DataId) + '">' + textRenderer(data) + '</a>';
                            </text>
                        }
                    },
                    </text>
                    break;
                case RenderDate date:
                    <text>
                    render: function (data, type, row, meta) {
                        return (data) ? moment(data).locale('@locale').format('@date.Format') : null;
                    },
                    </text>
                    break;
                case RenderButtonRemove button:
                    <text>
                    render: function (data, type, row, meta) {
                        return '<a href="#" class="@button.ClassName" onclick="table_deletedata_@(model_name)(\'' + data + '\');return false;"><i class="far fa-trash-alt"></i>@button.Title</a>';
                    },
                    </text>
                    break;
                    case RenderButtonsInlineEdit button:
                    <text>
                    render: function (data, type, row, meta) {
                        var origData = data;
                        var modData = data;
                        if (typeof data == 'string') {
                            modData = data.replace(/[.*+?^${}()|[\]\\]/g, "_");
                        }
                        return '<a href="#" class="@button.ClassName" id="buttonEdit_@(model_name)'+ modData + '" onclick="editData_@(model_name)($(this).parent().parent(), \'' + origData + '\');return false;"><i class="fas fa-pencil-alt"></i>@T("Admin.Common.Edit")</a>' +
                        '<a href="#" class="@button.ClassName" id="buttonConfirm_@(model_name)'+ modData + '" style="display:none" onclick="confirmEditData_@(model_name)($(this).parent().parent(), \'' + origData + '\', \'@column.Data\');return false;"><i class="fas fa-check"></i>@T("Admin.Common.Update")</a>' +
                        '<a href="#" class="@button.ClassName" id="buttonCancel_@(model_name)'+ modData + '" style="display:none" onclick="cancelEditData_@(model_name)(\'' + row + '\', \'' + origData + '\');updateTableWidth(\'' + '#@Model.Name' + '\');return false;"><i class="fas fa-ban"></i>@T("Admin.Common.Cancel")</a>';
                    },                         
                    </text>
                    break;
                case RenderButtonEdit buttonEdit:
                    <text>
                    render: function (data, type, row, meta) {
                        return '<a class="@buttonEdit.ClassName" href="@GetUrl(buttonEdit.Url)' + data + '"><i class="fas fa-pencil-alt"></i>@T("Admin.Common.Edit").Text</a>';
                    },
                    </text>
                    break;
                case RenderButtonView buttonView:
                    <text>
                    render: function (data, type, row, meta) {
                        return '<a class="@buttonView.ClassName" href="@GetUrl(buttonView.Url)' + data + '"><i class="far fa-eye"></i>@T("Admin.Common.View").Text</a>';
                    },
                    </text>
                    break;
                case RenderButtonCustom buttonCustom:
                    if (!string.IsNullOrEmpty(buttonCustom.Url))
                    {
                        <text>
                        render: function (data, type, row, meta) {
                            return '<a class="@buttonCustom.ClassName" href="@buttonCustom.Url' + data + '">@JavaScriptEncoder.Default.Encode(buttonCustom.Title)</a>';
                        },
                        </text>
                    }
                    if (!string.IsNullOrEmpty(buttonCustom.OnClickFunctionName))
                    {
                        <text>
                        render: function (data, type, row, meta) {
                            return '<a class="@buttonCustom.ClassName" onclick="@buttonCustom.OnClickFunctionName' + '(\'' + data + '\');">@JavaScriptEncoder.Default.Encode(buttonCustom.Title)</a>';
                        },
                        </text>
                    }
                    break;
                case RenderPicture picture:
                    var widthAttr = string.Empty;
                    <text>
                    render: function (data, type, row, meta) {
                        @if (picture.Width > 0)
                        {
                            widthAttr = "width=" + picture.Width;
                        }
                        @if (!string.IsNullOrEmpty(picture.Src))
                        {
                            <text>
                            return '<img src="@(picture.SrcPrefix)@(picture.Src)" @(widthAttr) />';
                            </text>
                        }
                        else
                        {
                            <text>
                            return '<img src="@(picture.SrcPrefix)' + data + '" @(widthAttr) />';
                            </text>
                        }
                    },
                    </text>
                    break;
                case RenderCheckBox checkBox:
                    <text>
                    render: function (data, type, row, meta) {
                        return (data === true)
                            ? '<input name="@checkBox.Name" value="' + row.@checkBox.PropertyKeyName + '" type="checkbox" class="checkboxGroups" checked="checked" />'
                            : '<input name="@checkBox.Name" value="' + row.@checkBox.PropertyKeyName + '" type="checkbox" class="checkboxGroups" />';
                    },
                    </text>
                    break;
                case RenderBoolean renderBoolean:
                    <text>
                    render: function (data, type, row) {
                        return data
                            ? '<i class="fas fa-check true-icon" nop-value="true"></i>'
                            : '<i class="fas fa-times false-icon" nop-value="false"></i>';
                    },
                    </text>
                    break;
                case RenderCustom custom:
                    <text>
                    render: function (data, type, row, meta) {
                        return @(custom.FunctionName)(data, type, row, meta);
                    },
                    </text>
                    break;
                case RenderChildCaret caret:
                    <text>
                    render: function (data, type, row, meta) {
                        return '<i class="fas fa-caret-right" aria-hidden="true"></i>';
                    },
                    </text>
                    break;
            }
            data: '@column.Data'            
        }
        @if (i != Model.ColumnCollection.Count - 1) {<text>,</text>}
        </text>
    }
]           