/* 项目: jdg-core-base
 * 文件: multi_selection
 * 模块名称:
 * Copyright 2018 JDG <www.yunside.com>
 * Created by bjccdsrlcr (longjie.jiang@yunside.com) @ 11/25/19
 */
odoo.define('jd_report.multi_selection', function (require) {
    "use strict";

    var ajax = require('web.ajax');
    var core = require('web.core');
    var crash_manager = require('web.crash_manager');
    var data = require('web.data');
    var datepicker = require('web.datepicker');
    var dom_utils = require('web.dom_utils');
    var Priority = require('web.Priority');
    var ProgressBar = require('web.ProgressBar');
    var Dialog = require('web.Dialog');
    var common = require('web.form_common');
    var formats = require('web.formats');
    var framework = require('web.framework');
    var Model = require('web.DataModel');
    var pyeval = require('web.pyeval');
    var session = require('web.session');
    var utils = require('web.utils');

    var _t = core._t;
    var QWeb = core.qweb;


    var FieldMultiSelection = common.AbstractField.extend(common.ReinitializeFieldMixin, {
        template: 'FieldMultiSelection',
        events: {
            'change': 'store_dom_value',
        },
        init: function (field_manager, node) {
            this._super(field_manager, node);
            this.set("value", false);
            this.set("values", []);
            this.records_orderer = new utils.DropMisordered();
            this.field_manager.on("view_content_has_changed", this, function () {
                var domain = new data.CompoundDomain(this.build_domain()).eval();
                if (!_.isEqual(domain, this.get("domain"))) {
                    this.set("domain", domain);
                }
            });
        },
        initialize_field: function () {
            common.ReinitializeFieldMixin.initialize_field.call(this);
            this.on("change:domain", this, this.query_values);
            this.set("domain", new data.CompoundDomain(this.build_domain()).eval());
            this.on("change:values", this, this.render_value);
        },
        query_values: function () {
            var self = this;
            var def;
            if (this.field.type === "many2one") {
                var model = new Model(this.field.relation);
                def = model.call("name_search", ['', this.get("domain")], {"context": this.build_context()});
            } else {
                var values = _.reject(this.field.selection, function (v) {
                    return v[0] === false && v[1] === '';
                });
                def = $.when(values);
            }
            this.records_orderer.add(def).then(function (values) {
                if (!_.isEqual(values, self.get("values"))) {
                    self.set("values", values);
                }
            });
            this.$el.selectpicker('refresh')
        },
        initialize_content: function () {
            // Flag indicating whether we're in an event chain containing a change
            // event on the select, in order to know what to do on keyup[RETURN]:
            // * If the user presses [RETURN] as part of changing the value of a
            //   selection, we should just let the value change and not let the
            //   event broadcast further (e.g. to validating the current state of
            //   the form in editable list view, which would lead to saving the
            //   current row or switching to the next one)
            // * If the user presses [RETURN] with a select closed (side-effect:
            //   also if the user opened the select and pressed [RETURN] without
            //   changing the selected value), takes the action as validating the row
            if (!this.get('effective_readonly')) {
                var ischanging = false;
                this.$el
                    .change(function () {
                        ischanging = true;
                    })
                    .click(function () {
                        ischanging = false;
                    })
                    .keyup(function (e) {
                        if (e.which !== 13 || !ischanging) {
                            return;
                        }
                        e.stopPropagation();
                        ischanging = false;
                    });
                this.setupFocus(this.$el);
            }
        },
        commit_value: function () {
            this.store_dom_value();
            return this._super();
        },
        store_dom_value: function () {
            if (!this.get('effective_readonly')) {
                var obj = this.$el[0];
                var value = [];
                for (var i = 0; i < obj.options.length; i++) {
                    if (obj.options[i].selected) {
                        value.push(obj.options[i].value) // 收集选中项
                    }
                }
                value = value.join(',');
                this.internal_set_value(value);
            }
        },
        set_value: function (value_) {
            value_ = value_ === null ? false : value_;
            value_ = value_ instanceof Array ? value_[0] : value_;
            this._super(value_);
        },
        render_value: function () {
            var values = this.get("values");
            values = [[false, this.node.attrs.placeholder || '']].concat(values);
            var found = _.find(values, function (el) {
                return el[0] === this.get("value");
            }, this);
            if (!found) {
                found = [this.get("value"), _t('Unknown')];
                values = [found].concat(values);
            }
            if (!this.get("effective_readonly")) {
                this.$el.empty();
                for (var i = 0; i < values.length; i++) {
                    this.$el.append($('<option/>', {
                        value: JSON.stringify(values[i][0]),
                        html: values[i][1]
                    }))
                }
                this.$el.val(JSON.stringify(found[0]));
            } else {
                this.$el.text(found[1]);
            }
            this.$el.selectpicker()
        },
        focus: function () {
            if (!this.get("effective_readonly")) {
                return this.$el.focus();
            }
            return false;
        },
    });


    /**
     * Registry of form fields, called by :js:`instance.web.FormView`.
     *
     * All referenced classes must implement FieldInterface. Those represent the classes whose instances
     * will substitute to the <field> tags as defined in OpenERP's views.
     */
    core.form_widget_registry
        .add('multi_selection', FieldMultiSelection);

    return {
        FieldMultiSelection: FieldMultiSelection
    };

});
