var watchedProperties = {};
var props = {
    gridOptions: {
        default: function () {
            return {};
        }
    }
};
agGrid.ComponentUtil.ALL_PROPERTIES.forEach((propertyName) => {
    props[propertyName] = {};

    watchedProperties[propertyName] = function (val, oldVal) {
        this.processChanges(propertyName, val, oldVal);
    };
});
agGrid.ComponentUtil.EVENTS.forEach((eventName) => {
    props[eventName] = {};
});
Vue.component('ag-grid-vue', {
    render: function (h) {
        return h('div');
    },
    props: props,
    data() {
        return {
            _initialised: false,
            _destroyed: false,
        };
    },
    methods: {
        'globalEventListener': function(eventType, event) {
            if (this._destroyed) {
                return;
            }

            // generically look up the eventType
            var emitter = this[eventType];
            if (emitter) {
                emitter(event);
            }
        },
        'processChanges': function(propertyName, val, oldVal) {
            if (this._initialised) {
                var changes = {};
                changes[propertyName] = {currentValue: val, previousValue: oldVal};
                agGrid.ComponentUtil.processOnChange(changes, this.gridOptions, this.gridOptions.api, this.gridOptions.columnApi);
            }
        }
    },
    mounted() {
        var frameworkComponentWrapper = new VueFrameworkComponentWrapper(this);
        var vueFrameworkFactory = new VueFrameworkFactory(this.$el, this);
        var gridOptions = agGrid.ComponentUtil.copyAttributesToGridOptions(this.gridOptions, this);

        var gridParams = {
            globalEventListener: this.globalEventListener.bind(this),
            frameworkFactory: vueFrameworkFactory,
            seedBeanInstances: {
                frameworkComponentWrapper: frameworkComponentWrapper
            }
        };

        new agGrid.Grid(this.$el, gridOptions, gridParams);

        this._initialised = true;
    },
    watch: watchedProperties,
    destroyed() {
        if (this._initialised) {
            if (this.gridOptions.api) {
                this.gridOptions.api.destroy();
            }
            this._destroyed = true;
        }
    }
});