import { default as BaseModel } from "./BaseModel.js";
export default class FeatureModel extends BaseModel {
    constructor(options) {
        super(options);
        this.m_errors = [];
        this.m_index = null;
        this.m_postbackOnChangeThrottle = _.throttle((triggerPostback) => {
            if (triggerPostback) {
                this.root.postbackHandler();
            }
        }, 500);
        this.m_parent = options.parent;
        this.state.unset("parent");
        this.m_initializer = _.camelCase(this.binding.slice(this.binding.lastIndexOf(".") + 1));
    }
    get id() {
        return this.binding;
    }
    get attributes() {
        return this.state.get("attributes");
    }
    get binding() {
        return this.state.get("binding");
    }
    get parent() {
        return this.m_parent;
    }
    get initializers() {
        return this.root.initializers[this.m_initializer];
    }
    get index() {
        if (this.m_index === null) {
            this.m_index = this.getIndex();
        }
        return this.m_index;
    }
    get dynamics() {
        return this.state.get("dynamics", []);
    }
    get errors() {
        return this.root.errors.getByFeature(this.parent.index, this.index);
    }
    get featureSet() {
        return this.root.context.featureSet;
    }
    getEditors() {
        return this.root.editors.getEditorsByFeature(this);
    }
    getValue(id, defaultValue) {
        if (this.hasFlex(id)) {
            return this.state.get(`flex.values.${id}.value`, defaultValue);
        }
        return this.state.get(id, defaultValue);
    }
    setValue(id, value, options = {}) {
        let args = {
            name: id,
            oldValue: this.getValue(id),
            newValue: value,
            cancel: false
        };
        let resolvedId = this.hasFlex(id) ?
            `flex.values.${id}.value` : id;
        if (!options.silent && this.hasValueChanged(resolvedId, value)) {
            this.featureSet.controller.valueChanged(args);
            this.root
                .context
                .globals
                .events
                .featureValueChangedPublish(args);
        }
        if (args.cancel) {
            return;
        }
        this.state.set(resolvedId, value, options);
        this.m_postbackOnChangeThrottle(options.postback);
    }
    getRemoteValue(key, defaultValue) {
        return this.root.context.featureSet.getValue(key, defaultValue);
    }
    setRemoteValue(key, value, options = {}) {
        this.root.context.featureSet.setValue(key, value, options);
    }
    toJSON() {
        return this.state.attributes;
    }
    onStateChanged() {
        super.onStateChanged();
        let set = this.parent.parent;
        let group = this.parent;
        let feature;
        let changed = this.state.changed;
        Object.keys(changed).forEach(key => {
            set.valueChanged({
                group: group,
                feature: feature,
                name: key,
                value: this.state.get(key)
            });
        });
    }
    getIndex() {
        let result = null;
        this.parent.features.some((feature, index) => {
            if (feature.id === this.id) {
                result = index;
                return true;
            }
        });
        return result;
    }
    hasProperty(id) {
        return this.state.attributes[id] !== undefined;
    }
    hasFlex(id) {
        return this.state.attributes.flex?.values[id] !== undefined;
    }
    hasValueChanged(id, newValue) {
        return this.state.get(id) !== newValue;
    }
}
