ProspectDirector.Web.UI.Packagers.Packager =
Class.extend({

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

    _context: null,
    _errors: null,
    _commands: null,
    _handlers: null,
    _products: null,

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

    init: function (options) {

        var clone = $.extend(true, {}, {
            commands: options.commands
        });

        this._context = options.context;
        this._errors = new ProspectDirector.Web.List();
        this._commands = new ProspectDirector.Web.List(clone.commands);
        this._handlers = new ProspectDirector.Web.List();
        this._products = new ProspectDirector.Web.List();

    },

    //================================
    // PROPERETIES
    //================================

    get_context: function () {
        return this._context;
    },

    get_commands: function () {
        return this._commands;
    },

    get_handlers: function () {
        return this._handlers;
    },

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

    execute: function (success, error) {

        if (this._handlers.count() === 0) {
            this._buildHandlers(this._context);
        }

        this._executeHandlers();

        if (this._errors.count() > 0) {
            if (error) {
                error(this._errors);
            }
        }
        else {
            success(this._products);
        }

    },

    onRequestHandler: function (command) {

        return new ProspectDirector.Web.UI.Packagers.PackagerCommandHandler({
            command: command,
            context: this._context
        });

    },

    onExecuteHandler: function (handler) {
        return handler.execute();
    },

    //================================
    // PRIVATE METHODS
    //================================

    _buildHandlers: function () {

        var that = this;

        this._commands.each(function (index, command) {

            var handler = that.onRequestHandler(command);

            if (handler) {
                that._handlers.add(handler);
            }

        });

    },

    _executeHandlers: function () {

        var that = this;

        this._handlers.each(function (index, handler) {

            var product = that.onExecuteHandler(handler);

            handler.get_errors().each(function (index, error) {
                that._errors.add(error);
            });

            that._products.add(product);

        });

    }

});