(function() {
  var CommandLogger, ignoredCommands, moment, tenMinutes;

  moment = null;

  ignoredCommands = {
    'show.bs.tooltip': true,
    'shown.bs.tooltip': true,
    'hide.bs.tooltip': true,
    'hidden.bs.tooltip': true,
    'editor:display-updated': true,
    'mousewheel': true
  };

  tenMinutes = 10 * 60 * 1000;

  module.exports = CommandLogger = (function() {
    CommandLogger.instance = function() {
      return this._instance != null ? this._instance : this._instance = new CommandLogger;
    };

    CommandLogger.start = function() {
      return this.instance().start();
    };

    CommandLogger.prototype.dateFmt = '-m:ss.S';

    CommandLogger.prototype.logSize = 16;

    function CommandLogger() {
      this.initLog();
    }

    CommandLogger.prototype.start = function() {
      return atom.commands.onWillDispatch((function(_this) {
        return function(event) {
          return _this.logCommand(event);
        };
      })(this));
    };

    CommandLogger.prototype.getText = function(externalData) {
      var lastTime, lines;
      lines = [];
      lastTime = Date.now();
      this.eachEvent((function(_this) {
        return function(event) {
          if (event.time > lastTime) {
            return;
          }
          if (!event.name || lastTime - event.time >= tenMinutes) {
            return;
          }
          return lines.push(_this.formatEvent(event, lastTime));
        };
      })(this));
      if (externalData) {
        lines.push("     " + (this.formatTime(0)) + " " + externalData.title);
      }
      lines.unshift('```');
      lines.push('```');
      return lines.join("\n");
    };

    CommandLogger.prototype.latestEvent = function() {
      return this.eventLog[this.logIndex];
    };

    CommandLogger.prototype.logCommand = function(command) {
      var event, name, source, time, _ref;
      name = command.type, source = command.target, time = command.time;
      if ((_ref = command.detail) != null ? _ref.jQueryTrigger : void 0) {
        return;
      }
      if (name in ignoredCommands) {
        return;
      }
      event = this.latestEvent();
      if (event.name === name) {
        return event.count++;
      } else {
        this.logIndex = (this.logIndex + 1) % this.logSize;
        event = this.latestEvent();
        event.name = name;
        event.source = source;
        event.count = 1;
        return event.time = time != null ? time : Date.now();
      }
    };

    CommandLogger.prototype.calculateLastEventTime = function(data) {
      var lastTime;
      if (data) {
        return data.time;
      }
      lastTime = null;
      this.eachEvent(function(event) {
        return lastTime = event.time;
      });
      return lastTime;
    };

    CommandLogger.prototype.eachEvent = function(fn) {
      var offset, _i, _ref;
      for (offset = _i = 1, _ref = this.logSize; 1 <= _ref ? _i <= _ref : _i >= _ref; offset = 1 <= _ref ? ++_i : --_i) {
        fn(this.eventLog[(this.logIndex + offset) % this.logSize]);
      }
    };

    CommandLogger.prototype.formatCount = function(count) {
      switch (false) {
        case !(count < 2):
          return '    ';
        case !(count < 10):
          return "  " + count + "x";
        case !(count < 100):
          return " " + count + "x";
      }
    };

    CommandLogger.prototype.formatEvent = function(event, lastTime) {
      var count, name, source, time;
      count = event.count, time = event.time, name = event.name, source = event.source;
      return "" + (this.formatCount(count)) + " " + (this.formatTime(lastTime - time)) + " " + name + " " + (this.formatSource(source));
    };

    CommandLogger.prototype.formatSource = function(source) {
      var classList, classText, id, idText, klass, nodeName, nodeText, _i, _len;
      nodeName = source.nodeName, id = source.id, classList = source.classList;
      nodeText = nodeName.toLowerCase();
      idText = id ? "#" + id : '';
      classText = '';
      if (classList) {
        for (_i = 0, _len = classList.length; _i < _len; _i++) {
          klass = classList[_i];
          classText += "." + klass;
        }
      }
      return "(" + nodeText + idText + classText + ")";
    };

    CommandLogger.prototype.formatTime = function(time) {
      if (moment == null) {
        moment = require('moment');
      }
      return moment(time).format(this.dateFmt);
    };

    CommandLogger.prototype.initLog = function() {
      var i;
      this.logIndex = 0;
      return this.eventLog = (function() {
        var _i, _ref, _results;
        _results = [];
        for (i = _i = 0, _ref = this.logSize; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
          _results.push({
            name: null,
            count: 0,
            source: null,
            time: null
          });
        }
        return _results;
      }).call(this);
    };

    return CommandLogger;

  })();

}).call(this);
