'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Message = exports.Aliases = undefined;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _class;

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _markdownIt = require('markdown-it');

var _markdownIt2 = _interopRequireDefault(_markdownIt);

var _mobxReact = require('mobx-react');

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _events = require('../lib/events');

var _events2 = _interopRequireDefault(_events);

var _tooltip = require('../tooltip/tooltip');

var _tooltip2 = _interopRequireDefault(_tooltip);

var _flashOnClick = require('../lib/flash-on-click');

var _flashOnClick2 = _interopRequireDefault(_flashOnClick);

var _runnablesStore = require('../runnables/runnables-store');

var _runnablesStore2 = _interopRequireDefault(_runnablesStore);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var md = new _markdownIt2.default();

var displayName = function displayName(model) {
  return model.displayName || model.name;
};
var nameClassName = function nameClassName(name) {
  return name.replace(/(\s+)/g, '-');
};
var truncatedMessage = function truncatedMessage(message) {
  return _lodash2.default.truncate(message, { length: 100 });
};
var formattedMessage = function formattedMessage(message) {
  return message ? md.renderInline(message) : '';
};
var visibleMessage = function visibleMessage(model) {
  if (model.visible) return '';

  return model.numElements > 1 ? 'One or more matched elements are not visible.' : 'This element is not visible.';
};

var Aliases = (0, _mobxReact.observer)(function (_ref) {
  var model = _ref.model;
  return _react2.default.createElement(
    'span',
    null,
    _lodash2.default.map([].concat(model.referencesAlias), function (alias) {
      return _react2.default.createElement(
        _tooltip2.default,
        { key: alias, placement: 'top', title: 'Found an alias for: \'' + alias + '\'' },
        _react2.default.createElement(
          'span',
          { className: 'command-alias ' + model.aliasType },
          '@',
          alias
        )
      );
    })
  );
});

var Message = (0, _mobxReact.observer)(function (_ref2) {
  var model = _ref2.model;
  return _react2.default.createElement(
    'span',
    null,
    _react2.default.createElement('i', { className: 'fa fa-circle ' + model.renderProps.indicator }),
    _react2.default.createElement('span', { className: 'command-message-text', dangerouslySetInnerHTML: { __html: formattedMessage(model.renderProps.message || truncatedMessage(model.message)) } })
  );
});

var Command = (0, _mobxReact.observer)(_class = function (_Component) {
  _inherits(Command, _Component);

  function Command() {
    _classCallCheck(this, Command);

    return _possibleConstructorReturn(this, (Command.__proto__ || Object.getPrototypeOf(Command)).apply(this, arguments));
  }

  _createClass(Command, [{
    key: 'render',
    value: function render() {
      var _this2 = this;

      var model = this.props.model;


      return _react2.default.createElement(
        'li',
        {
          className: (0, _classnames2.default)('command-name-' + nameClassName(model.name), 'command-state-' + model.state, 'command-type-' + model.type, {
            'command-is-event': !!model.event,
            'command-is-invisible': model.visible != null && !model.visible,
            'command-has-num-elements': model.state !== 'pending' && model.numElements != null,
            'command-has-no-elements': !model.numElements,
            'command-has-multiple-elements': model.numElements > 1,
            'command-with-indicator': !!model.renderProps.indicator,
            'command-scaled': model.renderProps.message && model.renderProps.message.length > 100
          })
        },
        _react2.default.createElement(
          _flashOnClick2.default,
          {
            message: 'Printed output to your console!',
            onClick: function onClick() {
              return _this2.props.events.emit('show:command', model.id);
            }
          },
          _react2.default.createElement(
            'div',
            {
              className: 'command-wrapper',
              onMouseOver: function onMouseOver() {
                return _this2._snapshot(true);
              },
              onMouseOut: function onMouseOut() {
                return _this2._snapshot(false);
              }
            },
            _react2.default.createElement(
              'span',
              { className: 'command-number' },
              _react2.default.createElement('i', { className: 'fa fa-spinner fa-spin' }),
              _react2.default.createElement(
                'span',
                null,
                model.number || ''
              )
            ),
            _react2.default.createElement(
              'span',
              { className: 'command-method' },
              _react2.default.createElement(
                'span',
                null,
                model.event ? '(' + displayName(model) + ')' : displayName(model)
              )
            ),
            _react2.default.createElement(
              'span',
              { className: 'command-message' },
              model.referencesAlias ? _react2.default.createElement(Aliases, { model: model }) : _react2.default.createElement(Message, { model: model })
            ),
            _react2.default.createElement(
              'span',
              { className: 'command-controls' },
              _react2.default.createElement(
                _tooltip2.default,
                { placement: 'top', title: model.message + ' aliased as: \'' + model.alias + '\'' },
                _react2.default.createElement(
                  'span',
                  { className: 'command-alias ' + model.aliasType },
                  model.alias
                )
              ),
              _react2.default.createElement(
                _tooltip2.default,
                { placement: 'top', title: visibleMessage(model) },
                _react2.default.createElement('i', { className: 'command-invisible fa fa-eye-slash' })
              ),
              _react2.default.createElement(
                _tooltip2.default,
                { placement: 'top', title: model.numElements + ' matched elements' },
                _react2.default.createElement(
                  'span',
                  { className: 'command-num-elements' },
                  model.numElements
                )
              )
            )
          )
        )
      );
    }

    // snapshot rules
    //
    // 1. when we hover over a command, wait 50 ms
    // if we're still hovering, send show:snapshot
    //
    // 2. when we hover off a command, wait 50 ms
    // and if we are still in a non-showing state
    // meaning we have moused over nothing instead
    // of a different command, send hide:snapshot
    //
    // this prevents heavy CPU usage when hovering
    // up and down over commands. it also prevents
    // restoring to the original through all of that.
    // additionally when quickly moving your mouse
    // over many commands, unless you're hovered for
    // 50ms, it won't show the snapshot at all. so we
    // optimize for both snapshot showing + restoring

  }, {
    key: '_snapshot',
    value: function _snapshot(show) {
      var _this3 = this;

      var runnablesStore = this.props.runnablesStore;


      if (show) {
        runnablesStore.attemptingShowSnapshot = true;

        this._showTimeout = setTimeout(function () {
          runnablesStore.showingSnapshot = true;
          _this3.props.events.emit('show:snapshot', _this3.props.model.id);
        }, 50);
      } else {
        runnablesStore.attemptingShowSnapshot = false;
        clearTimeout(this._showTimeout);

        setTimeout(function () {
          // if we are currently showing a snapshot but
          // we aren't trying to show a different snapshot
          if (runnablesStore.showingSnapshot && !runnablesStore.attemptingShowSnapshot) {
            runnablesStore.showingSnapshot = false;
            _this3.props.events.emit('hide:snapshot', _this3.props.model.id);
          }
        }, 50);
      }
    }
  }]);

  return Command;
}(_react.Component)) || _class;

Command.defaultProps = {
  events: _events2.default,
  runnablesStore: _runnablesStore2.default
};

exports.Aliases = Aliases;
exports.Message = Message;
exports.default = Command;