/// class PD.Web.UI.Controls.GridDataSource

PD.Web.UI.Controls.GridDataSource =
Class.extend({

    //===================================
    // FIELDS
    //===================================

    _grid: null,
    _dataSource: null,
    _dataSourceOnReadCallback: null,
    _localVariableDataSource: null,

    //===================================
    // CONSTRUCTOR
    //===================================

    init: function (options) {
        this._options = $.extend({}, options);
        this._dataSource = null;
        this._originalOptions = {};
        PD.BCL.Observable.mixin(this);
    },

    //===================================
    // PROPERTIES
    //===================================

    get_instance: function () {
        return this._dataSource;
    },

    get_options: function () {
        return this._options;
    },

    get_grid: function () {
        return this._grid;
    },

    get_storeAsLocalVariable: function() {
        return this.get_grid().getOption("dataSource.storeAsLocalVariable", false);
    },

    //===================================
    // EVENT HANDLERS
    //===================================

    _onDataSourceRead: function () {

        var result = this.getReadParameters() || {};

        if (this._dataSourceOnReadCallback) {
            result = this._dataSourceOnReadCallback(result) || {};
        }

        this.trigger("dataSourceRead", result);

        return result;

    },

    _onDataSourceChange: function () {
        // do nothing on purpose
    },

    _onDataSourceError: function (e) {
        new PDJS.AjaxErrorHandler({
            jqXHR: e.xhr
        });
    },

    _onDataSourceDataBind: function (e) {

    },

    //===================================
    // PUBLIC METHODS
    //===================================

    execute: function (grid, onReadyCallback) {

        var that = this;

        this._grid = grid;

        this.getDataSource(function (dataSource) {
            that._dataSource = dataSource;
            if (PD.Type.isFunction(onReadyCallback)) {
                $.proxy(onReadyCallback, grid)(that);
            }
        });

    },

    data: function (data) {

        if (this.get_storeAsLocalVariable()) {
            this._localVariableDataSource = data;
        }

        return this._dataSource.data(data);

    },

    read: function () {
        if (this._localVariableDataSource != null) {
            this._dataSource.fetch();
        }
        else {
            this._dataSource.read();
        }
    },

    //===================================
    // OVERRIDABLE METHODS
    //===================================

    getDataSource: function (onComplete) {

        var that = this;
        var ds = null;
        var dsOptions = this.get_grid().getOption("dataSource", {});
        var isLocalDataSource = ("data" in dsOptions);

        if (!isLocalDataSource) {
            $.extend(true, {}, dsOptions, {
                transport: {
                    read: {
                        type: "GET",
                        data: $.proxy(this._onDataSourceRead, this)
                    }
                },
                schema: {
                    data: "data"
                }
            });
        }
        else {

            if (this.get_grid().getOption("dataSource.storeAsLocalVariable", false)) {

                $.extend(true, {}, dsOptions, {
                    transport: {
                        read: function (e) {
                            e.success(that._localVariableDataSource);
                        }
                    },
                    schema: {
                        data: "data"
                    }
                });

                this._localVariableDataSource = [];

            }

        }

        this._dataSourceOnReadCallback = this.get_grid().getOption("dataSource.transport.read.data");

        ds = new kendo.data.DataSource(dsOptions);
        ds.bind("change", $.proxy(this._onDataSourceChange, this));
        ds.bind("error", $.proxy(this._onDataSourceError, this));

        onComplete(ds);

    },

    getReadParameters: function () {
        return {};
    }

});