module.exports = Advisor.extend({

  name: 'route',

  initialize: function(advisors, wards) {
    this.router = wards.router;
  },

  navigating: {

    navigate: Advisor.WrapperAction(function(){
      return {
        wrapMethod: [this.router, 'execute'],

        extractData: function(router, methodRetVal, methodArgs){
          return {
            current: router.currentRoute,
            previous: router.previousRoute
          }
        }
      }
    }),

    navigates: Advisor.Stream,

    navigatesTo: Advisor.FactoryStream(function(maybeRouteName){
      return this.navigates.filter(function(advisorEvent){
        var impendingRoute = advisorEvent.data.current.name;
        return impendingRoute.toLowerCase() === maybeRouteName.toLowerCase();
      })
      .map(function(advisorEvent){
        advisorEvent.type = 'route:navigateTo';
        return advisorEvent;
      });
    }),

    navigatesFrom: Advisor.FactoryStream(function(maybeRouteName){
      return this.navigates.filter(function(advisorEvent){
        var previousRoute = advisorEvent.data.previous;
        var previousRouteName = previousRoute && previousRoute.name;
        if(previousRoute) {
          return previousRouteName.toLowerCase() === maybeRouteName.toLowerCase();
        }
        return false;
      })
      .map(function(advisorEvent){
        advisorEvent.type = 'route:navigateFrom';
        return advisorEvent;
      });
    })

  }

});
module.exports = Advisor.extend({

  name: 'people',

  initialize: function(advisors, wards) {
    this.collection = wards.people;
  },

  fetching: {

    fetch: Advisor.WrapperAction(function(){
      return {
        wrapMethod: [this.collection, 'fetch'],
        extractData: function(collection, methodRetVal, methodArgs, baseStream){
          return methodRetVal;
        }
      };
    }),

    fetches: Advisor.Stream,

    hasFetched: Advisor.Stream(function(baseStream, helpers, customStream) {
      var stream = new Bacon.Bus(),
          advisorName = this.name;

      this.collection.on('sync', function(collection, e){
        var eventData = {
          collection: this,
          triggeringEvent: e
        };
        stream.push(new Advisor.Event(advisorName, 'fetched', eventData));
      });

      return stream;
    }),

    isFetching: Advisor.Stream(function(baseStream) {
      return baseStream.awaiting(this.streams.hasFetched);
    })

  },

  resetting: {

    reset: Advisor.Action(function(collection, triggeringEvent){
      return {
        collection: collection,
        triggeringEvent: triggeringEvent
      }
    }),

    resets: Advisor.Stream,

    hasReset: Advisor.Stream(function(baseStream, helpers, customStream) {
      var resetStream = new Bacon.Bus(),
          advisorName = this.name;

      this.collection.on('reset', function(collection, e){
        var eventData = {
          collection: this,
          triggeringEvent: e
        };
        resetStream.push(new Advisor.Event(advisorName, 'reset', eventData));
      });

      return resetStream;
    })

  },

  shuffling: {

    shuffle: Advisor.Action(function(collection, triggeringEvent){
      return {
        collection: collection,
        triggeringEvent: triggeringEvent
      }
    }),

    shuffles: Advisor.Stream,

    hasShuffled: Advisor.Stream(function(baseStream, helpers, customStream) {
      var shuffleStream = new Bacon.Bus(),
          advisorName = this.name;

      this.collection.on('sort', function(collection, e){
        var eventData = {
          collection: this,
          triggeringEvent: e
        };
        shuffleStream.push(new Advisor.Event(advisorName, 'shuffled', eventData));
      });

      return shuffleStream;
    })

  },

  adding: {

    addRandom: Advisor.Action(function(collection, triggeringEvent){
      return {
        collection: collection,
        triggeringEvent: triggeringEvent
      }
    }),

    addsRandom: Advisor.Stream,

    hasAddedRandom: Advisor.Stream(function(baseStream, helpers, customStream) {
      var stream = new Bacon.Bus(),
          advisorName = this.name;

      this.collection.on('add', function(collection, e){
        var eventData = {
          collection: this,
          triggeringEvent: e
        };
        stream.push(new Advisor.Event(advisorName, 'shuffled', eventData));
      });

      return stream;
    })

  }

});