'use strict';var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc);
    switch (arguments.length) {
        case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);
        case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);
        case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);
    }
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var collection_1 = require('angular2/src/facade/collection');
var lang_1 = require('angular2/src/facade/lang');
var di_1 = require('angular2/di');
var di_2 = require('angular2/di');
var Pipes = (function () {
    function Pipes(config) {
        this.config = config;
    }
    Pipes.prototype.get = function (type, obj, cdRef, existingPipe) {
        if (lang_1.isPresent(existingPipe) && existingPipe.supports(obj))
            return existingPipe;
        if (lang_1.isPresent(existingPipe))
            existingPipe.onDestroy();
        var factories = this._getListOfFactories(type, obj);
        var factory = this._getMatchingFactory(factories, type, obj);
        return factory.create(cdRef);
    };
    /**
     * Takes a {@link Pipes} config object and returns a binding used to extend the
     * inherited {@link Pipes} instance with the provided config and return a new
     * {@link Pipes} instance.
     *
     * If the provided config contains a key that is not yet present in the
     * inherited {@link Pipes}' config, a new {@link PipeFactory} list will be created
     * for that key. Otherwise, the provided config will be merged with the inherited
     * {@link Pipes} instance by prepending pipes to their respective keys, without mutating
     * the inherited {@link Pipes}.
     *
     * The following example shows how to extend an existing list of `async` factories
     * with a new {@link PipeFactory}, which will only be applied to the injector
     * for this component and its children. This step is all that's required to make a new
     * pipe available to this component's template.
     *
     * # Example
     *
     * ```
     * @Component({
     *   viewInjector: [
     *     Pipes.extend({
     *       async: [newAsyncPipe]
     *     })
     *   ]
     * })
     * ```
     */
    Pipes.extend = function (config) {
        return new di_2.Binding(Pipes, {
            toFactory: function (pipes) {
                if (lang_1.isBlank(pipes)) {
                    // Typically would occur when calling Pipe.extend inside of dependencies passed to
                    // bootstrap(), which would override default pipes instead of extending them.
                    throw new lang_1.BaseException('Cannot extend Pipes without a parent injector');
                }
                return Pipes.create(config, pipes);
            },
            // Dependency technically isn't optional, but we can provide a better error message this way.
            deps: [[Pipes, new di_1.UnboundedMetadata(), new di_1.OptionalMetadata()]]
        });
    };
    Pipes.create = function (config, pipes) {
        if (pipes === void 0) { pipes = null; }
        if (lang_1.isPresent(pipes)) {
            collection_1.StringMapWrapper.forEach(pipes.config, function (v, k) {
                if (collection_1.StringMapWrapper.contains(config, k)) {
                    var configFactories = config[k];
                    config[k] = configFactories.concat(v);
                }
                else {
                    config[k] = collection_1.ListWrapper.clone(v);
                }
            });
        }
        return new Pipes(config);
    };
    Pipes.prototype._getListOfFactories = function (type, obj) {
        var listOfFactories = this.config[type];
        if (lang_1.isBlank(listOfFactories)) {
            throw new lang_1.BaseException("Cannot find '" + type + "' pipe supporting object '" + obj + "'");
        }
        return listOfFactories;
    };
    Pipes.prototype._getMatchingFactory = function (listOfFactories, type, obj) {
        var matchingFactory = collection_1.ListWrapper.find(listOfFactories, function (pipeFactory) { return pipeFactory.supports(obj); });
        if (lang_1.isBlank(matchingFactory)) {
            throw new lang_1.BaseException("Cannot find '" + type + "' pipe supporting object '" + obj + "'");
        }
        return matchingFactory;
    };
    Pipes = __decorate([
        di_1.Injectable(),
        lang_1.CONST(), 
        __metadata('design:paramtypes', [Object])
    ], Pipes);
    return Pipes;
})();
exports.Pipes = Pipes;
//# sourceMappingURL=pipes.js.map