import { default as BaseModel } from "./BaseModel.js";
import GroupModel from "./GroupModel.js";
import ControllerModel from "./ControllerModel.js";
export default class SetModel extends BaseModel {
    constructor(options) {
        super(options);
        this.m_groups = [];
        this.m_parent = options.parent;
        this.state.unset("parent");
        options.data.groups.forEach((group, index) => {
            this.m_groups[this.m_groups.length] =
                new GroupModel({
                    data: group,
                    parent: this,
                    root: this.root
                });
        });
    }
    get parent() {
        return this.m_parent;
    }
    get groups() {
        return this.m_groups;
    }
    get controller() {
        this.ensureController();
        return this.m_controller;
    }
    get controllerTypeName() {
        return this.state.get("controller");
    }
    get valueChangesAreSilent() {
        return this.m_valueChangesAreSilent;
    }
    set valueChangesAreSilent(value) {
        this.m_valueChangesAreSilent = value;
    }
    valueChanged(args) {
        this.root.context.globals.events.publish("fb:feature:value:changed", {
            group: args.group,
            feature: args.feature,
            name: args.name,
            value: args.value
        });
    }
    onValueChanged(subscriber) {
        return this.root.context.globals.events.subscribe("fb:feature:value:changed", subscriber);
    }
    toJSON() {
        return {
            groups: this.groups.map(group => {
                return group.toJSON();
            })
        };
    }
    hasChanges() {
        let result = false;
        this.groups.forEach(group => {
            group.features.forEach(feature => {
                if (result == false) {
                    result = _.keys(feature.state.changed).length > 0;
                }
                ;
            });
        });
        return result;
    }
    getValue(key, defaultValue) {
        var result = undefined;
        this.groups.forEach((group) => {
            if (result == undefined) {
                group.features.forEach(feature => {
                    if (result === undefined) {
                        let value = feature.getValue(key);
                        if (value != undefined) {
                            result = value;
                        }
                    }
                });
            }
        });
        return result === undefined || result == null ?
            defaultValue : result;
    }
    setValue(key, value, options = {}) {
        let found = false;
        this.groups.forEach((group) => {
            if (found == false) {
                group.features.forEach(feature => {
                    if (found == false) {
                        let foundValue = feature.getValue(key);
                        if (foundValue !== undefined) {
                            feature.setValue(key, value, options);
                            found = true;
                        }
                    }
                });
            }
        });
    }
    ensureController() {
        if (!this.m_controller) {
            let type = Jade.Type.getType(this.controllerTypeName) || ControllerModel;
            if (type) {
                try {
                    this.m_controller = this.createController(type);
                }
                catch (ex) {
                    this.m_controller = this.createController(ControllerModel);
                }
            }
        }
    }
    createController(type) {
        return new type({
            parent: this,
            data: {},
            root: this.root
        });
    }
}
