(function() {
  var ResultsPaneView, buildMouseEvent, path, temp, waitsForPromise, _,
    __slice = [].slice;

  path = require('path');

  _ = require('underscore-plus');

  temp = require("temp");

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

  waitsForPromise = function(fn) {
    return window.waitsForPromise({
      timeout: 30000
    }, fn);
  };

  describe('ResultsView', function() {
    var getExistingResultsPane, getResultsView, pack, projectFindView, resultsView, searchPromise, workspaceElement, _ref;
    _ref = [], pack = _ref[0], projectFindView = _ref[1], resultsView = _ref[2], searchPromise = _ref[3], workspaceElement = _ref[4];
    getExistingResultsPane = function() {
      var pane;
      pane = atom.workspace.paneForURI(ResultsPaneView.URI);
      if (pane != null) {
        return pane.itemForURI(ResultsPaneView.URI);
      }
      return null;
    };
    getResultsView = function() {
      return resultsView = getExistingResultsPane().resultsView;
    };
    beforeEach(function() {
      var promise;
      workspaceElement = atom.views.getView(atom.workspace);
      workspaceElement.style.height = '1000px';
      jasmine.attachToDOM(workspaceElement);
      atom.project.setPaths([path.join(__dirname, 'fixtures')]);
      promise = atom.packages.activatePackage("find-and-replace").then(function(_arg) {
        var mainModule, spy;
        mainModule = _arg.mainModule;
        mainModule.createViews();
        projectFindView = mainModule.projectFindView;
        return spy = spyOn(projectFindView, 'confirm').andCallFake(function() {
          return searchPromise = spy.originalValue.call(projectFindView);
        });
      });
      atom.commands.dispatch(workspaceElement, 'project-find:show');
      return waitsForPromise(function() {
        return promise;
      });
    });
    describe("when the result is for a long line", function() {
      return it("renders the context around the match", function() {
        projectFindView.findEditor.setText('ghijkl');
        atom.commands.dispatch(projectFindView.element, 'core:confirm');
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          resultsView = getResultsView();
          expect(resultsView.find('.path-name').text()).toBe("one-long-line.coffee");
          expect(resultsView.find('.preview').length).toBe(1);
          expect(resultsView.find('.preview').text()).toBe('test test test test test test test test test test test a b c d e f g h i j k l abcdefghijklmnopqrstuvwxyz');
          return expect(resultsView.find('.match').text()).toBe('ghijkl');
        });
      });
    });
    describe("when there are multiple project paths", function() {
      beforeEach(function() {
        return atom.project.addPath(temp.mkdirSync("another-project-path"));
      });
      return it("includes the basename of the project path that contains the match", function() {
        projectFindView.findEditor.setText('ghijkl');
        atom.commands.dispatch(projectFindView.element, 'core:confirm');
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          resultsView = getResultsView();
          return expect(resultsView.find('.path-name').text()).toBe(path.join("fixtures", "one-long-line.coffee"));
        });
      });
    });
    describe("rendering replacement text", function() {
      var modifiedDelay;
      modifiedDelay = null;
      beforeEach(function() {
        projectFindView.findEditor.setText('ghijkl');
        return modifiedDelay = projectFindView.replaceEditor.getModel().getBuffer().stoppedChangingDelay;
      });
      it("renders the replacement when doing a search and there is a replacement pattern", function() {
        projectFindView.replaceEditor.setText('cats');
        atom.commands.dispatch(projectFindView.element, 'core:confirm');
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          resultsView = getResultsView();
          expect(resultsView.find('.path-name').text()).toBe("one-long-line.coffee");
          expect(resultsView.find('.preview').length).toBe(1);
          expect(resultsView.find('.match').text()).toBe('ghijkl');
          return expect(resultsView.find('.replacement').text()).toBe('cats');
        });
      });
      return it("renders the replacement when changing the text in the replacement field", function() {
        atom.commands.dispatch(projectFindView.element, 'core:confirm');
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          resultsView = getResultsView();
          expect(resultsView.find('.match').text()).toBe('ghijkl');
          expect(resultsView.find('.match')).toHaveClass('highlight-info');
          expect(resultsView.find('.replacement').text()).toBe('');
          expect(resultsView.find('.replacement')).toBeHidden();
          projectFindView.replaceEditor.setText('cats');
          advanceClock(modifiedDelay);
          expect(resultsView.find('.match').text()).toBe('ghijkl');
          expect(resultsView.find('.match')).toHaveClass('highlight-error');
          expect(resultsView.find('.replacement').text()).toBe('cats');
          expect(resultsView.find('.replacement')).toBeVisible();
          projectFindView.replaceEditor.setText('');
          advanceClock(modifiedDelay);
          expect(resultsView.find('.match').text()).toBe('ghijkl');
          expect(resultsView.find('.match')).toHaveClass('highlight-info');
          return expect(resultsView.find('.replacement')).toBeHidden();
        });
      });
    });
    describe("when list is scrollable", function() {
      it("adds more results to the DOM when scrolling", function() {
        projectFindView.findEditor.setText(' ');
        atom.commands.dispatch(projectFindView.element, 'core:confirm');
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          var previousOperationCount, previousScrollHeight;
          resultsView = getResultsView();
          expect(resultsView.prop('scrollHeight')).toBeGreaterThan(resultsView.height());
          previousScrollHeight = resultsView.prop('scrollHeight');
          previousOperationCount = resultsView.find("li").length;
          resultsView.scrollTop(resultsView.pixelOverdraw * 2);
          resultsView.trigger('scroll');
          expect(resultsView.prop('scrollHeight')).toBeGreaterThan(previousScrollHeight);
          return expect(resultsView.find("li").length).toBeGreaterThan(previousOperationCount);
        });
      });
      it("adds more results to the DOM when scrolled to bottom", function() {
        projectFindView.findEditor.setText(' ');
        atom.commands.dispatch(projectFindView.element, 'core:confirm');
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          var previousOperationCount, previousScrollHeight;
          resultsView = getResultsView();
          expect(resultsView.prop('scrollHeight')).toBeGreaterThan(resultsView.height());
          previousScrollHeight = resultsView.prop('scrollHeight');
          previousOperationCount = resultsView.find("li").length;
          resultsView.scrollToBottom();
          resultsView.trigger('scroll');
          expect(resultsView.prop('scrollHeight')).toBeGreaterThan(previousScrollHeight);
          return expect(resultsView.find("li").length).toBeGreaterThan(previousOperationCount);
        });
      });
      it("renders more results when a result is collapsed via core:move-left", function() {
        projectFindView.findEditor.setText(' ');
        projectFindView.confirm();
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          var pathNode;
          resultsView = getResultsView();
          expect(resultsView.find(".path").length).toBe(1);
          pathNode = resultsView.find(".path")[0];
          pathNode.dispatchEvent(buildMouseEvent('mousedown', {
            target: pathNode,
            which: 1
          }));
          expect(resultsView.find(".path").length).toBe(2);
          pathNode = resultsView.find(".path")[1];
          pathNode.dispatchEvent(buildMouseEvent('mousedown', {
            target: pathNode,
            which: 1
          }));
          return expect(resultsView.find(".path").length).toBe(3);
        });
      });
      it("renders more results when a result is collapsed via click", function() {
        projectFindView.findEditor.setText(' ');
        projectFindView.confirm();
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          resultsView = getResultsView();
          expect(resultsView.find(".path-details").length).toBe(1);
          atom.commands.dispatch(resultsView.element, 'core:move-down');
          atom.commands.dispatch(resultsView.element, 'core:move-left');
          expect(resultsView.find(".path-details").length).toBe(2);
          atom.commands.dispatch(resultsView.element, 'core:move-down');
          atom.commands.dispatch(resultsView.element, 'core:move-left');
          return expect(resultsView.find(".path-details").length).toBe(3);
        });
      });
      return it("renders all results when core:move-to-bottom is triggered", function() {
        workspaceElement.style.height = '300px';
        projectFindView.findEditor.setText('so');
        projectFindView.confirm();
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          var previousScrollHeight;
          resultsView = getResultsView();
          expect(resultsView.prop('scrollHeight')).toBeGreaterThan(resultsView.height());
          previousScrollHeight = resultsView.prop('scrollHeight');
          atom.commands.dispatch(resultsView.element, 'core:move-to-bottom');
          return expect(resultsView.find("li").length).toBe(resultsView.getPathCount() + resultsView.getMatchCount());
        });
      });
    });
    describe("arrowing through the list", function() {
      resultsView = null;
      it("opens the correct file containing the result when 'core:confirm' is called", function() {
        var openHandler;
        openHandler = null;
        waitsForPromise(function() {
          return atom.workspace.open('sample.js');
        });
        runs(function() {
          projectFindView.findEditor.setText('items');
          atom.commands.dispatch(projectFindView.element, 'core:confirm');
          openHandler = jasmine.createSpy("open handler");
          return atom.workspace.onDidOpen(openHandler);
        });
        waitsForPromise(function() {
          return searchPromise;
        });
        runs(function() {
          resultsView = getResultsView();
          resultsView.selectFirstResult();
          _.times(3, function() {
            return atom.commands.dispatch(resultsView.element, 'core:move-down');
          });
          openHandler.reset();
          return atom.commands.dispatch(resultsView.element, 'core:confirm');
        });
        waitsFor(function() {
          return openHandler.callCount === 1;
        });
        runs(function() {
          expect(atom.workspace.getActivePaneItem().getPath()).toContain('sample.');
          resultsView.focus();
          _.times(6, function() {
            return atom.commands.dispatch(resultsView.element, 'core:move-down');
          });
          openHandler.reset();
          return atom.commands.dispatch(resultsView.element, 'core:confirm');
        });
        waitsFor(function() {
          return openHandler.callCount === 1;
        });
        return runs(function() {
          return expect(atom.workspace.getActivePaneItem().getPath()).toContain('sample.');
        });
      });
      it("arrows through the entire list without selecting paths and overshooting the boundaries", function() {
        waitsForPromise(function() {
          return atom.workspace.open('sample.js');
        });
        runs(function() {
          projectFindView.findEditor.setText('items');
          return atom.commands.dispatch(projectFindView.element, 'core:confirm');
        });
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          var lastSelectedItem, length;
          resultsView = getResultsView();
          lastSelectedItem = null;
          length = resultsView.find("li > ul > li").length;
          expect(length).toBe(13);
          resultsView.selectFirstResult();
          _.times(length - 1, function() {
            var selectedItem;
            atom.commands.dispatch(resultsView.element, 'core:move-down');
            selectedItem = resultsView.find('.selected');
            expect(selectedItem).toHaveClass('search-result');
            expect(selectedItem[0]).not.toBe(lastSelectedItem);
            return lastSelectedItem = selectedItem[0];
          });
          _.times(2, function() {
            var selectedItem;
            atom.commands.dispatch(resultsView.element, 'core:move-down');
            selectedItem = resultsView.find('.selected');
            expect(selectedItem[0]).toBe(lastSelectedItem);
            return lastSelectedItem = selectedItem[0];
          });
          _.times(length - 1, function() {
            var selectedItem;
            atom.commands.dispatch(resultsView.element, 'core:move-up');
            selectedItem = resultsView.find('.selected');
            expect(selectedItem).toHaveClass('search-result');
            expect(selectedItem[0]).not.toBe(lastSelectedItem);
            return lastSelectedItem = selectedItem[0];
          });
          return _.times(2, function() {
            var selectedItem;
            atom.commands.dispatch(resultsView.element, 'core:move-up');
            selectedItem = resultsView.find('.selected');
            expect(selectedItem[0]).toBe(lastSelectedItem);
            return lastSelectedItem = selectedItem[0];
          });
        });
      });
      return describe("when there are a list of items", function() {
        beforeEach(function() {
          projectFindView.findEditor.setText('items');
          atom.commands.dispatch(projectFindView.element, 'core:confirm');
          waitsForPromise(function() {
            return searchPromise;
          });
          return runs(function() {
            return resultsView = getResultsView();
          });
        });
        it("collapses the selected results view", function() {
          var selectedItem;
          resultsView.find('.selected').removeClass('selected');
          resultsView.find('.path:eq(0) .search-result:first').addClass('selected');
          atom.commands.dispatch(resultsView.element, 'core:move-left');
          selectedItem = resultsView.find('.selected');
          expect(selectedItem).toHaveClass('collapsed');
          return expect(selectedItem.element).toBe(resultsView.find('.path:eq(0)').element);
        });
        it("expands the selected results view", function() {
          var selectedItem;
          resultsView.find('.selected').removeClass('selected');
          resultsView.find('.path:eq(0)').addClass('selected').addClass('collapsed');
          atom.commands.dispatch(resultsView.element, 'core:move-right');
          selectedItem = resultsView.find('.selected');
          expect(selectedItem).toHaveClass('search-result');
          return expect(selectedItem[0]).toBe(resultsView.find('.path:eq(0) .search-result:first')[0]);
        });
        describe("when nothing is selected", function() {
          it("doesnt error when the user arrows down", function() {
            resultsView.find('.selected').removeClass('selected');
            expect(resultsView.find('.selected')).not.toExist();
            atom.commands.dispatch(resultsView.element, 'core:move-down');
            return expect(resultsView.find('.selected')).toExist();
          });
          return it("doesnt error when the user arrows up", function() {
            resultsView.find('.selected').removeClass('selected');
            expect(resultsView.find('.selected')).not.toExist();
            atom.commands.dispatch(resultsView.element, 'core:move-up');
            return expect(resultsView.find('.selected')).toExist();
          });
        });
        return describe("when there are collapsed results", function() {
          it("moves to the correct next result when a path is selected", function() {
            var selectedItem;
            resultsView.find('.selected').removeClass('selected');
            resultsView.find('.path:eq(0) .search-result:last').addClass('selected');
            resultsView.find('.path:eq(1)').view().expand(false);
            atom.commands.dispatch(resultsView.element, 'core:move-down');
            selectedItem = resultsView.find('.selected');
            expect(selectedItem).toHaveClass('path');
            return expect(selectedItem[0]).toBe(resultsView.find('.path:eq(1)')[0]);
          });
          return it("moves to the correct previous result when a path is selected", function() {
            var selectedItem;
            resultsView.find('.selected').removeClass('selected');
            resultsView.find('.path:eq(1) .search-result:first').addClass('selected');
            resultsView.find('.path:eq(0)').view().expand(false);
            atom.commands.dispatch(resultsView.element, 'core:move-up');
            selectedItem = resultsView.find('.selected');
            expect(selectedItem).toHaveClass('path');
            return expect(selectedItem[0]).toBe(resultsView.find('.path:eq(0)')[0]);
          });
        });
      });
    });
    describe("when the results view is empty", function() {
      return it("ignores core:confirm events", function() {
        projectFindView.findEditor.setText('thiswillnotmatchanythingintheproject');
        atom.commands.dispatch(projectFindView.element, 'core:confirm');
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          resultsView = getResultsView();
          return expect(function() {
            return atom.commands.dispatch(resultsView.element, 'core:confirm');
          }).not.toThrow();
        });
      });
    });
    return describe("copying items with core:copy", function() {
      var openHandler, _ref1;
      _ref1 = [], resultsView = _ref1[0], openHandler = _ref1[1];
      beforeEach(function() {
        waitsForPromise(function() {
          return atom.workspace.open('sample.js');
        });
        runs(function() {
          projectFindView.findEditor.setText('items');
          return atom.commands.dispatch(projectFindView.element, 'core:confirm');
        });
        waitsForPromise(function() {
          return searchPromise;
        });
        return runs(function() {
          resultsView = getResultsView();
          return resultsView.selectFirstResult();
        });
      });
      return it("copies the selected line onto the clipboard", function() {
        _.times(2, function() {
          return atom.commands.dispatch(resultsView.element, 'core:move-down');
        });
        atom.commands.dispatch(resultsView.element, 'core:copy');
        return expect(atom.clipboard.read()).toBe('    return items if items.length <= 1');
      });
    });
  });

  buildMouseEvent = function() {
    var event, properties, type;
    type = arguments[0], properties = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
    properties = _.extend.apply(_, [{
      bubbles: true,
      cancelable: true
    }].concat(__slice.call(properties)));
    if (properties.detail == null) {
      properties.detail = 1;
    }
    event = new MouseEvent(type, properties);
    if (properties.which != null) {
      Object.defineProperty(event, 'which', {
        get: function() {
          return properties.which;
        }
      });
    }
    if (properties.target != null) {
      Object.defineProperty(event, 'target', {
        get: function() {
          return properties.target;
        }
      });
      Object.defineProperty(event, 'srcObject', {
        get: function() {
          return properties.target;
        }
      });
    }
    return event;
  };

}).call(this);
