/// <reference path="leaf.ts" />
var Leaf;
(function (Leaf) {
    var Model = (function () {
        function Model(name, _fields) {
            if (_fields === void 0) { _fields = []; }
            var _this = this;
            this.name = name;
            this._fields = _fields;
            this.events = new Leaf.EventEmitter();
            this._data = {};
            for (var _i = 0, _a = this._fields; _i < _a.length; _i++) {
                var field = _a[_i];
                this.define(field);
            }
            Object.defineProperty(this, "fields", {
                get: function () {
                    return _this._fields.slice(0);
                }
            });
            Object.defineProperty(this, "data", {
                get: function () {
                    return _this;
                },
                set: function (values) {
                    _this.sets(values);
                }
            });
        }
        Model.prototype.define = function (name) {
            var _this = this;
            Object.defineProperty(this, name, {
                get: function () {
                    return _this.get(name);
                },
                set: function (value) {
                    return _this.set(name, value);
                }
            });
        };
        Model.prototype.hasKey = function (key) {
            return this._fields.indexOf(key) >= 0;
        };
        Model.prototype.sets = function (obj) {
            if (!obj) {
                return;
            }
            if (obj instanceof Model) {
                obj = obj.toJSON();
            }
            var changed = false;
            var diff = {};
            for (var key in obj) {
                if (!this.hasKey(key)) {
                    continue;
                }
                var old = this._data[key];
                var value = obj[key];
                if (this.set(key, value, true)) {
                    changed = true;
                    this.events.emit("change/" + key, value, old);
                    diff[key] = old;
                }
            }
            if (changed) {
                this.events.emit("change", diff);
            }
        };
        Model.prototype.set = function (key, value, silent) {
            var old = this._data[key];
            if (!this.hasKey(key))
                return false;
            if (old === value) {
                return false;
            }
            this._data[key] = value;
            if (silent)
                return true;
            this.events.emit("change/" + key, value, old);
            var diff = {};
            diff[key] = old;
            this.events.emit("change", diff);
            return true;
        };
        Model.prototype.get = function (key) {
            return this._data[key] || null;
        };
        Model.prototype.toJSON = function () {
            return JSON.parse(JSON.stringify(this._data));
        };
        return Model;
    }());
    Leaf.Model = Model;
})(Leaf || (Leaf = {}));
//# sourceMappingURL=model.js.map