var ARY_TYPE = 0;
var ARY_VAL = 1;
var ARY_FID = 2;

function TBL_OBJ(table_id, modal_id, options) {
    this.table_id = table_id; // 显示的table id
    this.modal_id = modal_id; // 添加和编辑的弹出框 id

    this.edit_id = -1; // 正在编辑的数据条目序列号
    this.datalist = {}; // 存放数据
    this.rowcnt = 0; // 使用了的序号, 只增不减 

    var settings = {
        process_formdata: null,
        init_modal: null
    };
    $.extend(settings, options);

    this.process_formdata = settings.process_formdata;
    this.init_modal = settings.init_modal;

    var tbl_obj = this;

    this.create_table = function (arylist) {
        var tbody = $("#" + this.table_id + " tbody");
        tbody.html("");
        this.edit_id = -1;
        this.datalist = {};
        this.rowcnt = 0;
        if (arylist.length == 0) {
            var cols = $('#' + this.table_id + ' thead tr th').length;
            if (cols == 0) cols = $('#' + this.table_id + ' thead tr td').length;
            var outputString = '<tr name="blank"><td colspan=' + cols + ' style="text-align:center" >'+getLangM("No data in table.")+'</td></tr>';
            tbody.append(outputString);
        } else {
            for (var i = 0; i < arylist.length; i++) {
                this._table_add_row(arylist[i]);
            }
        }
        var o = $("#" + this.table_id);
        if (o.length) {
            o.on('click', '.table-btn', function () {
                var type = $(this).attr('name');
                var id = $(this).closest('tr').attr('data-rowid');

                if (type == "edit") {
                    remove_error_msg();
                    if (tbl_obj.init_modal != null) tbl_obj.init_modal();
                    data2form(tbl_obj.datalist[id]);
                    tbl_obj.edit_id = id;
                    var e = $("#" + tbl_obj.modal_id);
                    if (e.length) e.modal('show');
                } else if (type == "del") {
                    delete tbl_obj.datalist[id];
                    $("#" + tbl_obj.table_id + " tbody").find('tr[data-rowid=' + id + ']').remove();
                }
            }).on('click', 'input[type=checkbox]', function () {
                var id = $(this).closest('tr').attr('data-rowid');
                var obj = tbl_obj.datalist[id];
                for (var i = 0; i < obj.length; i++) {
                    if (obj[i][ARY_TYPE] == "ck") {
                        obj[i][ARY_VAL] = $(this).prop('checked');
                        break;
                    }
                }
            });
            o.trigger("update");
        }
    };

    this._table_add_row = function (ary, id) {
        var RowCell = new Array();

        if (id == null) id = this.rowcnt;
        for (var i = 0; i < ary.length; i++) {
            var tbl_str;
            switch (ary[i][ARY_TYPE]) {
                case "ck":
                    tbl_str = format_checkbox(id, ary[i][ARY_VAL]);
                    RowCell.push([tbl_str]);
                    break;
                case "str":
                    tbl_str = format_str(ary[i][ARY_VAL]);
                    RowCell.push([tbl_str]);
                    break;
                case "input":
                    tbl_str = format_input(ary[i][ARY_VAL]);
                    RowCell.push([tbl_str]);
                    break;
                case "select":
                    tbl_str = format_select(ary[i][ARY_FID], ary[i][ARY_VAL]);
                    RowCell.push([tbl_str]);
                    break;
                case "edit":
                    tbl_str = format_edit(id);
                    RowCell.push([tbl_str]);
                    break;
                case "del":
                    tbl_str = format_delete(id);
                    RowCell.push([tbl_str]);
                    break;
            }
        }
        var outputString = "";
        for (var i = 0; i < RowCell.length; i++) {
            outputString += "<td>" + RowCell[i] + "</td>\n";
        }

        var tbody = $("#" + this.table_id + " tbody");
        var e = tbody.find('tr[data-rowid=' + id + ']');
        tbody.find("tr[name=blank]").remove();
        if (e.length) {
            e.html(outputString);
        } else {
            tbody.append($('<tr>').html(outputString).attr('data-rowid', id));
            this.datalist[this.rowcnt] = ary;
            ++this.rowcnt;
        }
    }

    this.modal_apply = function (ary) {
        var index = null;
        if (this.edit_id > -1) // edit
        {
            ary = this.datalist[this.edit_id];
            index = this.edit_id;
        }
        form2data(ary);
        if (this.process_formdata) this.process_formdata(ary);
        this._table_add_row(ary, index);
        this.edit_id = -1;
        var e = $("#" + tbl_obj.modal_id);
        if (e.length) e.modal('hide');
    }

    this.check_tbl_val_same = function (check_obj, err_info) {
        for (var i in tbl_obj.datalist) {
            if (i == tbl_obj.edit_id)
                continue;

            if (check_obj.length == 1) {
                for (var j = 0; j < tbl_obj.datalist[i].length; j++) {
                    if (tbl_obj.datalist[i][j][ARY_FID] == check_obj.attr('id')) {
                        if (tbl_obj.datalist[i][j][ARY_VAL] == check_obj.val()) {
                            if(err_info)show_error_msg(err_info, check_obj);
                            return false;
                        }
                    }
                }
            } else if (check_obj.length > 1) {
                var rule_same = true;
                for (var j = 0; j < tbl_obj.datalist[i].length && rule_same; j++) {
                    if (tbl_obj.datalist[i][j][ARY_TYPE] != "edit" && tbl_obj.datalist[i][j][ARY_TYPE] != "del") {
                        for (var k = 0; k < check_obj.length; k++) {
                            if (tbl_obj.datalist[i][j][ARY_FID] == check_obj.eq(k).attr('id')) {
                                if (getObjItemValue(tbl_obj.datalist[i][j]).toString() != tbl_obj.datalist[i][j][ARY_VAL]) {
                                    rule_same = false;
                                    break;
                                }
                            }
                        }
                    }
                }
                if (rule_same) {
                    if(err_info)show_error_msg(err_info, check_obj.first());
                    return false;
                }
            }

        }
        return true;
    }

    function format_checkbox(i, value) {
        var input = '<input class="checkbox" type="checkbox"' +
            ((value == "true" || value == true) ? ' checked' : '') + '>';
        return '<div class="d-flex justify-content-center"><div class="form-check m-0"><label class="form-check-label">' + input + '<i class="input-helper"></i></label></div></div>';
    }

    function format_edit(i) {
        return '<div class="table-btn" name="edit"><i class="bi bi-pencil-square"></i></div>';
    }

    function format_delete(i) {
        return '<div class="table-btn" name="del"><i class="bi bi-trash"></i></div>';
    }

    function format_input(value) {
        return '<input type="text" class="form-control table-input" value="' + value + '">';
    }

    function format_str(str) {
        if (str == "")
            return "N/A";
        else
            return str;
    }

    function format_select(id, val) {
        if (val == "")
            return "N/A";
        else {
            return $("#" + id + " option[value='" + val + "']").text();
        }
    }

    function data2form(obj) {
        for (var i = 0; i < obj.length; i++) {
            if (obj[i][ARY_TYPE] != "edit" && obj[i][ARY_TYPE] != "del" && obj[i][ARY_FID] != "") {
                switch (obj[i][ARY_TYPE]) {
                    case "ck":
                    case "ck_hide":
                        if ($("#" + obj[i][ARY_FID]).prop('checked') != obj[i][ARY_VAL])
                            $("#" + obj[i][ARY_FID]).trigger('click');
                        break;
                    case "str":
                    case "select":
                        $("#" + obj[i][ARY_FID]).val(obj[i][ARY_VAL]).trigger('change');
                        break;
                    case "hide":
                        $("#" + obj[i][ARY_FID]).val(obj[i][ARY_VAL]).trigger('change');
                        break;
                }
            }
        }
    }

    function form2data(obj) {
        for (var i = 0; i < obj.length; i++) {
            if (obj[i][ARY_TYPE] != "edit" && obj[i][ARY_TYPE] != "del" && obj[i][ARY_FID] != "") {
                switch (obj[i][ARY_TYPE]) {
                    case "ck":
                    case "ck_hide":
                        obj[i][ARY_VAL] = $("#" + obj[i][ARY_FID]).prop('checked');
                        break;
                    case "str":
                    case "select":
                        obj[i][ARY_VAL] = $("#" + obj[i][ARY_FID]).val();
                        break;
                    case "hide":
                        obj[i][ARY_VAL] = $("#" + obj[i][ARY_FID]).val();
                        break;
                }
            }
        }
    }

    function getObjItemValue(objItem) {
        var value = "";
        switch (objItem[ARY_TYPE]) {
            case "ck":
            case "ck_hide":
                value = $("#" + objItem[ARY_FID]).prop('checked');
                break;
            case "str":
            case "select":
                value = $("#" + objItem[ARY_FID]).val();
                break;
            case "hide":
                value = $("#" + objItem[ARY_FID]).val();
                break;
        }
        return value;
    }
}