// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

lib.rtdep('lib.colors', 'lib.f', 'lib.fs', 'lib.MessageManager');

/**
 * Constructor a new ConnectDialog instance.
 *
 * There should only be one of these, and it assumes the connect dialog is
 * the only thing in the current window.
 *
 * @param {MessagePort} messagePort The HTML5 message port we should use to
 *     communicate with the nassh instance.
 */
nassh.ConnectDialog = function(messagePort) {

  // Message port back to the terminal.
  this.messagePort_ = messagePort;
  this.messagePort_.onmessage = this.onMessage_.bind(this);
  this.messagePort_.start();

  // Turn off spellcheck everywhere.
  var ary = document.querySelectorAll('input[type="text"]');
  for (var i = 0; i < ary.length; i++) {
    ary[i].setAttribute('spellcheck', 'false');
  }

  // The Message Manager instance, null until the messages have loaded.
  this.mm_ = null;

  // The nassh global pref manager.
  this.prefs_ = new nassh.PreferenceManager();
  this.prefs_.readStorage(() => {
    this.syncProfiles_(this.onPreferencesReady_.bind(this));
  });

  // The profile we're currently displaying.
  this.currentProfileRecord_ = null;

  // The 'new' profile is special in that it doesn't have a real id or
  // prefs object until it is saved for the first time.
  this.emptyProfileRecord_ = new nassh.ConnectDialog.ProfileRecord(
      'new', null, '[New Connection]');

  // Map of id->nassh.ConnectDialog.ProfileRecord.
  this.profileMap_ = {};

  // Array of nassh.ConnectDialog.ProfileRecord instances in display order.
  this.profileList_ = [];

  // Cached DOM nodes.
  this.form_ = document.querySelector('form');
  this.mountButton_ = document.querySelector('#mount');
  this.unmountButton_ = document.querySelector('#unmount');
  this.connectButton_ = document.querySelector('#connect');
  this.deleteButton_ = document.querySelector('#delete');
  this.optionsButton_ = document.querySelector('#options');
};

/**
 * Global window message handler, uninstalled after proper handshake.
 */
nassh.ConnectDialog.onWindowMessage = function(e) {
  if (e.data.name != 'ipc-init') {
    console.warn('Unknown message from terminal:', e.data);
    return;
  }

  window.removeEventListener('message', nassh.ConnectDialog.onWindowMessage);

  lib.init(function() {
    window.dialog_ = new nassh.ConnectDialog(e.data.argv[0].messagePort);
  });
};

// Register the message listener.
window.addEventListener('message', nassh.ConnectDialog.onWindowMessage);

/**
 * Called by the preference manager when we've retrieved the current preference
 * values from storage.
 */
nassh.ConnectDialog.prototype.onPreferencesReady_ = function() {
  // Create and draw the shortcut list.
  this.shortcutList_ = new nassh.ColumnList(
      document.querySelector('#shortcut-list'), this.profileList_);

  // Install various (DOM and non-DOM) event handlers.
  this.installHandlers_();

  var profileIndex = 0;

  if (this.profileList_.length == 1) {
    // Just one profile record?  It's the "New..." profile, focus the form.
    this.$f('description').focus();

  } else {
    this.shortcutList_.focus();

    chrome.storage.local.get('/nassh/connectDialog/lastProfileId', (items) => {
      var lastProfileId = items['/nassh/connectDialog/lastProfileId'];
      if (lastProfileId)
        profileIndex = Math.max(0, this.getProfileIndex_(lastProfileId));

      this.shortcutList_.setActiveIndex(profileIndex);
      this.setCurrentProfileRecord(this.profileList_[profileIndex]);
    });
  }

  this.shortcutList_.setActiveIndex(profileIndex);
  // The shortcut list will eventually do this async, but we want it now...
  this.setCurrentProfileRecord(this.profileList_[profileIndex]);

  nassh.getFileSystem(this.onFileSystemFound_.bind(this));
};

/**
 * Simple struct to collect data about a profile.
 */
nassh.ConnectDialog.ProfileRecord = function(id, prefs, opt_textContent) {
  this.id = id;
  this.prefs = prefs;
  this.textContent = opt_textContent || prefs.get('description');
};

/**
 * Get a localized message from the Message Manager.
 *
 * This converts all message name to UPPER_AND_UNDER format, since that's
 * pretty handy in the connect dialog.
 */
nassh.ConnectDialog.prototype.msg = function(name, opt_args) {
  if (!this.mm_)
    return 'loading...';

  return this.mm_.get(name.toUpperCase().replace(/-/g, '_'), opt_args);
};

/**
 * Align the bottom fields.
 *
 * We want a grid-like layout for these fields.  This is not easily done
 * with box layout, but since we're using a fixed width font it's a simple
 * hack.  We just left-pad all of the labels with &nbsp; so they're all
 * the same length.
 */
nassh.ConnectDialog.prototype.alignLabels_ = function() {
  var labels = document.querySelectorAll('.aligned-dialog-labels');

  var labelWidth = 0;
  labels.forEach(function(el) {
    labelWidth = Math.max(labelWidth, el.textContent.length);
  });

  labels.forEach(function(el) {
      el.textContent = el.textContent.padStart(labelWidth, '\xa0');
    });
};

/**
 * Install various event handlers.
 */
nassh.ConnectDialog.prototype.installHandlers_ = function() {
  // Small utility to connect DOM events.
  function addListeners(node, events, handler, var_args) {
    for (var i = 2; i < arguments.length; i++) {
      handler = arguments[i];
      for (var j = 0; j < events.length; j++) {
        node.addEventListener(events[j], handler);
      }
    }
  }

  // Observe global 'profile-ids' list so we can keep the ColumnList updated.
  this.prefs_.addObservers(null, {
      'profile-ids': this.onProfileListChanged_.bind(this)
    });

  // Same for the 'description' field of all known profiles.
  for (var i = 0; i < this.profileList_.length; i++) {
    var rec = this.profileList_[i];
    if (rec.prefs) {
      rec.prefs.addObservers(null, {
       description: this.onDescriptionChanged_.bind(this)
      });
    }
  }

  // Watch for selection changes on the ColumnList so we can keep the
  // 'billboard' updated.
  this.shortcutList_.onActiveIndexChanged =
      this.onProfileIndexChanged.bind(this);

  // Register for keyboard shortcuts on the column list.
  this.shortcutList_.addEventListener('keydown',
                                      this.onShortcutListKeyDown_.bind(this));

  this.shortcutList_.addEventListener('dblclick',
                                      this.onShortcutListDblClick_.bind(this));

  this.form_.addEventListener('keyup', this.onFormKeyUp_.bind(this));

  this.connectButton_.addEventListener('keypress',
                                       this.onButtonKeypress_.bind(this));
  this.deleteButton_.addEventListener('keypress',
                                      this.onButtonKeypress_.bind(this));

  this.mountButton_.addEventListener('click',
                                     this.onMountClick_.bind(this));
  this.unmountButton_.addEventListener('click',
                                     this.onUnmountClick_.bind(this));
  this.connectButton_.addEventListener('click',
                                       this.onConnectClick_.bind(this));
  this.deleteButton_.addEventListener('click',
                                      this.onDeleteClick_.bind(this));
  this.optionsButton_.addEventListener('click',
                                       this.onOptionsClick_.bind(this));

  this.$f('identity').addEventListener('select', function(e) {
      if (e.target.value == '')
        e.target.selectedIndex = 0;
    });

  // These fields interact with each-other's placeholder text.
  ['description', 'username', 'hostname', 'port'
  ].forEach((name) => {
      var field = this.$f(name);

      // Alter description or detail placeholders, and commit the pref.
      addListeners(field, ['change', 'keypress', 'keyup'],
                   this.updatePlaceholders_.bind(this, name),
                   this.maybeDirty_.bind(this, name));

      addListeners(field, ['focus'],
                   this.maybeCopyPlaceholder_.bind(this, name));
    });

  this.$f('description').addEventListener(
      'blur', this.maybeCopyPlaceholders_.bind(this));

  // These fields are plain text with no fancy properties.
  ['argstr', 'terminal-profile', 'mount-path',
  ].forEach((name) => {
      var field = this.$f(name)
      addListeners(field,
                   ['change', 'keypress', 'keyup'],
                   this.maybeDirty_.bind(this, name));
    });

  ['description', 'username', 'hostname', 'port', 'relay-options',
   'identity', 'argstr', 'terminal-profile', 'mount-path',
  ].forEach((name) => {
      addListeners(this.$f(name), ['focus', 'blur'],
                   this.onFormFocusChange_.bind(this, name));
    });

  // Listen for DEL on the identity select box.
  this.$f('identity').addEventListener('keyup', (e) => {
      if (e.keyCode == 46 && e.target.selectedIndex != 0) {
        this.deleteIdentity_(e.target.value);
      }
    });

  this.importFileInput_ = document.querySelector('#import-file-input');
  this.importFileInput_.addEventListener(
      'change', this.onImportFiles_.bind(this));

  var importLink = document.querySelector('#import-link');
  importLink.addEventListener('click', (e) => {
      this.importFileInput_.click();
      e.preventDefault();
    });
};

/**
 * Quick way to ask for a '#field-' element from the dom.
 */
nassh.ConnectDialog.prototype.$f = function(
    name, opt_attrName, opt_attrValue) {
  var node = document.querySelector('#field-' + name);
  if (!node)
    throw new Error('Can\'t find: #field-' + name);

  if (!opt_attrName)
    return node;

  if (typeof opt_attrValue == 'undefined')
    return node.getAttribute(opt_attrName);

  node.setAttribute(opt_attrName, opt_attrValue);
};

/**
 * Change the active profile.
 */
nassh.ConnectDialog.prototype.setCurrentProfileRecord = function(
    profileRecord) {
  if (!profileRecord)
    throw 'null profileRecord.';

  this.currentProfileRecord_ = profileRecord;
  this.syncForm_();

  // For console debugging.
  window.p_ = profileRecord;
};

/**
 * Change the enabled state of one of our <div role='button'> elements.
 *
 * Since they're not real <button> tags the don't react properly to the
 * disabled property.
 */
nassh.ConnectDialog.prototype.enableButton_ = function(button, state) {
  if (state) {
    button.removeAttribute('disabled');
    button.setAttribute('tabindex', '0');
  } else {
    button.setAttribute('disabled', 'disabled');
    button.setAttribute('tabindex', '-1');
  }
};

/**
 * Change the display state of one of our <div role='button'> elements.
 */
nassh.ConnectDialog.prototype.displayButton_ = function(
    button, state, style='inline') {
  if (state) {
    button.style.display = style;
    button.setAttribute('tabindex', '0');
  } else {
    button.style.display = 'none';
    button.setAttribute('tabindex', '-1');
  }
};

/**
 * Change the mounted state of the mount button.
 */
nassh.ConnectDialog.prototype.displayMountButton_ = function(state) {
  this.displayButton_(document.querySelector('#mount-path'), state, 'flex');
  if (!state) {
    this.displayButton_(this.mountButton_, false);
    this.displayButton_(this.unmountButton_, false);
    return;
  }

  chrome.fileSystemProvider.getAll((fileSystems) => {
    for (var i in fileSystems) {
      if (fileSystems[i].fileSystemId == this.currentProfileRecord_.id) {
        this.displayButton_(this.mountButton_, false);
        this.displayButton_(this.unmountButton_, true);
        return;
      }
    }
    this.displayButton_(this.mountButton_, true);
    this.displayButton_(this.unmountButton_, false);
    this.enableButton_(this.mountButton_, this.form_.checkValidity());
  });
};

/**
 * Persist the current form to prefs, even if it's invalid.
 */
nassh.ConnectDialog.prototype.save = function() {
  if (!this.$f('description').value)
    return;

  var dirtyForm = false;
  var changedFields = {};

  var prefs = this.currentProfileRecord_.prefs;

  ['description', 'username', 'hostname', 'port', 'relay-options',
   'identity', 'argstr', 'terminal-profile', 'mount-path',
  ].forEach((name) => {
       if (name == 'identity' && this.$f('identity').selectedIndex === 0)
         return;

       var value = this.$f(name).value;

       if (name == 'port')
         value = value ? parseInt(value) : '';

       if ((!prefs && !value) || (prefs && value == prefs.get(name)))
         return;

       dirtyForm = true;
       changedFields[name] = value;
     });

  if (dirtyForm) {
    if (!prefs) {
      var prefs = this.prefs_.createProfile();
      var rec = new nassh.ConnectDialog.ProfileRecord(
          prefs.id, prefs, changedFields['description']);
      this.currentProfileRecord_ = rec;

      prefs.addObservers(null, {
       description: this.onDescriptionChanged_.bind(this)
      });

      this.shortcutList_.afterNextRedraw(() => {
        this.shortcutList_.setActiveIndex(this.profileList_.length - 1);
      });
    }

    for (var name in changedFields) {
      this.currentProfileRecord_.prefs.set(name, changedFields[name]);
    }
  }
};

/**
 * Mount if the form validates.
 */
nassh.ConnectDialog.prototype.mount = function() {
  this.maybeCopyPlaceholders_();
  this.save();

  var items = {
    '/nassh/connectDialog/lastProfileId': this.currentProfileRecord_.id
  };
  chrome.storage.local.set(items);

  if (this.form_.checkValidity())
    this.postMessage('mountProfile', [this.currentProfileRecord_.id]);
};

/**
 * Unmount the SFTP connection.
 */
nassh.ConnectDialog.prototype.unmount = function() {
  var options = {fileSystemId: this.currentProfileRecord_.id};
  chrome.extension.getBackgroundPage().
    nassh.sftp.fsp.onUnmountRequested(options,
    (success) => { this.displayMountButton_(true); },
    (error) => { /* do nothing */ });
};

/**
 * Save any changes and connect if the form validates.
 */
nassh.ConnectDialog.prototype.connect = function(name, argv) {
  this.maybeCopyPlaceholders_();
  this.save();

  // Since the user has initiated this connection, register the protocol.
  nassh.registerProtocolHandler();

  var items = {
    '/nassh/connectDialog/lastProfileId': this.currentProfileRecord_.id
  };
  chrome.storage.local.set(items);

  if (this.form_.checkValidity())
    this.postMessage('connectToProfile', [this.currentProfileRecord_.id]);
};

/**
 * Send a message back to the terminal.
 */
nassh.ConnectDialog.prototype.postMessage = function(name, argv) {
  this.messagePort_.postMessage({name: name, argv: argv || null});
};

/**
 * Set the profile's dirty bit if the given field has changed from it's current
 * pref value.
 */
nassh.ConnectDialog.prototype.maybeDirty_ = function(fieldName) {
  if (this.currentProfileRecord_.prefs) {
    if (this.$f(fieldName).value !=
        this.currentProfileRecord_.prefs.get(fieldName)) {
      this.currentProfileRecord_.dirty = true;
    }
  } else {
    if (this.$f(fieldName).value)
      this.currentProfileRecord_.dirty = true;
  }
};

/**
 * Invoke the maybeCopyPlaceholder_ method for the fields we're willing
 * to bulk-default.
 */
nassh.ConnectDialog.prototype.maybeCopyPlaceholders_ = function() {
  ['description', 'username', 'hostname', 'port', 'relay-options',
  ].forEach(this.maybeCopyPlaceholder_.bind(this));
  this.syncButtons_();
};

/**
 * If the field is empty and the current placeholder isn't the default,
 * then initialize the field to the placeholder.
 */
nassh.ConnectDialog.prototype.maybeCopyPlaceholder_ = function(fieldName) {
  var field = this.$f(fieldName);
  var placeholder = field.getAttribute('placeholder');
  if (!field.value && placeholder != this.msg('FIELD_' + fieldName +
                                              '_PLACEHOLDER')) {
    field.value = placeholder;
  }
};

/**
 * Compute the placeholder text for a given field.
 */
nassh.ConnectDialog.prototype.updatePlaceholders_ = function(fieldName) {
  if (fieldName == 'description') {
    // If the description changed, update the username/host/etc placeholders.
    this.updateDetailPlaceholders_();
  } else {
    // Otherwise update the description placeholder.
    this.updateDescriptionPlaceholder_();
  }
};

/**
 * Update the placeholders in the detail (username, hostname, etc) fields.
 */
nassh.ConnectDialog.prototype.updateDetailPlaceholders_ = function() {
  // Try to split the description up into the sub-fields.
  var ary = this.$f('description').value.match(
      /^([^@]+)@([^:@]+)?(?::(\d+)?)?(?:@(.*))?$/);

  // Set a blank array if the match failed.
  ary = ary || [];

  // Remove element 0, the "full match" string.
  ary.shift();

  // Copy the remaining match elements into the appropriate placeholder
  // attribute.  Set the default placeholder text from this.str.placeholders
  // for any field that was not matched.
  ['username', 'hostname', 'port'
  ].forEach((name) => {
    var value = ary.shift();
    if (!value) {
      value = this.msg('FIELD_' + name + '_PLACEHOLDER');
    }

    this.$f(name, 'placeholder', value);
  });

  // Google-specific relay hack.  This feels dirty.  We can revert this once
  // we support managed default configs.  http://b/28205376 & related docs.
  let value = this.msg('FIELD_RELAY_OPTIONS_PLACEHOLDER');
  if (!this.$f('relay-options').value) {
    let hostname = this.$f('hostname').placeholder;
    if (hostname.endsWith('.corp.google.com'))
      value = '--config=google';
    else if (hostname.endsWith('.c.googlers.com'))
      value = '--config=google --proxy-host=sup-ssh-relay.corp.google.com';
  }
  this.$f('relay-options', 'placeholder', value);
};

/**
 * Update the description placeholder.
 */
nassh.ConnectDialog.prototype.updateDescriptionPlaceholder_ = function() {
  var username = this.$f('username').value;
  var hostname = this.$f('hostname').value;

  var placeholder;

  if (username && hostname) {
    placeholder = username + '@' + hostname;

    var v = this.$f('port').value;
    if (v)
      placeholder += ':' + v;
  } else {
    placeholder = this.msg('FIELD_DESCRIPTION_PLACEHOLDER');
  }

  this.$f('description', 'placeholder', placeholder);
};

/**
 * Sync the form with the current profile record.
 */
nassh.ConnectDialog.prototype.syncForm_ = function() {
  ['description', 'username', 'hostname', 'port', 'argstr', 'relay-options',
   'identity', 'terminal-profile', 'mount-path',
  ].forEach((n) => {
      var emptyValue = '';
      if (n == 'identity')
        emptyValue = this.$f('identity').firstChild.textContent;

      if (this.currentProfileRecord_.prefs) {
        this.$f(n).value =
            this.currentProfileRecord_.prefs.get(n) || emptyValue;
      } else {
        this.$f(n).value = emptyValue;
      }
    });

  this.updateDetailPlaceholders_();
  this.updateDescriptionPlaceholder_();
};

/**
 * Checks whether the current machine can use the File System Provider API, and
 * thus be able to be mounted.
 */
nassh.ConnectDialog.prototype.checkMountable_ = function() {
  return chrome.fileSystemProvider !== undefined;
};

/**
 * Sync the states of the buttons.
 */
nassh.ConnectDialog.prototype.syncButtons_ = function() {
  this.enableButton_(
      this.deleteButton_,
      document.activeElement.getAttribute('id') == 'shortcut-list');

  this.enableButton_(this.connectButton_, this.form_.checkValidity());
  this.displayMountButton_(this.checkMountable_());
};

/**
 * Sync the identity dropdown box with the filesystem.
 */
nassh.ConnectDialog.prototype.syncIdentityDropdown_ = function(opt_onSuccess) {
  var keyfileNames = [];
  var identitySelect = this.$f('identity');

  var selectedName;
  if (this.currentProfileRecord_.prefs) {
    selectedName = this.currentProfileRecord_.prefs.get('identity');
  } else {
    selectedName = identitySelect.value;
  }

  function clearSelect() {
    while (identitySelect.firstChild) {
      identitySelect.removeChild(identitySelect.firstChild);
    }
  }

  var onReadError = () => {
    clearSelect();
    var option = document.createElement('option');
    option.textContent = 'Error!';
    identitySelect.appendChild(option);
  };

  var onReadSuccess = (entries) => {
    for (var key in entries) {
      var ary = key.match(/^(.*)\.pub/);
      if (ary && ary[1] in entries)
        keyfileNames.push(ary[1]);
    }

    clearSelect();

    var option = document.createElement('option');
    option.textContent = '[default]';
    identitySelect.appendChild(option);

    for (var i = 0; i < keyfileNames.length; i++) {
      var option = document.createElement('option');
      option.textContent = keyfileNames[i];
      identitySelect.appendChild(option);
      if (keyfileNames[i] == selectedName)
        identitySelect.selectedIndex = i;
    }

    this.syncForm_();

    if (opt_onSuccess)
      opt_onSuccess();

  };

  lib.fs.readDirectory(this.fileSystem_.root, '/.ssh/', onReadSuccess,
                       lib.fs.err('Error enumerating /.ssh/', onReadError));
};

/**
 * Delete one a pair of identity files from the html5 filesystem.
 */
nassh.ConnectDialog.prototype.deleteIdentity_ = function(identityName) {
  var count = 0;

  var onRemove = () => {
    if (++count == 2)
      this.syncIdentityDropdown_();
  };

  lib.fs.removeFile(this.fileSystem_.root, '/.ssh/' + identityName,
                    onRemove);
  lib.fs.removeFile(this.fileSystem_.root, '/.ssh/' + identityName + '.pub',
                    onRemove);
};

nassh.ConnectDialog.prototype.deleteProfile_ = function(deadID) {
  if (this.currentProfileRecord_.id == deadID) {
    // The actual profile removal and list-updating will happen async.
    // Rather than come up with a fancy hack to update the selection when
    // it's done, we just move it before the delete.
    var currentIndex = this.shortcutList_.activeIndex;
    if (currentIndex == this.profileList_.length - 1) {
      // User is deleting the last (non-new) profile, select the one before
      // it.
      this.shortcutList_.setActiveIndex(this.profileList_.length - 2);
    } else {
      this.shortcutList_.setActiveIndex(currentIndex + 1);
    }
  }

  this.prefs_.removeProfile(deadID);
};

/**
 * Return the index into this.profileList_ for a given profile id.
 *
 * Returns -1 if the id is not found.
 */
nassh.ConnectDialog.prototype.getProfileIndex_ = function(id) {
  for (var i = 0; i < this.profileList_.length; i++) {
    if (this.profileList_[i].id == id)
      return i;
  }

  return -1;
};

/**
 * Sync the ColumnList with the known profiles.
 */
nassh.ConnectDialog.prototype.syncProfiles_ = function(opt_callback) {
  var ids = this.prefs_.get('profile-ids');

  this.profileList_.length = 0;
  var currentProfileExists = false;
  var emptyProfileExists = false;

  var deadProfiles = Object.keys(this.profileMap_);

  for (var i = 0; i < ids.length; i++) {
    var id = ids[i];
    var p;

    if (this.currentProfileRecord_ && id == this.currentProfileRecord_.id)
      currentProfileExists = true;

    if (id == this.emptyProfileRecord_.id) {
      emptyProfileExists = true;
      p = this.emptyProfileRecord_;
    } else {
      p = this.profileMap_[id];
    }

    deadProfiles.splice(deadProfiles.indexOf(id), 1);

    if (!p) {
      p = this.profileMap_[id] = new nassh.ConnectDialog.ProfileRecord(
          id, this.prefs_.getProfile(id));
    } else if (p.prefs) {
      p.textContent = p.prefs.get('description');
    }

    this.profileList_.push(p);
  }

  for (var i = 0; i < deadProfiles.length; i++) {
    delete this.profileMap_[deadProfiles[i]];
  }

  if (!currentProfileExists) {
    this.setCurrentProfileRecord(this.emptyProfileRecord_);
  }

  if (!emptyProfileExists) {
    this.profileList_.unshift(this.emptyProfileRecord_);
    this.profileMap_[this.emptyProfileRecord_.id] = this.emptyProfileRecord_;
  }

  if (this.profileList_.length == 1) {
    if (opt_callback)
      opt_callback();
  }

  // Start at 1 for the "[New Connection]" profile.
  var initialized = 1;

  var onRead = function(profile) {
    profile.textContent = profile.prefs.get('description');

    if ((++initialized == this.profileList_.length) && opt_callback)
        opt_callback();
  };

  this.profileList_.forEach((profile) => {
    if (profile.prefs)
      profile.prefs.readStorage(onRead.bind(this, profile));
  });
};

/**
 * Success callback for lib.fs.getFileSystem().
 *
 * Kick off the "Identity" dropdown now that we have access to the filesystem.
 */
nassh.ConnectDialog.prototype.onFileSystemFound_ = function(
    fileSystem, sshDirectoryEntry) {
  this.fileSystem_ = fileSystem;
  this.sshDirectoryEntry_ = sshDirectoryEntry;
  this.syncIdentityDropdown_();

  // Tell the parent we're ready to roll.
  this.postMessage('ipc-init-ok');
};

/**
 * User initiated file import.
 *
 * This is the onChange handler for the `input type="file"`
 * (aka this.importFileInput_) control.
 */
nassh.ConnectDialog.prototype.onImportFiles_ = function(e) {
  var input = this.importFileInput_;
  var select = this.$f('identity');

  var onImportSuccess = () => {
    this.syncIdentityDropdown_(function() {
      select.selectedIndex = select.childNodes.length - 1;
    });
  };

  if (!input.files.length)
    return;

  nassh.importFiles(this.fileSystem_, '/.ssh/', input.files, onImportSuccess);

  return false;
};

/**
 * Keydown event on the shortcut list.
 */
nassh.ConnectDialog.prototype.onShortcutListKeyDown_ = function(e) {
  var isNewConnection = this.currentProfileRecord_ == this.emptyProfileRecord_;
  if (e.keyCode == 46) {
    // DEL delete the profile.
    if (!isNewConnection) {
      this.deleteProfile_(this.currentProfileRecord_.id);
    } else {
      // Otherwise the user is deleting the placeholder profile.  All we
      // do here is reset the form.
      this.syncForm_();
      this.$f('description').focus();
    }

  } else if (e.keyCode == 13) {
    if (isNewConnection) {
      this.$f('description').focus();
    } else {
      this.onConnectClick_();
    }
  }
};

nassh.ConnectDialog.prototype.onShortcutListDblClick_ = function(e) {
  this.onConnectClick_();
};

/**
 * Called when the ColumnList says the active profile changed.
 */
nassh.ConnectDialog.prototype.onProfileIndexChanged = function(e) {
  this.setCurrentProfileRecord(this.profileList_[e.now]);
  this.syncButtons_();
};

/**
 * Key press while a button has focus.
 */
nassh.ConnectDialog.prototype.onButtonKeypress_ = function(e) {
  if (e.charCode == 13 || e.charCode == 32)
    e.srcElement.click();
};

/**
 * Someone clicked on the mount button.
 */
nassh.ConnectDialog.prototype.onMountClick_ = function(e) {
  this.mount();
};

/**
 * Someone clicked on the unmount button.
 */
nassh.ConnectDialog.prototype.onUnmountClick_ = function(e) {
  this.unmount();
};

/**
 * Someone clicked on the connect button.
 */
nassh.ConnectDialog.prototype.onConnectClick_ = function(e) {
  if (this.connectButton_.getAttribute('disabled'))
    return;

  this.connect();
};

/**
 * Someone clicked on the delete button.
 */
nassh.ConnectDialog.prototype.onDeleteClick_ = function(e) {
  if (this.deleteButton_.getAttribute('disabled'))
    return;

  if (document.activeElement.getAttribute('id') == 'field-identity') {
    this.deleteIdentity_(e.target.value);
  } else {
    this.deleteProfile_(this.currentProfileRecord_.id);
    this.shortcutList_.focus();
  }
};

/**
 * Someone clicked on the options button.
 */
nassh.ConnectDialog.prototype.onOptionsClick_ = nassh.openOptionsPage;

/**
 * KeyUp on the form element.
 */
nassh.ConnectDialog.prototype.onFormKeyUp_ = function(e) {
  if (e.keyCode == 13) {  // ENTER
    this.connect();
  } else if (e.keyCode == 27) {  // ESC
    this.syncForm_();
    this.shortcutList_.focus();
  }
};

/**
 * Focus change on the form element.
 *
 * This handler is registered to every form element's focus and blur events.
 * Keep in mind that for change in focus from one input to another will invoke
 * this twice.
 */
nassh.ConnectDialog.prototype.onFormFocusChange_ = function(e) {
  this.syncButtons_();
  this.save();
};

/**
 * Pref callback invoked when the global 'profile-ids' changed.
 */
nassh.ConnectDialog.prototype.onProfileListChanged_ = function() {
  this.syncProfiles_(() => { this.shortcutList_.redraw() });
};

/**
 * Pref callback invoked when a profile's description has changed.
 */
nassh.ConnectDialog.prototype.onDescriptionChanged_ = function(
    value, name, prefs) {
  if (this.profileMap_[prefs.id]) {
    this.profileMap_[prefs.id].textContent = value;
    this.shortcutList_.scheduleRedraw();
  }
};

/**
 * Handle a message from the terminal.
 */
nassh.ConnectDialog.prototype.onMessage_ = function(e) {
  if (e.data.name in this.onMessageName_) {
    this.onMessageName_[e.data.name].apply(this, e.data.argv);
  } else {
    console.warn('Unhandled message: ' + e.data.name, e.data);
  }
};

/**
 * Terminal message handlers.
 */
nassh.ConnectDialog.prototype.onMessageName_ = {};

/**
 * terminal-info: The terminal introduces itself.
 */
nassh.ConnectDialog.prototype.onMessageName_['terminal-info'] = function(info) {
  this.mm_ = new lib.MessageManager(info.acceptLanguages);
  this.mm_.processI18nAttributes(document.body);
  this.alignLabels_();
  this.updateDetailPlaceholders_();
  this.updateDescriptionPlaceholder_();

  document.body.style.fontFamily = info.fontFamily;
  document.body.style.fontSize = info.fontSize + 'px';

  var fg = lib.colors.normalizeCSS(info.foregroundColor);
  var bg = lib.colors.normalizeCSS(info.backgroundColor);
  var cursor = lib.colors.normalizeCSS(info.cursorColor);

  var vars = {
    '--nassh-bg-color': bg,
    '--nassh-fg-color': fg,
    '--nassh-cursor-color': cursor,
  };

  for (var i = 10; i < 100; i += 5) {
    vars['--nassh-bg-color-' + i] = lib.colors.setAlpha(bg, i / 100);
    vars['--nassh-fg-color-' + i] = lib.colors.setAlpha(fg, i / 100);
    vars['--nassh-cursor-color-' + i] = lib.colors.setAlpha(cursor, i / 100);
  }

  for (var key in vars)
    if (key.startsWith('--nassh-'))
      document.documentElement.style.setProperty(key, vars[key]);

  // Tell the parent we've finished loading all the terminal details.
  this.postMessage('terminal-info-ok');
};
