"use strict";
/**
 * 监听属性值变化对象
 *
 * @class IBizListenProperty
 */
var IBizListenProperty = /** @class */ (function () {
    /**
     *Creates an instance of IBizListenProperty.
     * @memberof IBizListenProperty
     */
    function IBizListenProperty() {
        /**
         * 数组需监听的方法集合
         *
         * @type {Array<String>}
         * @memberof IBizListenProperty
         */
        this.methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
        /**
         * 数组对象的原型
         *
         * @type {*}
         * @memberof IBizListenProperty
         */
        this.arrayProto = Array.prototype;
        /**
         * 根据数组原型创建的对象
         *
         * @type {*}
         * @memberof IBizListenProperty
         */
        this.arrayMethods = null;
        var _this = this;
        _this.arrayMethods = Object.create(_this.arrayProto);
        _this.methods.forEach(function (method) {
            Object.defineProperty(_this.arrayMethods, method, {
                value: function mutator() {
                    var original = _this.arrayProto[method];
                    var args = [];
                    var len = arguments.length;
                    while (len--) {
                        args[len] = arguments[len];
                    }
                    var data = [];
                    this.forEach(function (item) {
                        data.push(item);
                    });
                    var result = original.apply(data, args);
                    var bo = this.__bo__;
                    delete this.__bo__;
                    bo.obj[bo.key] = data;
                    _this.listenArray(bo.obj, bo.key).subscribe(function (data) {
                        bo.subscribe(data);
                    });
                }
            });
        });
    }
    /**
     * 创建对象
     *
     * @static
     * @memberof IBizListenProperty
     */
    IBizListenProperty.create = function () {
        this.listenObj = new IBizListenProperty();
    };
    /**
     * 注册需监听的对象
     *
     * @static
     * @param {*} obj
     * @returns
     * @memberof IBizListenProperty
     */
    IBizListenProperty.regListenObject = function (obj) {
        var _this_1 = this;
        var subject = new rxjs.Subject();
        if (obj instanceof Object) {
            var keys = Object.keys(obj);
            keys.forEach(function (key) {
                var val = obj[key];
                var args = { name: key };
                if (Array.isArray(val)) {
                    _this_1.listenObj.listenArray(obj, key).subscribe(function (data) {
                        Object.assign(args, data);
                        subject.next(args);
                    });
                }
                else if (val instanceof Object) {
                    _this_1.listenObj.listenObject(val).subscribe(function (data) {
                        Object.assign(args, data);
                        subject.next(args);
                    });
                }
                _this_1.listenObj.defineProperty(obj, key).subscribe(function (data) {
                    Object.assign(args, data);
                    subject.next(args);
                });
            });
        }
        return subject;
    };
    /**
     * 监听数组
     *
     * @param {*} obj
     * @param {string} key
     * @memberof IBizListenProperty
     */
    IBizListenProperty.prototype.listenArray = function (obj, key) {
        var _this = this;
        var subject = new rxjs.Subject();
        if (obj instanceof Object && key) {
            var arr = obj[key];
            arr.__bo__ = { obj: obj, key: key, subscribe: subject.next };
            var augment = arr.__proto__ ? this.protoAugment : this.copyAugment;
            augment(arr, this.arrayMethods, key);
            _this.listenObject(arr).subscribe(function (data) {
                subject.next(data);
            });
        }
        return subject;
    };
    /**
     * 监听对象
     *
     * @param {*} obj
     * @returns {Subject<any>}
     * @memberof IBizListenProperty
     */
    IBizListenProperty.prototype.listenObject = function (obj) {
        var _this = this;
        var subject = new rxjs.Subject();
        if (obj instanceof Object) {
            var keys = Object.keys(obj);
            keys.forEach(function (key) {
                var val = obj[key];
                if (val instanceof Object) {
                    if (Array.isArray(val)) {
                        _this.listenArray(obj, key);
                    }
                }
                _this.defineProperty(obj, key).subscribe(function (args) {
                    subject.next(args);
                });
            });
        }
        return subject;
    };
    /**
     * 监听属性值
     *
     * @param {*} obj
     * @param {string} key
     * @returns
     * @memberof IBizListenProperty
     */
    IBizListenProperty.prototype.defineProperty = function (obj, key) {
        var subject = new rxjs.Subject();
        if (obj instanceof Object && key) {
            var value_1 = obj[key];
            var args_1 = {};
            Object.defineProperty(obj, key, {
                enumerable: true,
                configurable: true,
                get: function () {
                    return value_1;
                },
                set: function (newVal) {
                    if (newVal === value_1)
                        return;
                    var val = value_1;
                    value_1 = newVal;
                    Object.assign(args_1, { newVal: value_1, oldVal: val, property: key });
                    subject.next(args_1);
                }
            });
        }
        return subject;
    };
    /**
     * 辅助方法
     *
     * @param {*} obj
     * @param {*} key
     * @param {*} val
     * @memberof IBizListenProperty
     */
    IBizListenProperty.prototype.define = function (obj, key, val) {
        Object.defineProperty(obj, key, {
            value: val,
            enumerable: true,
            writable: true,
            configurable: true
        });
    };
    /**
     * 重新赋值Array的__proto__属性
     *
     * @param {*} target
     * @param {*} src
     * @param {*} opt
     * @memberof IBizListenProperty
     */
    IBizListenProperty.prototype.protoAugment = function (target, src, opt) {
        target.__proto__ = src;
    };
    /**
     * 不支持__proto__的直接修改相关属性方法
     *
     * @param {*} target
     * @param {*} src
     * @param {*} keys
     * @memberof IBizListenProperty
     */
    IBizListenProperty.prototype.copyAugment = function (target, src, keys) {
        var _this = this;
        keys.forEach(function (key) {
            _this.define(target, src, key);
        });
    };
    /**
     * 监听对象
     *
     * @static
     * @type {IBizListenProperty}
     * @memberof IBizListenProperty
     */
    IBizListenProperty.listenObj = null;
    return IBizListenProperty;
}());
/**
 * 创建对象
 */
IBizListenProperty.create();
