
require('knockout.validation');
require("../../util/bindingHandlers.js")


export class FormBuilder {
    constructor() {
        this.showCancel = ko.observable(true);
        this.formControls = ko.observableArray();
        this.formButtons = ko.observableArray();
        this.hideBodyForm = ko.observable(false);
    }

    toggleHideBodyForm() {
        this.hideBodyForm(!this.hideBodyForm());
    }

    toServer() {
        let data = ko.toJS(this);
        delete data["validationObject"];
        delete data["formButtons"];
        delete data["formControls"];
        delete data["parentVM"];
        delete data["editMode"];
        delete data["ad"];
        delete data["selected"];
        delete data["ruleModel"];
        return data;
    }

    propName(value) {
        var se = this;
        for (var i in se) {
            if (se[i] === value) {
                return i;
            }
        }
        return false;
    }

    createLine(property1, property2, vis = true, t = 0, b = 0, className = undefined) {
        var row = {};
        if (property1.t === "tm") {
            row = {
                name: property1.templateName, data: this, vis: true
            }
        }
        else {
            row = {
                name: 'row-form-t', data: {
                    className: className,
                    items: [{
                        t: property1.t, name: this.propName(property1.val), val: property1.val,
                        click: property1["click"] ? property1["click"] : null,
                        type: property1["type"] ? property1["type"] : 'text',
                        hlp: property1["hlp"] ? property1["hlp"] : undefined
                    }], t: t, b: b, vis: vis
                }
            }
        }
        switch (property1.t) {
            case "txb":
                row.data.items[0].dis = property1["dis"] ? property1["dis"] : false;
                break;
            case "tsp":
                row.data.items[0].min = property1.min;
                row.data.items[0].max = property1.max;
                row.data.items[0].dis = property1["dis"] ? property1["dis"] : false;
                break;
            case "rdo":
                row.data.items[0].list = property1.list;
                row.data.items[0].className = property1["className"] ? "radio radio-inline " + property1["className"]
                    : "radio radio-success radio-inline";
                break;
            case "txf":
                row.data.items[0].dis = property1["dis"] ? property1["dis"] : false;

                break;
            case "slcfm":
                row.data.items[0].comName = 'ko-formulamaker';
                row.data.items[0].params = {
                    parent: this,
                    name: this.propName(property1.val),
                    disable: property1["dis"] ? property1["dis"] : false,
                    value: property1.val,
                    controllerName: this.parentVM.controllerName
                }
                break;
            case "slcn":
                row.data.items[0].comName = 'ko-nodeselect';
                row.data.items[0].params = {
                    type: property1["slcType"] ? property1["slcType"] : '',
                    parent: this,
                    name: this.propName(property1.val),
                    disable: property1["dis"] ? property1["dis"] : false,
                    value: property1.val,
                    valName: property1.valName,
                    controllerName: this.parentVM.controllerName,
                    treeId: property1.treeId,
                    values: property1["slcType"] ? property1.values : null,
                    branchSelectable: property1.branchSelectable,
                    location: property1.location,
                }
                break;
            case "slc":
                row.data.items[0].comName = 'ko-select';
                row.data.items[0].params = {
                    options: property1.options,
                    parent: this,
                    controllerName: this.parentVM.controllerName,
                    renderFunc: property1["renderFunc"] ? property1["renderFunc"] : '',
                    disable: property1["dis"] ? property1["dis"] : false,
                    name: this.propName(property1.val),
                    value: property1.val,
                    tagManager: property1["tagManager"] ? property1["tagManager"] : null,
                    values: property1["slcType"] ? property1.val : null,
                    type: property1["slcType"] ? property1["slcType"] : '',
                    refreshFunc: property1["refreshFunc"] ? property1["refreshFunc"] : undefined,
                }
                break;
            case "dpk":
                row.data.items[0].comName = 'ko-datepicker';
                row.data.items[0].params = {
                    dateType: property1.dateType,
                    parent: this,
                    disable: property1["dis"] ? property1["dis"] : false,
                    name: this.propName(property1.val),
                    value: property1.val
                }
                break;
        }

        if (property2) {
            row.data.items[1] = {
                t: property2.t, name: this.propName(property2.val), val: property2.val,
                type: property2["type"] ? property2["type"] : 'text',

            };
            switch (property2.t) {
                case "txb":
                    row.data.items[1].dis = property2["dis"] ? property2["dis"] : false;
                    break;
                case "tsp":
                    row.data.items[1].min = property2.min;
                    row.data.items[1].max = property2.max;
                    row.data.items[1].dis = property2["dis"] ? property2["dis"] : false;
                    break;
                case "txf":
                    row.data.items[1].dis = property2["dis"] ? property2["dis"] : false;
                    break;
                case "slc":
                    row.data.items[1].comName = 'ko-select';
                    row.data.items[1].params = {
                        options: property2.options,
                        parent: this,
                        renderFunc: property2["renderFunc"] ? property2["renderFunc"] : '',
                        disable: property2["dis"] ? property2["dis"] : false,
                        name: this.propName(property2.val),
                        value: property2.val,
                        values: property2["slcType"] ? property2.val : null,
                        tagManager: property2["tagManager"] ? property2["tagManager"] : null,
                        type: property2["slcType"] ? property2["slcType"] : ''
                    }
                    break;
                case "dpk":
                    row.data.items[1].comName = 'ko-datepicker';
                    row.data.items[1].params = {
                        dateType: property2.dateType,
                        parent: this,
                        disable: property2["dis"] ? property2["dis"] : false,
                        name: this.propName(property2.val),
                        value: property2.val
                    }
                    break;
            }
        }
        return row;
    }
}

export class BaseFormModel extends FormBuilder {
    constructor(viewModel, editMode, excludeList, customCaptions) {
        super();
        this.parentVM = viewModel;
        this.editMode = ko.observable(editMode || false);
        if (!customCaptions)
            this.caption = ko.observable(!this.editMode() ? _h.getLocalizedText('createCaption') : _h.getLocalizedText('editCaption'));
        else
            this.caption = ko.observable(!this.editMode() ? _h.getLocalizedText(customCaptions[0]) : _h.getLocalizedText(customCaptions[1]));
        if (!excludeList)
            excludeList = ["gParent"];
        else
            excludeList.push("gParent");
        if (editMode) {
            var model = viewModel.multiCommandExecute("selectedRowRecord");
            _autoMapper.fillForm(this, model, excludeList);
        } else {
            var entityName = this.parentVM.entityName;
            if (entityName) {

            }
            var res = window[this.constructor.name.replace("Form", "").toLowerCase() + "ModelRes"];
            if (!res) {
                res = window[entityName.replace("Form", "").toLowerCase() + "ModelRes"];
            }
            _autoMapper.createProps(this, res, excludeList);
        }
    }
}

export class BaseModel {
    constructor(model) {
        _autoMapper.fillModel(this, model);
        this.selected = ko.observable(false);
    }

    createTagId() {
        if (this["id"])
            return this.constructor.name + "-" + this.id();
        else
            return "";
    }

    refreshModel(model) {
        _autoMapper.fillModel(this, model);
    }
}

export class BaseInnerModel {
    constructor(model, paramList) {
        if (model !== null)
            _autoMapper.fillModel(this, model);
        if (paramList && paramList.length > 0)
            _autoMapper.createPropsFromList(this, paramList);
    }

    createTagId() {
        if (this["id"])
            return this.constructor.name + "-" + this.id();
        else if (this["value"])
            return this.constructor.name + "-" + this.value();
        else
            return "";
    }
}

export class BaseInfoModel {
    constructor(model) {
        _autoMapper.fillInfoModel(this, model);
    }
}

export class BaseSecondaryForm extends FormBuilder {
    constructor(viewModel, paramList, caption) {
        super();
        this.parentVM = viewModel;
        if (typeof caption !== 'object')
            this.caption = _h.getLocalizedText(caption);
        else
            this.caption = caption.text;

        _autoMapper.createPropsFromList(this, paramList);
    }
}
