(function() {
  var $, $$$, CompositeDisposable, Disposable, HistoryCycler, ProjectFindView, Q, ResultsModel, ResultsPaneView, TextEditorView, Util, View, fs, _, _ref, _ref1,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  fs = require('fs-plus');

  Q = require('q');

  _ = require('underscore-plus');

  _ref = require('atom'), Disposable = _ref.Disposable, CompositeDisposable = _ref.CompositeDisposable;

  _ref1 = require('atom-space-pen-views'), $ = _ref1.$, $$$ = _ref1.$$$, View = _ref1.View, TextEditorView = _ref1.TextEditorView;

  HistoryCycler = require('./history').HistoryCycler;

  Util = require('./project/util');

  ResultsModel = require('./project/results-model');

  ResultsPaneView = require('./project/results-pane');

  module.exports = ProjectFindView = (function(_super) {
    __extends(ProjectFindView, _super);

    function ProjectFindView() {
      this.setSelectionAsFindPattern = __bind(this.setSelectionAsFindPattern, this);
      this.generateResultsMessage = __bind(this.generateResultsMessage, this);
      return ProjectFindView.__super__.constructor.apply(this, arguments);
    }

    ProjectFindView.content = function() {
      return this.div({
        tabIndex: -1,
        "class": 'project-find padded'
      }, (function(_this) {
        return function() {
          _this.header({
            "class": 'header'
          }, function() {
            _this.span({
              outlet: 'descriptionLabel',
              "class": 'header-item description'
            });
            return _this.span({
              "class": 'header-item options-label pull-right'
            }, function() {
              _this.span('Finding with Options: ');
              return _this.span({
                outlet: 'optionsLabel',
                "class": 'options'
              });
            });
          });
          _this.section({
            outlet: 'replacmentInfoBlock',
            "class": 'input-block'
          }, function() {
            _this.progress({
              outlet: 'replacementProgress',
              "class": 'inline-block'
            });
            return _this.span({
              outlet: 'replacmentInfo',
              "class": 'inline-block'
            }, 'Replaced 2 files of 10 files');
          });
          _this.section({
            "class": 'input-block find-container'
          }, function() {
            _this.div({
              "class": 'input-block-item input-block-item--flex editor-container'
            }, function() {
              return _this.subview('findEditor', new TextEditorView({
                mini: true,
                placeholderText: 'Find in project'
              }));
            });
            return _this.div({
              "class": 'input-block-item'
            }, function() {
              return _this.div({
                "class": 'btn-group btn-toggle btn-group-options'
              }, function() {
                _this.button({
                  outlet: 'regexOptionButton',
                  "class": 'btn option-regex'
                }, '.*');
                return _this.button({
                  outlet: 'caseOptionButton',
                  "class": 'btn option-case-sensitive'
                }, 'Aa');
              });
            });
          });
          _this.section({
            "class": 'input-block replace-container'
          }, function() {
            _this.div({
              "class": 'input-block-item input-block-item--flex editor-container'
            }, function() {
              return _this.subview('replaceEditor', new TextEditorView({
                mini: true,
                placeholderText: 'Replace in project'
              }));
            });
            return _this.div({
              "class": 'input-block-item'
            }, function() {
              return _this.div({
                "class": 'btn-group btn-group-replace-all'
              }, function() {
                return _this.button({
                  outlet: 'replaceAllButton',
                  "class": 'btn'
                }, 'Replace All');
              });
            });
          });
          return _this.section({
            "class": 'input-block paths-container'
          }, function() {
            return _this.div({
              "class": 'input-block-item editor-container'
            }, function() {
              return _this.subview('pathsEditor', new TextEditorView({
                mini: true,
                placeholderText: 'File/directory pattern. eg. `src` to search in the "src" directory or `*.js` to search all javascript files.'
              }));
            });
          });
        };
      })(this));
    };

    ProjectFindView.prototype.initialize = function(findInBufferModel, model, _arg) {
      var findHistory, pathsHistory, replaceHistory;
      this.findInBufferModel = findInBufferModel;
      this.model = model;
      findHistory = _arg.findHistory, replaceHistory = _arg.replaceHistory, pathsHistory = _arg.pathsHistory;
      this.subscriptions = new CompositeDisposable;
      this.handleEvents();
      this.findHistory = new HistoryCycler(this.findEditor, findHistory);
      this.replaceHistory = new HistoryCycler(this.replaceEditor, replaceHistory);
      this.pathsHistory = new HistoryCycler(this.pathsEditor, pathsHistory);
      this.onlyRunIfChanged = true;
      if (this.model.useRegex) {
        this.regexOptionButton.addClass('selected');
      }
      if (this.model.caseSensitive) {
        this.caseOptionButton.addClass('selected');
      }
      this.clearMessages();
      return this.updateOptionsLabel();
    };

    ProjectFindView.prototype.destroy = function() {
      var _ref2, _ref3;
      if ((_ref2 = this.subscriptions) != null) {
        _ref2.dispose();
      }
      return (_ref3 = this.tooltipSubscriptions) != null ? _ref3.dispose() : void 0;
    };

    ProjectFindView.prototype.setPanel = function(panel) {
      this.panel = panel;
      return this.subscriptions.add(this.panel.onDidChangeVisible((function(_this) {
        return function(visible) {
          if (visible) {
            return _this.didShow();
          } else {
            return _this.didHide();
          }
        };
      })(this)));
    };

    ProjectFindView.prototype.didShow = function() {
      var subs;
      atom.views.getView(atom.workspace).classList.add('find-visible');
      if (this.tooltipSubscriptions != null) {
        return;
      }
      this.tooltipSubscriptions = subs = new CompositeDisposable;
      subs.add(atom.tooltips.add(this.regexOptionButton, {
        title: "Use Regex",
        keyBindingCommand: 'project-find:toggle-regex-option',
        keyBindingTarget: this.findEditor.element
      }));
      subs.add(atom.tooltips.add(this.caseOptionButton, {
        title: "Match Case",
        keyBindingCommand: 'project-find:toggle-case-option',
        keyBindingTarget: this.findEditor.element
      }));
      return subs.add(atom.tooltips.add(this.replaceAllButton, {
        title: "Replace All",
        keyBindingCommand: 'project-find:replace-all',
        keyBindingTarget: this.replaceEditor.element
      }));
    };

    ProjectFindView.prototype.didHide = function() {
      var workspaceElement;
      this.hideAllTooltips();
      workspaceElement = atom.views.getView(atom.workspace);
      workspaceElement.focus();
      return workspaceElement.classList.remove('find-visible');
    };

    ProjectFindView.prototype.hideAllTooltips = function() {
      this.tooltipSubscriptions.dispose();
      return this.tooltipSubscriptions = null;
    };

    ProjectFindView.prototype.handleEvents = function() {
      var focusCallback;
      this.subscriptions.add(atom.commands.add('atom-workspace', {
        'find-and-replace:use-selection-as-find-pattern': this.setSelectionAsFindPattern
      }));
      this.subscriptions.add(atom.commands.add(this.element, {
        'find-and-replace:focus-next': (function(_this) {
          return function() {
            return _this.focusNextElement(1);
          };
        })(this),
        'find-and-replace:focus-previous': (function(_this) {
          return function() {
            return _this.focusNextElement(-1);
          };
        })(this),
        'core:confirm': (function(_this) {
          return function() {
            return _this.confirm();
          };
        })(this),
        'core:close': (function(_this) {
          return function() {
            var _ref2;
            return (_ref2 = _this.panel) != null ? _ref2.hide() : void 0;
          };
        })(this),
        'core:cancel': (function(_this) {
          return function() {
            var _ref2;
            return (_ref2 = _this.panel) != null ? _ref2.hide() : void 0;
          };
        })(this),
        'project-find:confirm': (function(_this) {
          return function() {
            return _this.confirm();
          };
        })(this),
        'project-find:toggle-regex-option': (function(_this) {
          return function() {
            return _this.toggleRegexOption();
          };
        })(this),
        'project-find:toggle-case-option': (function(_this) {
          return function() {
            return _this.toggleCaseOption();
          };
        })(this),
        'project-find:replace-all': (function(_this) {
          return function() {
            return _this.replaceAll();
          };
        })(this)
      }));
      this.subscriptions.add(this.model.onDidClear((function(_this) {
        return function() {
          return _this.clearMessages();
        };
      })(this)));
      this.subscriptions.add(this.model.onDidClearReplacementState((function(_this) {
        return function(results) {
          return _this.generateResultsMessage(results);
        };
      })(this)));
      this.subscriptions.add(this.model.onDidFinishSearching((function(_this) {
        return function(results) {
          return _this.generateResultsMessage(results);
        };
      })(this)));
      this.on('focus', (function(_this) {
        return function(e) {
          return _this.findEditor.focus();
        };
      })(this));
      this.regexOptionButton.click((function(_this) {
        return function() {
          return _this.toggleRegexOption();
        };
      })(this));
      this.caseOptionButton.click((function(_this) {
        return function() {
          return _this.toggleCaseOption();
        };
      })(this));
      this.replaceAllButton.on('click', (function(_this) {
        return function() {
          return _this.replaceAll();
        };
      })(this));
      focusCallback = (function(_this) {
        return function() {
          return _this.onlyRunIfChanged = false;
        };
      })(this);
      $(window).on('focus', focusCallback);
      this.subscriptions.add(new Disposable(function() {
        return $(window).off('focus', focusCallback);
      }));
      return this.handleEventsForReplace();
    };

    ProjectFindView.prototype.handleEventsForReplace = function() {
      this.replaceEditor.getModel().getBuffer().onDidChange((function(_this) {
        return function() {
          return _this.model.clearReplacementState();
        };
      })(this));
      this.replaceEditor.getModel().onDidStopChanging((function(_this) {
        return function() {
          return _this.model.updateReplacementPattern(_this.replaceEditor.getText());
        };
      })(this));
      this.replacementsMade = 0;
      this.subscriptions.add(this.model.onDidStartReplacing((function(_this) {
        return function(promise) {
          _this.replacementsMade = 0;
          _this.replacmentInfoBlock.show();
          return _this.replacementProgress.removeAttr('value');
        };
      })(this)));
      this.subscriptions.add(this.model.onDidReplacePath((function(_this) {
        return function(result) {
          _this.replacementsMade++;
          _this.replacementProgress[0].value = _this.replacementsMade / _this.model.getPathCount();
          return _this.replacmentInfo.text("Replaced " + _this.replacementsMade + " of " + (_.pluralize(_this.model.getPathCount(), 'file')));
        };
      })(this)));
      return this.subscriptions.add(this.model.onDidFinishReplacing((function(_this) {
        return function(result) {
          return _this.onFinishedReplacing(result);
        };
      })(this)));
    };

    ProjectFindView.prototype.toggleRegexOption = function() {
      this.model.toggleUseRegex();
      if (this.model.useRegex) {
        this.regexOptionButton.addClass('selected');
      } else {
        this.regexOptionButton.removeClass('selected');
      }
      this.updateOptionsLabel();
      return this.search({
        onlyRunIfActive: true
      });
    };

    ProjectFindView.prototype.toggleCaseOption = function() {
      this.model.toggleCaseSensitive();
      if (this.model.caseSensitive) {
        this.caseOptionButton.addClass('selected');
      } else {
        this.caseOptionButton.removeClass('selected');
      }
      this.updateOptionsLabel();
      return this.search({
        onlyRunIfActive: true
      });
    };

    ProjectFindView.prototype.focusNextElement = function(direction) {
      var elements, focusedElement, focusedIndex, _base;
      elements = [this.findEditor, this.replaceEditor, this.pathsEditor];
      focusedElement = _.find(elements, function(el) {
        return el.hasClass('is-focused');
      });
      focusedIndex = elements.indexOf(focusedElement);
      focusedIndex = focusedIndex + direction;
      if (focusedIndex >= elements.length) {
        focusedIndex = 0;
      }
      if (focusedIndex < 0) {
        focusedIndex = elements.length - 1;
      }
      elements[focusedIndex].focus();
      return typeof (_base = elements[focusedIndex]).getModel === "function" ? _base.getModel().selectAll() : void 0;
    };

    ProjectFindView.prototype.focusFindElement = function() {
      var selectedText, _ref2;
      selectedText = (_ref2 = atom.workspace.getActiveTextEditor()) != null ? typeof _ref2.getSelectedText === "function" ? _ref2.getSelectedText() : void 0 : void 0;
      if (selectedText && selectedText.indexOf('\n') < 0) {
        this.findEditor.setText(selectedText);
      }
      this.findEditor.focus();
      return this.findEditor.getModel().selectAll();
    };

    ProjectFindView.prototype.confirm = function() {
      var searchPromise;
      if (this.findEditor.getText().length === 0) {
        this.model.clear();
        return;
      }
      this.findHistory.store();
      this.replaceHistory.store();
      this.pathsHistory.store();
      searchPromise = this.search({
        onlyRunIfChanged: this.onlyRunIfChanged
      });
      this.onlyRunIfChanged = true;
      return searchPromise;
    };

    ProjectFindView.prototype.search = function(_arg) {
      var onlyRunIfActive, onlyRunIfChanged, pattern, _ref2;
      _ref2 = _arg != null ? _arg : {}, onlyRunIfActive = _ref2.onlyRunIfActive, onlyRunIfChanged = _ref2.onlyRunIfChanged;
      if (onlyRunIfActive && !this.model.active) {
        return Q();
      }
      pattern = this.findEditor.getText();
      this.findInBufferModel.update({
        pattern: pattern
      });
      this.clearMessages();
      return this.showResultPane().then((function(_this) {
        return function() {
          var e;
          try {
            return _this.model.search(pattern, _this.getPaths(), _this.replaceEditor.getText(), {
              onlyRunIfChanged: onlyRunIfChanged
            });
          } catch (_error) {
            e = _error;
            return _this.setErrorMessage(e.message);
          }
        };
      })(this));
    };

    ProjectFindView.prototype.replaceAll = function() {
      this.clearMessages();
      return this.showResultPane().then((function(_this) {
        return function() {
          var pattern, replacementPattern;
          pattern = _this.findEditor.getText();
          replacementPattern = _this.replaceEditor.getText();
          return _this.model.search(pattern, _this.getPaths(), replacementPattern, {
            onlyRunIfChanged: true
          }).then(function() {
            _this.clearMessages();
            return _this.model.replace(pattern, _this.getPaths(), replacementPattern, _this.model.getPaths());
          });
        };
      })(this));
    };

    ProjectFindView.prototype.getPaths = function() {
      var path, _i, _len, _ref2, _results;
      _ref2 = this.pathsEditor.getText().trim().split(',');
      _results = [];
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        path = _ref2[_i];
        if (path) {
          _results.push(path.trim());
        }
      }
      return _results;
    };

    ProjectFindView.prototype.directoryPathForElement = function(element) {
      var elementPath, _ref2, _ref3;
      elementPath = (_ref2 = element != null ? element.dataset.path : void 0) != null ? _ref2 : element != null ? (_ref3 = element.querySelector('[data-path]')) != null ? _ref3.dataset.path : void 0 : void 0;
      if (!elementPath) {
        while (element != null) {
          elementPath = element.dataset.path;
          if (elementPath) {
            break;
          }
          element = element.parentElement;
        }
      }
      if (fs.isFileSync(elementPath)) {
        return require('path').dirname(elementPath);
      } else {
        return elementPath;
      }
    };

    ProjectFindView.prototype.findInCurrentlySelectedDirectory = function(selectedElement) {
      var absPath, relPath, rootPath, _ref2;
      if (absPath = this.directoryPathForElement(selectedElement)) {
        _ref2 = atom.project.relativizePath(absPath), rootPath = _ref2[0], relPath = _ref2[1];
        if ((rootPath != null) && atom.project.getDirectories().length > 1) {
          relPath = path.join(path.basename(rootPath), relPath);
        }
        this.pathsEditor.setText(relPath);
        this.findEditor.focus();
        return this.findEditor.getModel().selectAll();
      }
    };

    ProjectFindView.prototype.showResultPane = function() {
      var options;
      options = null;
      if (atom.config.get('find-and-replace.openProjectFindResultsInRightPane')) {
        options = {
          split: 'right'
        };
      }
      return atom.workspace.open(ResultsPaneView.URI, options);
    };

    ProjectFindView.prototype.onFinishedReplacing = function(results) {
      if (!results.replacedPathCount) {
        atom.beep();
      }
      return this.replacmentInfoBlock.hide();
    };

    ProjectFindView.prototype.generateResultsMessage = function(results) {
      var message;
      message = Util.getSearchResultsMessage(results);
      if (results.replacedPathCount != null) {
        message = Util.getReplacementResultsMessage(results);
      }
      return this.setInfoMessage(message);
    };

    ProjectFindView.prototype.clearMessages = function() {
      this.setInfoMessage('Find in Project <span class="subtle-info-message">Close this panel with the <span class="highlight">esc</span> key</span>').removeClass('text-error');
      return this.replacmentInfoBlock.hide();
    };

    ProjectFindView.prototype.setInfoMessage = function(infoMessage) {
      return this.descriptionLabel.html(infoMessage).removeClass('text-error');
    };

    ProjectFindView.prototype.setErrorMessage = function(errorMessage) {
      return this.descriptionLabel.html(errorMessage).addClass('text-error');
    };

    ProjectFindView.prototype.updateOptionsLabel = function() {
      var label;
      label = [];
      if (this.model.useRegex) {
        label.push('Regex');
      }
      if (this.model.caseSensitive) {
        label.push('Case Sensitive');
      } else {
        label.push('Case Insensitive');
      }
      return this.optionsLabel.text(label.join(', '));
    };

    ProjectFindView.prototype.setSelectionAsFindPattern = function() {
      var editor, pattern;
      editor = atom.workspace.getActivePaneItem();
      if ((editor != null ? editor.getSelectedText : void 0) != null) {
        pattern = editor.getSelectedText();
        return this.findEditor.setText(pattern);
      }
    };

    return ProjectFindView;

  })(View);

}).call(this);
