var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
/**
 * @module ol/source/Source
 */
import BaseObject from '../Object.js';
import { abstract } from '../util.js';
import { get as getProjection } from '../proj.js';
/**
 * @typedef {'undefined' | 'loading' | 'ready' | 'error'} State
 * State of the source, one of 'undefined', 'loading', 'ready' or 'error'.
 */
/**
 * A function that takes a {@link module:ol/PluggableMap~FrameState} and returns a string or
 * an array of strings representing source attributions.
 *
 * @typedef {function(import("../PluggableMap.js").FrameState): (string|Array<string>)} Attribution
 */
/**
 * A type that can be used to provide attribution information for data sources.
 *
 * It represents either
 * * a simple string (e.g. `'© Acme Inc.'`)
 * * an array of simple strings (e.g. `['© Acme Inc.', '© Bacme Inc.']`)
 * * a function that returns a string or array of strings ({@link module:ol/source/Source~Attribution})
 *
 * @typedef {string|Array<string>|Attribution} AttributionLike
 */
/**
 * @typedef {Object} Options
 * @property {AttributionLike} [attributions] Attributions.
 * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
 * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
 * @property {import("./Source.js").State} [state='ready'] State.
 * @property {boolean} [wrapX=false] WrapX.
 * @property {boolean} [interpolate=false] Use interpolated values when resampling.  By default,
 * the nearest neighbor is used when resampling.
 */
/**
 * @classdesc
 * Abstract base class; normally only used for creating subclasses and not
 * instantiated in apps.
 * Base class for {@link module:ol/layer/Layer~Layer} sources.
 *
 * A generic `change` event is triggered when the state of the source changes.
 * @abstract
 * @api
 */
var Source = /** @class */ (function (_super) {
    __extends(Source, _super);
    /**
     * @param {Options} options Source options.
     */
    function Source(options) {
        var _this = _super.call(this) || this;
        /**
         * @protected
         * @type {import("../proj/Projection.js").default|null}
         */
        _this.projection = getProjection(options.projection);
        /**
         * @private
         * @type {?Attribution}
         */
        _this.attributions_ = adaptAttributions(options.attributions);
        /**
         * @private
         * @type {boolean}
         */
        _this.attributionsCollapsible_ =
            options.attributionsCollapsible !== undefined
                ? options.attributionsCollapsible
                : true;
        /**
         * This source is currently loading data. Sources that defer loading to the
         * map's tile queue never set this to `true`.
         * @type {boolean}
         */
        _this.loading = false;
        /**
         * @private
         * @type {import("./Source.js").State}
         */
        _this.state_ = options.state !== undefined ? options.state : 'ready';
        /**
         * @private
         * @type {boolean}
         */
        _this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;
        /**
         * @private
         * @type {boolean}
         */
        _this.interpolate_ = !!options.interpolate;
        /**
         * @protected
         * @type {function(import("../View.js").ViewOptions):void}
         */
        _this.viewResolver = null;
        /**
         * @protected
         * @type {function(Error):void}
         */
        _this.viewRejector = null;
        var self = _this;
        /**
         * @private
         * @type {Promise<import("../View.js").ViewOptions>}
         */
        _this.viewPromise_ = new Promise(function (resolve, reject) {
            self.viewResolver = resolve;
            self.viewRejector = reject;
        });
        return _this;
    }
    /**
     * Get the attribution function for the source.
     * @return {?Attribution} Attribution function.
     * @api
     */
    Source.prototype.getAttributions = function () {
        return this.attributions_;
    };
    /**
     * @return {boolean} Attributions are collapsible.
     * @api
     */
    Source.prototype.getAttributionsCollapsible = function () {
        return this.attributionsCollapsible_;
    };
    /**
     * Get the projection of the source.
     * @return {import("../proj/Projection.js").default|null} Projection.
     * @api
     */
    Source.prototype.getProjection = function () {
        return this.projection;
    };
    /**
     * @abstract
     * @return {Array<number>|null} Resolutions.
     */
    Source.prototype.getResolutions = function () {
        return abstract();
    };
    /**
     * @return {Promise<import("../View.js").ViewOptions>} A promise for view-related properties.
     */
    Source.prototype.getView = function () {
        return this.viewPromise_;
    };
    /**
     * Get the state of the source, see {@link import("./Source.js").State} for possible states.
     * @return {import("./Source.js").State} State.
     * @api
     */
    Source.prototype.getState = function () {
        return this.state_;
    };
    /**
     * @return {boolean|undefined} Wrap X.
     */
    Source.prototype.getWrapX = function () {
        return this.wrapX_;
    };
    /**
     * @return {boolean} Use linear interpolation when resampling.
     */
    Source.prototype.getInterpolate = function () {
        return this.interpolate_;
    };
    /**
     * Refreshes the source. The source will be cleared, and data from the server will be reloaded.
     * @api
     */
    Source.prototype.refresh = function () {
        this.changed();
    };
    /**
     * Set the attributions of the source.
     * @param {AttributionLike|undefined} attributions Attributions.
     *     Can be passed as `string`, `Array<string>`, {@link module:ol/source/Source~Attribution},
     *     or `undefined`.
     * @api
     */
    Source.prototype.setAttributions = function (attributions) {
        this.attributions_ = adaptAttributions(attributions);
        this.changed();
    };
    /**
     * Set the state of the source.
     * @param {import("./Source.js").State} state State.
     */
    Source.prototype.setState = function (state) {
        this.state_ = state;
        this.changed();
    };
    return Source;
}(BaseObject));
/**
 * Turns the attributions option into an attributions function.
 * @param {AttributionLike|undefined} attributionLike The attribution option.
 * @return {Attribution|null} An attribution function (or null).
 */
function adaptAttributions(attributionLike) {
    if (!attributionLike) {
        return null;
    }
    if (Array.isArray(attributionLike)) {
        return function (frameState) {
            return attributionLike;
        };
    }
    if (typeof attributionLike === 'function') {
        return attributionLike;
    }
    return function (frameState) {
        return [attributionLike];
    };
}
export default Source;
//# sourceMappingURL=Source.js.map