// Backbone.Wreqr (Backbone.Marionette)
// ----------------------------------
// v1.3.1
//
// Copyright (c)2014 Derick Bailey, Muted Solutions, LLC.
// Distributed under MIT license
//
// http://github.com/marionettejs/backbone.wreqr


(function(root, factory) {

  if (typeof define === 'function' && define.amd) {
    define(['backbone', 'underscore'], function(Backbone, _) {
      return factory(Backbone, _);
    });
  } else if (typeof exports !== 'undefined') {
    var Backbone = require('backbone');
    var _ = require('underscore');
    module.exports = factory(Backbone, _);
  } else {
    factory(root.Backbone, root._);
  }

}(this, function(Backbone, _) {
  "use strict";

  var previousWreqr = Backbone.Wreqr;

  var Wreqr = Backbone.Wreqr = {};

  Backbone.Wreqr.VERSION = '1.3.1';

  Backbone.Wreqr.noConflict = function () {
    Backbone.Wreqr = previousWreqr;
    return this;
  };

  // Handlers
  // --------
  // A registry of functions to call, given a name
  
  Wreqr.Handlers = (function(Backbone, _){
    "use strict";
    
    // Constructor
    // -----------
  
    var Handlers = function(options){
      this.options = options;
      this._wreqrHandlers = {};
      
      if (_.isFunction(this.initialize)){
        this.initialize(options);
      }
    };
  
    Handlers.extend = Backbone.Model.extend;
  
    // Instance Members
    // ----------------
  
    _.extend(Handlers.prototype, Backbone.Events, {
  
      // Add multiple handlers using an object literal configuration
      setHandlers: function(handlers){
        _.each(handlers, function(handler, name){
          var context = null;
  
          if (_.isObject(handler) && !_.isFunction(handler)){
            context = handler.context;
            handler = handler.callback;
          }
  
          this.setHandler(name, handler, context);
        }, this);
      },
  
      // Add a handler for the given name, with an
      // optional context to run the handler within
      setHandler: function(name, handler, context){
        var config = {
          callback: handler,
          context: context
        };
  
        this._wreqrHandlers[name] = config;
  
        this.trigger("handler:add", name, handler, context);
      },
  
      // Determine whether or not a handler is registered
      hasHandler: function(name){
        return !! this._wreqrHandlers[name];
      },
  
      // Get the currently registered handler for
      // the specified name. Throws an exception if
      // no handler is found.
      getHandler: function(name){
        var config = this._wreqrHandlers[name];
  
        if (!config){
          return;
        }
  
        return function(){
          var args = Array.prototype.slice.apply(arguments);
          return config.callback.apply(config.context, args);
        };
      },
  
      // Remove a handler for the specified name
      removeHandler: function(name){
        delete this._wreqrHandlers[name];
      },
  
      // Remove all handlers from this registry
      removeAllHandlers: function(){
        this._wreqrHandlers = {};
      }
    });
  
    return Handlers;
  })(Backbone, _);
  
  // Wreqr.CommandStorage
  // --------------------
  //
  // Store and retrieve commands for execution.
  Wreqr.CommandStorage = (function(){
    "use strict";
  
    // Constructor function
    var CommandStorage = function(options){
      this.options = options;
      this._commands = {};
  
      if (_.isFunction(this.initialize)){
        this.initialize(options);
      }
    };
  
    // Instance methods
    _.extend(CommandStorage.prototype, Backbone.Events, {
  
      // Get an object literal by command name, that contains
      // the `commandName` and the `instances` of all commands
      // represented as an array of arguments to process
      getCommands: function(commandName){
        var commands = this._commands[commandName];
  
        // we don't have it, so add it
        if (!commands){
  
          // build the configuration
          commands = {
            command: commandName, 
            instances: []
          };
  
          // store it
          this._commands[commandName] = commands;
        }
  
        return commands;
      },
  
      // Add a command by name, to the storage and store the
      // args for the command
      addCommand: function(commandName, args){
        var command = this.getCommands(commandName);
        command.instances.push(args);
      },
  
      // Clear all commands for the given `commandName`
      clearCommands: function(commandName){
        var command = this.getCommands(commandName);
        command.instances = [];
      }
    });
  
    return CommandStorage;
  })();
  
  // Wreqr.Commands
  // --------------
  //
  // A simple command pattern implementation. Register a command
  // handler and execute it.
  Wreqr.Commands = (function(Wreqr){
    "use strict";
  
    return Wreqr.Handlers.extend({
      // default storage type
      storageType: Wreqr.CommandStorage,
  
      constructor: function(options){
        this.options = options || {};
  
        this._initializeStorage(this.options);
        this.on("handler:add", this._executeCommands, this);
  
        var args = Array.prototype.slice.call(arguments);
        Wreqr.Handlers.prototype.constructor.apply(this, args);
      },
  
      // Execute a named command with the supplied args
      execute: function(name, args){
        name = arguments[0];
        args = Array.prototype.slice.call(arguments, 1);
  
        if (this.hasHandler(name)){
          this.getHandler(name).apply(this, args);
        } else {
          this.storage.addCommand(name, args);
        }
  
      },
  
      // Internal method to handle bulk execution of stored commands
      _executeCommands: function(name, handler, context){
        var command = this.storage.getCommands(name);
  
        // loop through and execute all the stored command instances
        _.each(command.instances, function(args){
          handler.apply(context, args);
        });
  
        this.storage.clearCommands(name);
      },
  
      // Internal method to initialize storage either from the type's
      // `storageType` or the instance `options.storageType`.
      _initializeStorage: function(options){
        var storage;
  
        var StorageType = options.storageType || this.storageType;
        if (_.isFunction(StorageType)){
          storage = new StorageType();
        } else {
          storage = StorageType;
        }
  
        this.storage = storage;
      }
    });
  
  })(Wreqr);
  
  // Wreqr.RequestResponse
  // ---------------------
  //
  // A simple request/response implementation. Register a
  // request handler, and return a response from it
  Wreqr.RequestResponse = (function(Wreqr){
    "use strict";
  
    return Wreqr.Handlers.extend({
      request: function(){
        var name = arguments[0];
        var args = Array.prototype.slice.call(arguments, 1);
        if (this.hasHandler(name)) {
          return this.getHandler(name).apply(this, args);
        }
      }
    });
  
  })(Wreqr);
  
  // Event Aggregator
  // ----------------
  // A pub-sub object that can be used to decouple various parts
  // of an application through event-driven architecture.
  
  Wreqr.EventAggregator = (function(Backbone, _){
    "use strict";
    var EA = function(){};
  
    // Copy the `extend` function used by Backbone's classes
    EA.extend = Backbone.Model.extend;
  
    // Copy the basic Backbone.Events on to the event aggregator
    _.extend(EA.prototype, Backbone.Events);
  
    return EA;
  })(Backbone, _);
  
  // Wreqr.Channel
  // --------------
  //
  // An object that wraps the three messaging systems:
  // EventAggregator, RequestResponse, Commands
  Wreqr.Channel = (function(Wreqr){
    "use strict";
  
    var Channel = function(channelName) {
      this.vent        = new Backbone.Wreqr.EventAggregator();
      this.reqres      = new Backbone.Wreqr.RequestResponse();
      this.commands    = new Backbone.Wreqr.Commands();
      this.channelName = channelName;
    };
  
    _.extend(Channel.prototype, {
  
      // Remove all handlers from the messaging systems of this channel
      reset: function() {
        this.vent.off();
        this.vent.stopListening();
        this.reqres.removeAllHandlers();
        this.commands.removeAllHandlers();
        return this;
      },
  
      // Connect a hash of events; one for each messaging system
      connectEvents: function(hash, context) {
        this._connect('vent', hash, context);
        return this;
      },
  
      connectCommands: function(hash, context) {
        this._connect('commands', hash, context);
        return this;
      },
  
      connectRequests: function(hash, context) {
        this._connect('reqres', hash, context);
        return this;
      },
  
      // Attach the handlers to a given message system `type`
      _connect: function(type, hash, context) {
        if (!hash) {
          return;
        }
  
        context = context || this;
        var method = (type === 'vent') ? 'on' : 'setHandler';
  
        _.each(hash, function(fn, eventName) {
          this[type][method](eventName, _.bind(fn, context));
        }, this);
      }
    });
  
  
    return Channel;
  })(Wreqr);
  
  // Wreqr.Radio
  // --------------
  //
  // An object that lets you communicate with many channels.
  Wreqr.radio = (function(Wreqr){
    "use strict";
  
    var Radio = function() {
      this._channels = {};
      this.vent = {};
      this.commands = {};
      this.reqres = {};
      this._proxyMethods();
    };
  
    _.extend(Radio.prototype, {
  
      channel: function(channelName) {
        if (!channelName) {
          throw new Error('Channel must receive a name');
        }
  
        return this._getChannel( channelName );
      },
  
      _getChannel: function(channelName) {
        var channel = this._channels[channelName];
  
        if(!channel) {
          channel = new Wreqr.Channel(channelName);
          this._channels[channelName] = channel;
        }
  
        return channel;
      },
  
      _proxyMethods: function() {
        _.each(['vent', 'commands', 'reqres'], function(system) {
          _.each( messageSystems[system], function(method) {
            this[system][method] = proxyMethod(this, system, method);
          }, this);
        }, this);
      }
    });
  
  
    var messageSystems = {
      vent: [
        'on',
        'off',
        'trigger',
        'once',
        'stopListening',
        'listenTo',
        'listenToOnce'
      ],
  
      commands: [
        'execute',
        'setHandler',
        'setHandlers',
        'removeHandler',
        'removeAllHandlers'
      ],
  
      reqres: [
        'request',
        'setHandler',
        'setHandlers',
        'removeHandler',
        'removeAllHandlers'
      ]
    };
  
    var proxyMethod = function(radio, system, method) {
      return function(channelName) {
        var messageSystem = radio._getChannel(channelName)[system];
        var args = Array.prototype.slice.call(arguments, 1);
  
        return messageSystem[method].apply(messageSystem, args);
      };
    };
  
    return new Radio();
  
  })(Wreqr);
  

  return Backbone.Wreqr;

}));
