(function() {
  var Watchers, _, bundle, chokidar, pathHelpers;

  _ = require("lodash");

  chokidar = require("chokidar");

  bundle = require("./util/bundle");

  pathHelpers = require("./util/path_helpers");

  Watchers = (function() {
    function Watchers() {
      if (!(this instanceof Watchers)) {
        return new Watchers;
      }
      this.watchers = {};
      this.bundleWatchers = {};
    }

    Watchers.prototype.close = function() {
      var filePath, results;
      for (filePath in this.watchers) {
        this._remove(filePath);
      }
      results = [];
      for (filePath in this.bundleWatchers) {
        results.push(this.removeBundle(filePath));
      }
      return results;
    };

    Watchers.prototype.watch = function(filePath, options) {
      var w;
      if (options == null) {
        options = {};
      }
      _.defaults(options, {
        interval: 250,
        usePolling: true,
        useFsEvents: false,
        ignored: null,
        onChange: null,
        onReady: null,
        onError: null
      });
      w = chokidar.watch(filePath, options);
      this._add(filePath, w);
      if (_.isFunction(options.onChange)) {
        w.on("change", options.onChange);
      }
      if (_.isFunction(options.onReady)) {
        w.on("ready", options.onReady);
      }
      if (_.isFunction(options.onError)) {
        w.on("error", options.onError);
      }
      return this;
    };

    Watchers.prototype._add = function(filePath, watcher) {
      this._remove(filePath);
      return this.watchers[filePath] = watcher;
    };

    Watchers.prototype._remove = function(filePath) {
      var watcher;
      if (!(watcher = this.watchers[filePath])) {
        return;
      }
      watcher.close();
      return delete this.watchers[filePath];
    };

    Watchers.prototype.watchBundle = function(filePath, config, options) {
      var watcher;
      if (options == null) {
        options = {};
      }
      _.defaults(options, {
        onChange: null,
        onReady: null
      });
      if (!(watcher = this.bundleWatchers[filePath])) {
        watcher = bundle.build(filePath, config);
        this._addBundle(filePath, watcher);
      }
      if (_.isFunction(options.onChange)) {
        watcher.addChangeListener(options.onChange);
      }
      return watcher.getLatestBundle();
    };

    Watchers.prototype._addBundle = function(filePath, watcher) {
      return this.bundleWatchers[filePath] = watcher;
    };

    Watchers.prototype.removeBundle = function(filePath) {
      var watcher;
      if (!(watcher = this.bundleWatchers[filePath])) {
        return;
      }
      watcher.close();
      return delete this.bundleWatchers[filePath];
    };

    return Watchers;

  })();

  module.exports = Watchers;

}).call(this);
