(function() {
  var FatalMetaNotificationTemplate, NotificationElement, NotificationIssue, NotificationTemplate, TemplateHelper, UserUtilities, addSplitLinesToContainer, fs, marked, path,
    __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');

  path = require('path');

  marked = require('marked');

  NotificationIssue = require('./notification-issue');

  TemplateHelper = require('./template-helper');

  UserUtilities = require('./user-utilities');

  NotificationTemplate = "<div class=\"content\">\n  <div class=\"message item\"></div>\n  <div class=\"detail item\">\n    <div class=\"detail-content\"></div>\n    <a href=\"#\" class=\"stack-toggle\"></a>\n    <div class=\"stack-container\"></div>\n  </div>\n  <div class=\"meta item\"></div>\n</div>\n<div class=\"close icon icon-x\"></div>\n<div class=\"close-all btn btn-error\">Close All</div>";

  FatalMetaNotificationTemplate = "<div class=\"fatal-notification\"></div>\n<div class=\"btn-toolbar\">\n  <a href=\"#\" class=\"btn-issue btn btn-error\"></a>\n  <a href=\"#\" class=\"btn-copy-report icon icon-clippy\" title=\"Copy error report to clipboard\"></a>\n</div>";

  NotificationElement = (function(_super) {
    __extends(NotificationElement, _super);

    NotificationElement.prototype.animationDuration = 700;

    NotificationElement.prototype.visibilityDuration = 5000;

    NotificationElement.prototype.fatalTemplate = TemplateHelper.create(FatalMetaNotificationTemplate);

    function NotificationElement() {}

    NotificationElement.prototype.initialize = function(model) {
      this.model = model;
      if (this.model.getType() === 'fatal') {
        this.issue = new NotificationIssue(this.model);
      }
      this.renderPromise = this.render()["catch"](function(e) {
        console.error(e.message);
        return console.error(e.stack);
      });
      if (this.model.isDismissable()) {
        this.model.onDidDismiss((function(_this) {
          return function() {
            return _this.removeNotification();
          };
        })(this));
      } else {
        this.autohide();
      }
      return this;
    };

    NotificationElement.prototype.getModel = function() {
      return this.model;
    };

    NotificationElement.prototype.getRenderPromise = function() {
      return this.renderPromise;
    };

    NotificationElement.prototype.render = function() {
      var closeAllButton, closeButton, detail, notificationContainer, stack, stackContainer, stackToggle;
      this.classList.add("" + (this.model.getType()));
      this.classList.add("icon", "icon-" + (this.model.getIcon()), "native-key-bindings");
      if (detail = this.model.getDetail()) {
        this.classList.add('has-detail');
      }
      if (this.model.isDismissable()) {
        this.classList.add('has-close');
      }
      if (this.model.getOptions().stack != null) {
        this.classList.add('has-stack');
      }
      this.setAttribute('tabindex', '-1');
      this.innerHTML = NotificationTemplate;
      notificationContainer = this.querySelector('.message');
      notificationContainer.innerHTML = marked(this.model.getMessage());
      if (detail = this.model.getDetail()) {
        addSplitLinesToContainer(this.querySelector('.detail-content'), detail);
        if (stack = this.model.getOptions().stack) {
          stackToggle = this.querySelector('.stack-toggle');
          stackContainer = this.querySelector('.stack-container');
          addSplitLinesToContainer(stackContainer, stack);
          stackToggle.addEventListener('click', (function(_this) {
            return function(e) {
              return _this.handleStackTraceToggleClick(e, stackContainer);
            };
          })(this));
          this.handleStackTraceToggleClick({
            currentTarget: stackToggle
          }, stackContainer);
        }
      }
      if (this.model.isDismissable()) {
        closeButton = this.querySelector('.close');
        closeButton.addEventListener('click', (function(_this) {
          return function() {
            return _this.handleRemoveNotificationClick();
          };
        })(this));
        closeAllButton = this.querySelector('.close-all');
        closeAllButton.classList.add(this.getButtonClass());
        closeAllButton.addEventListener('click', (function(_this) {
          return function() {
            return _this.handleRemoveAllNotificationsClick();
          };
        })(this));
      }
      if (this.model.getType() === 'fatal') {
        return this.renderFatalError();
      } else {
        return Promise.resolve();
      }
    };

    NotificationElement.prototype.renderFatalError = function() {
      var copyReportButton, fatalContainer, fatalNotification, issueButton, packageName, promises, repoUrl;
      repoUrl = this.issue.getRepoUrl();
      packageName = this.issue.getPackageName();
      fatalContainer = this.querySelector('.meta');
      fatalContainer.appendChild(TemplateHelper.render(this.fatalTemplate));
      fatalNotification = this.querySelector('.fatal-notification');
      issueButton = fatalContainer.querySelector('.btn-issue');
      copyReportButton = fatalContainer.querySelector('.btn-copy-report');
      atom.tooltips.add(copyReportButton, {
        title: copyReportButton.getAttribute('title')
      });
      copyReportButton.addEventListener('click', (function(_this) {
        return function(e) {
          e.preventDefault();
          return _this.issue.getIssueBody().then(function(issueBody) {
            return atom.clipboard.write(issueBody);
          });
        };
      })(this));
      if ((packageName != null) && (repoUrl != null)) {
        fatalNotification.innerHTML = "The error was thrown from the <a href=\"" + repoUrl + "\">" + packageName + " package</a>. ";
      } else if (packageName != null) {
        issueButton.remove();
        fatalNotification.textContent = "The error was thrown from the " + packageName + " package. ";
      } else {
        fatalNotification.textContent = "This is likely a bug in Atom. ";
      }
      if (issueButton.parentNode != null) {
        if ((packageName != null) && (repoUrl != null)) {
          issueButton.textContent = "Create issue on the " + packageName + " package";
        } else {
          issueButton.textContent = "Create issue on atom/atom";
        }
        promises = [];
        promises.push(this.issue.findSimilarIssues());
        promises.push(this.issue.getIssueUrlForSystem());
        promises.push(UserUtilities.checkAtomUpToDate());
        if (packageName != null) {
          promises.push(UserUtilities.checkPackageUpToDate(packageName));
        }
        return Promise.all(promises).then((function(_this) {
          return function(allData) {
            var atomCheck, issue, issues, newIssueUrl, packageCheck, packagePath, _ref;
            issues = allData[0], newIssueUrl = allData[1], atomCheck = allData[2], packageCheck = allData[3];
            if ((issues != null ? issues.open : void 0) || (issues != null ? issues.closed : void 0)) {
              issue = issues.open || issues.closed;
              issueButton.setAttribute('href', issue.html_url);
              issueButton.textContent = "View Issue";
              fatalNotification.innerHTML += " This issue has already been reported.";
            } else if ((packageCheck != null) && !packageCheck.upToDate && !packageCheck.isCore) {
              issueButton.setAttribute('href', '#');
              issueButton.textContent = "Check for package updates";
              issueButton.addEventListener('click', function(e) {
                var command;
                e.preventDefault();
                command = 'settings-view:check-for-package-updates';
                return atom.commands.dispatch(atom.views.getView(atom.workspace), command);
              });
              fatalNotification.innerHTML += "<code>" + packageName + "</code> is out of date: " + packageCheck.installedVersion + " installed;\n" + packageCheck.latestVersion + " latest.\nUpgrading to the latest version may fix this issue.";
            } else if ((packageCheck != null) && !packageCheck.upToDate && packageCheck.isCore) {
              issueButton.remove();
              fatalNotification.innerHTML += "<br><br>\nLocally installed core Atom package <code>" + packageName + "</code> is out of date: " + packageCheck.installedVersion + " installed locally;\n" + packageCheck.versionShippedWithAtom + " included with the version of Atom you're running.\nRemoving the locally installed version may fix this issue.";
              packagePath = (_ref = atom.packages.getLoadedPackage(packageName)) != null ? _ref.path : void 0;
              if (fs.isSymbolicLinkSync(packagePath)) {
                fatalNotification.innerHTML += "<br><br>\nUse: <code>apm unlink " + packagePath + "</code>";
              }
            } else if ((atomCheck != null) && !atomCheck.upToDate) {
              issueButton.remove();
              fatalNotification.innerHTML += "Atom is out of date: " + atomCheck.installedVersion + " installed;\n" + atomCheck.latestVersion + " latest.\nUpgrading to the <a href='https://github.com/atom/atom/releases/tag/v" + atomCheck.latestVersion + "'>latest version</a> may fix this issue.";
            } else {
              if (newIssueUrl != null) {
                issueButton.setAttribute('href', newIssueUrl);
              }
              fatalNotification.innerHTML += " You can help by creating an issue. Please explain what actions triggered this error.";
            }
          };
        })(this));
      } else {
        return Promise.resolve();
      }
    };

    NotificationElement.prototype.removeNotification = function() {
      this.classList.add('remove');
      this.removeNotificationAfterTimeout();
      return atom.workspace.getActivePane().activate();
    };

    NotificationElement.prototype.handleRemoveNotificationClick = function() {
      return this.model.dismiss();
    };

    NotificationElement.prototype.handleRemoveAllNotificationsClick = function() {
      var notification, notifications, _i, _len;
      notifications = atom.notifications.getNotifications();
      for (_i = 0, _len = notifications.length; _i < _len; _i++) {
        notification = notifications[_i];
        if (notification.isDismissable() && !notification.isDismissed()) {
          notification.dismiss();
        }
      }
    };

    NotificationElement.prototype.handleStackTraceToggleClick = function(e, container) {
      if (typeof e.preventDefault === "function") {
        e.preventDefault();
      }
      if (container.style.display === 'none') {
        e.currentTarget.innerHTML = '<span class="icon icon-dash"></span>Hide Stack Trace';
        return container.style.display = 'block';
      } else {
        e.currentTarget.innerHTML = '<span class="icon icon-plus"></span>Show Stack Trace';
        return container.style.display = 'none';
      }
    };

    NotificationElement.prototype.autohide = function() {
      return setTimeout((function(_this) {
        return function() {
          _this.classList.add('remove');
          return _this.removeNotificationAfterTimeout();
        };
      })(this), this.visibilityDuration);
    };

    NotificationElement.prototype.removeNotificationAfterTimeout = function() {
      return setTimeout((function(_this) {
        return function() {
          return _this.remove();
        };
      })(this), this.animationDuration);
    };

    NotificationElement.prototype.getButtonClass = function() {
      var type;
      type = "btn-" + (this.model.getType());
      if (type === 'btn-fatal') {
        return 'btn-error';
      } else {
        return type;
      }
    };

    return NotificationElement;

  })(HTMLElement);

  addSplitLinesToContainer = function(container, content) {
    var div, line, _i, _len, _ref;
    _ref = content.split('\n');
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      line = _ref[_i];
      div = document.createElement('div');
      div.classList.add('line');
      div.textContent = line;
      container.appendChild(div);
    }
  };

  module.exports = NotificationElement = document.registerElement('atom-notification', {
    prototype: NotificationElement.prototype
  });

}).call(this);
