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

/**
 * The repeat delay in milliseconds before a key starts repeating. Use the
 * same rate as Chromebook.
 * (See chrome/browser/chromeos/language_preferences.cc)
 * @const
 * @type {number}
 */
var REPEAT_DELAY_MSEC = 500;

/**
 * The repeat interval or number of milliseconds between subsequent
 * keypresses. Use the same rate as Chromebook.
 * @const
 * @type {number}
 */
var REPEAT_INTERVAL_MSEC = 50;

/**
 * The double click/tap interval.
 * @const
 * @type {number}
 */
var DBL_INTERVAL_MSEC = 300;

/**
 * The index of the name of the keyset when searching for all keysets.
 * @const
 * @type {number}
 */
var REGEX_KEYSET_INDEX = 1;

/**
 * The integer number of matches when searching for keysets.
 * @const
 * @type {number}
 */
var REGEX_MATCH_COUNT = 2;

/**
 * The boolean to decide if keyboard should transit to upper case keyset
 * when spacebar is pressed. If a closing punctuation is followed by a
 * spacebar, keyboard should automatically transit to upper case.
 * @type {boolean}
 */
var enterUpperOnSpace = false;

/**
 * A structure to track the currently repeating key on the keyboard.
 */
var repeatKey = {

  /**
    * The timer for the delay before repeating behaviour begins.
    * @type {number|undefined}
    */
  timer: undefined,

  /**
   * The interval timer for issuing keypresses of a repeating key.
   * @type {number|undefined}
   */
  interval: undefined,

  /**
   * The key which is currently repeating.
   * @type {BaseKey|undefined}
   */
  key: undefined,

  /**
   * Cancel the repeat timers of the currently active key.
   */
  cancel: function() {
    clearTimeout(this.timer);
    clearInterval(this.interval);
    this.timer = undefined;
    this.interval = undefined;
    this.key = undefined;
  }
};

/**
 * The minimum movement interval needed to trigger cursor move on
 * horizontal and vertical way.
 * @const
 * @type {number}
 */
var MIN_SWIPE_DIST_X = 50;
var MIN_SWIPE_DIST_Y = 20;

/**
 * The maximum swipe distance that will trigger hintText of a key
 * to be typed.
 * @const
 * @type {number}
 */
var MAX_SWIPE_FLICK_DIST = 60;

/**
 * The boolean to decide if it is swipe in process or finished.
 * @type {boolean}
 */
var swipeInProgress = false;

// Flag values for ctrl, alt and shift as defined by EventFlags
// in "event_constants.h".
// @enum {number}
var Modifier = {
  NONE: 0,
  ALT: 8,
  CONTROL: 4,
  SHIFT: 2
};

/**
 * A structure to track the current swipe status.
 */
var swipeTracker = {
  /**
   * The latest PointerMove event in the swipe.
   * @type {Object}
   */
  currentEvent: undefined,

  /**
   * Whether or not a swipe changes direction.
   * @type {false}
   */
  isComplex: false,

  /**
   * The count of horizontal and vertical movement.
   * @type {number}
   */
  offset_x : 0,
  offset_y : 0,

  /**
   * Last touch coordinate.
   * @type {number}
   */
  pre_x : 0,
  pre_y : 0,

  /**
   * The PointerMove event which triggered the swipe.
   * @type {Object}
   */
  startEvent: undefined,

  /**
   * The flag of current modifier key.
   * @type {number}
   */
  swipeFlags : 0,

  /**
   * Current swipe direction.
   * @type {number}
   */
  swipeDirection : 0,

  /**
   * The number of times we've swiped within a single swipe.
   * @type {number}
   */
  swipeIndex: 0,

  /**
   * Returns the combined direction of the x and y offsets.
   * @return {number} The latest direction.
   */
  getOffsetDirection: function() {
    // TODO (rsadam): Use angles to figure out the direction.
    var direction = 0;
    // Checks for horizontal swipe.
    if (Math.abs(this.offset_x) > MIN_SWIPE_DIST_X) {
      if (this.offset_x > 0) {
        direction |= SwipeDirection.RIGHT;
      } else {
        direction |= SwipeDirection.LEFT;
      }
    }
    // Checks for vertical swipe.
    if (Math.abs(this.offset_y) > MIN_SWIPE_DIST_Y) {
      if (this.offset_y < 0) {
        direction |= SwipeDirection.UP;
      } else {
        direction |= SwipeDirection.DOWN;
      }
    }
    return direction;
  },

  /**
   * Populates the swipe update details.
   * @param {boolean} endSwipe Whether this is the final event for this
   *     swipe.
   * @return {Object} The current state of the swipeTracker.
   */
  populateDetails: function(endSwipe) {
    var detail = {};
    detail.direction = this.swipeDirection;
    detail.index = this.swipeIndex;
    detail.status = this.swipeStatus;
    detail.endSwipe = endSwipe;
    detail.startEvent = this.startEvent;
    detail.currentEvent = this.currentEvent;
    detail.isComplex = this.isComplex;
    return detail;
  },

  /**
   * Reset all the values when swipe finished.
   */
  resetAll: function() {
    this.offset_x = 0;
    this.offset_y = 0;
    this.pre_x = 0;
    this.pre_y = 0;
    this.swipeFlags = 0;
    this.swipeDirection = 0;
    this.swipeIndex = 0;
    this.startEvent = undefined;
    this.currentEvent = undefined;
    this.isComplex = false;
  },

  /**
   * Updates the swipe path with the current event.
   * @param {Object} event The PointerEvent that triggered this update.
   * @return {boolean} Whether or not to notify swipe observers.
   */
  update: function(event) {
    if(!event.isPrimary)
      return false;
    // Update priors.
    this.offset_x += event.screenX - this.pre_x;
    this.offset_y += event.screenY - this.pre_y;
    this.pre_x = event.screenX;
    this.pre_y = event.screenY;

    // Check if movement crosses minimum thresholds in each direction.
    var direction = this.getOffsetDirection();
    if (direction == 0)
      return false;
    // If swipeIndex is zero the current event is triggering the swipe.
    if (this.swipeIndex == 0) {
      this.startEvent = event;
    } else if (direction != this.swipeDirection) {
      // Toggle the isComplex flag.
      this.isComplex = true;
    }
    // Update the swipe tracker.
    this.swipeDirection = direction;
    this.offset_x = 0;
    this.offset_y = 0;
    this.currentEvent = event;
    this.swipeIndex++;
    return true;
  },

};

Polymer('kb-keyboard', {
  alt: null,
  config: null,
  control: null,
  dblDetail_: null,
  dblTimer_: null,
  inputType: null,
  lastPressedKey: null,
  shift: null,
  sounds: {},
  stale: true,
  swipeHandler: null,
  voiceInput_: null,
  //TODO(rsadam@): Add a control to let users change this.
  volume: DEFAULT_VOLUME,

  /**
   * The default input type to keyboard layout map. The key must be one of
   * the input box type values.
   * @type {object}
   */
  inputTypeToLayoutMap: {
    number: "numeric",
    text: "qwerty",
    password: "qwerty"
  },

  /**
   * Caches the specified sound on the keyboard.
   * @param {string} soundId The name of the .wav file in the "sounds"
       directory.
   */
  addSound: function(soundId) {
    // Check if already loaded.
    if (soundId == Sound.NONE || this.sounds[soundId])
      return;
    var pool = [];
    for (var i = 0; i < SOUND_POOL_SIZE; i++) {
      var audio = document.createElement('audio');
      audio.preload = "auto";
      audio.id = soundId;
      audio.src = "../sounds/" + soundId + ".wav";
      audio.volume = this.volume;
      pool.push(audio);
    }
    this.sounds[soundId] = pool;
  },

  /**
   * Changes the current keyset.
   * @param {Object} detail The detail of the event that called this
   *     function.
   */
  changeKeyset: function(detail) {
    if (detail.relegateToShift && this.shift) {
      this.keyset = this.shift.textKeyset;
      this.activeKeyset.nextKeyset = undefined;
      return true;
    }
    var toKeyset = detail.toKeyset;
    if (toKeyset) {
      this.keyset = toKeyset;
      this.activeKeyset.nextKeyset = detail.nextKeyset;
      return true;
    }
    return false;
  },

  keysetChanged: function() {
    var keyset = this.activeKeyset;
    // Show the keyset if it has been initialized.
    if (keyset)
      keyset.show();
  },

  configChanged: function() {
    this.layout = this.config.layout;
  },

  ready: function() {
    this.voiceInput_ = new VoiceInput(this);
    this.swipeHandler = this.move.bind(this);
    var self = this;
    getKeyboardConfig(function(config) {
      self.config = config;
    });
  },

  /**
   * Registers a callback for state change events.
   * @param{!Function} callback Callback function to register.
   */
  addKeysetChangedObserver: function(callback) {
    this.addEventListener('stateChange', callback);
  },

  /**
   * Called when the type of focused input box changes. If a keyboard layout
   * is defined for the current input type, that layout will be loaded.
   * Otherwise, the keyboard layout for 'text' type will be loaded.
   */
  inputTypeChanged: function() {
    // Disable layout switching at accessbility mode.
    if (this.config && this.config.a11ymode)
      return;

    // TODO(bshe): Toggle visibility of some keys in a keyboard layout
    // according to the input type.
    var layout = this.inputTypeToLayoutMap[this.inputType];
    if (!layout)
      layout = this.inputTypeToLayoutMap.text;
    this.layout = layout;
  },

  /**
   * When double click/tap event is enabled, the second key-down and key-up
   * events on the same key should be skipped. Return true when the event
   * with |detail| should be skipped.
   * @param {Object} detail The detail of key-up or key-down event.
   */
  skipEvent: function(detail) {
    if (this.dblDetail_) {
      if (this.dblDetail_.char != detail.char) {
        // The second key down is not on the same key. Double click/tap
        // should be ignored.
        this.dblDetail_ = null;
        clearTimeout(this.dblTimer_);
      } else if (this.dblDetail_.clickCount == 1) {
        return true;
      }
    }
    return false;
  },

  /**
   * Handles a swipe update.
   * param {Object} detail The swipe update details.
   */
  onSwipeUpdate: function(detail) {
    var direction = detail.direction;
    if (!direction)
      console.error("Swipe direction cannot be: " + direction);
    // Triggers swipe editting if it's a purely horizontal swipe.
    if (!(direction & (SwipeDirection.UP | SwipeDirection.DOWN))) {
      // Nothing to do if the swipe has ended.
      if (detail.endSwipe)
        return;
      var modifiers = 0;
      // TODO (rsadam): This doesn't take into account index shifts caused
      // by vertical swipes.
      if (detail.index % 2 != 0) {
        modifiers |= Modifier.SHIFT;
        modifiers |= Modifier.CONTROL;
      }
      MoveCursor(direction, modifiers);
      return;
    }
    // Triggers swipe hintText if it's a purely vertical swipe.
    if (this.activeKeyset.flick &&
        !(direction & (SwipeDirection.LEFT | SwipeDirection.RIGHT))) {
      // Check if event is relevant to us.
      if ((!detail.endSwipe) || (detail.isComplex))
        return;
      // Too long a swipe.
      var distance = Math.abs(detail.startEvent.screenY -
          detail.currentEvent.screenY);
      if (distance > MAX_SWIPE_FLICK_DIST)
        return;
      var triggerKey = detail.startEvent.target;
      if (triggerKey && triggerKey.onFlick)
        triggerKey.onFlick(detail);
    }
  },

  /**
   * This function is bound to swipeHandler. Updates the current swipe
   * status so that PointerEvents can be converted to Swipe events.
   * @param {PointerEvent} event.
   */
  move: function(event) {
    if (!swipeTracker.update(event))
      return;
    // Conversion was successful, swipe is now in progress.
    swipeInProgress = true;
    if (this.lastPressedKey) {
      this.lastPressedKey.classList.remove('active');
      this.lastPressedKey = null;
    }
    this.onSwipeUpdate(swipeTracker.populateDetails(false));
  },

  /**
   * Handles key-down event that is sent by kb-key-base.
   * @param {CustomEvent} event The key-down event dispatched by
   *     kb-key-base.
   * @param {Object} detail The detail of pressed kb-key.
   */
  keyDown: function(event, detail) {
    if (this.skipEvent(detail))
      return;

    if (this.lastPressedKey) {
      this.lastPressedKey.classList.remove('active');
      this.lastPressedKey.autoRelease();
    }
    this.lastPressedKey = event.target;
    this.lastPressedKey.classList.add('active');
    repeatKey.cancel();
    this.playSound(detail.sound);

    var char = detail.char;
    switch(char) {
      case 'Shift':
        this.classList.remove('caps-locked');
        break;
      case 'Alt':
      case 'Ctrl':
        var modifier = char.toLowerCase() + "-active";
        // Removes modifier if already active.
        if (this.classList.contains(modifier))
          this.classList.remove(modifier);
        break;
      case 'Invalid':
        // Not all Invalid keys are transition keys. Reset control keys if
        // we pressed a transition key.
        if (event.target.toKeyset || detail.relegateToShift)
          this.onNonControlKeyTyped();
        break;
      default:
        // Notify shift key.
        if (this.shift)
          this.shift.onNonControlKeyDown();
        if (this.ctrl)
          this.ctrl.onNonControlKeyDown();
        if (this.alt)
          this.alt.onNonControlKeyDown();
        break;
    }
    if(this.changeKeyset(detail))
      return;
    if (detail.repeat) {
      this.keyTyped(detail);
      this.onNonControlKeyTyped();
      repeatKey.key = this.lastPressedKey;
      var self = this;
      repeatKey.timer = setTimeout(function() {
        repeatKey.timer = undefined;
        repeatKey.interval = setInterval(function() {
           self.playSound(detail.sound);
           self.keyTyped(detail);
        }, REPEAT_INTERVAL_MSEC);
      }, Math.max(0, REPEAT_DELAY_MSEC - REPEAT_INTERVAL_MSEC));
    }
  },

  /**
   * Handles key-out event that is sent by kb-shift-key.
   * @param {CustomEvent} event The key-out event dispatched by
   *     kb-shift-key.
   * @param {Object} detail The detail of pressed kb-shift-key.
   */
  keyOut: function(event, detail) {
    this.changeKeyset(detail);
  },

  /**
   * Enable/start double click/tap event recognition.
   * @param {CustomEvent} event The enable-dbl event dispatched by
   *     kb-shift-key.
   * @param {Object} detail The detail of pressed kb-shift-key.
   */
  enableDbl: function(event, detail) {
    if (!this.dblDetail_) {
      this.dblDetail_ = detail;
      this.dblDetail_.clickCount = 0;
      var self = this;
      this.dblTimer_ = setTimeout(function() {
        self.dblDetail_.callback = null;
        self.dblDetail_ = null;
      }, DBL_INTERVAL_MSEC);
    }
  },

  /**
   * Enable the selection while swipe.
   * @param {CustomEvent} event The enable-dbl event dispatched by
   *    kb-shift-key.
   */
  enableSel: function(event) {
    // TODO(rsadam): Disabled for now. May come back if we revert swipe
    // selection to not do word selection.
  },

  /**
   * Handles pointerdown event. This is used for swipe selection process.
   * to get the start pre_x and pre_y. And also add a pointermove handler
   * to start handling the swipe selection event.
   * @param {PointerEvent} event The pointerup event that received by
   *     kb-keyboard.
   */
  down: function(event) {
    var layout = getKeysetLayout(this.activeKeysetId);
    var key = layout.findClosestKey(event.clientX, event.clientY);
    if (key)
      key.down(event);
    if (event.isPrimary) {
      swipeTracker.pre_x = event.screenX;
      swipeTracker.pre_y = event.screenY;
      this.addEventListener("pointermove", this.swipeHandler, false);
    }
  },

  /**
   * Handles pointerup event. This is used for double tap/click events.
   * @param {PointerEvent} event The pointerup event that bubbled to
   *     kb-keyboard.
   */
  up: function(event) {
    var layout = getKeysetLayout(this.activeKeysetId);
    var key = layout.findClosestKey(event.clientX, event.clientY);
    if (key)
      key.up(event);
    // When touch typing, it is very possible that finger moves slightly out
    // of the key area before releases. The key should not be dropped in
    // this case.
    // TODO(rsadam@) Change behaviour such that the key drops and the second
    // key gets pressed.
    if (this.lastPressedKey &&
        this.lastPressedKey.pointerId == event.pointerId) {
      this.lastPressedKey.autoRelease();
    }

    if (this.dblDetail_) {
      this.dblDetail_.clickCount++;
      if (this.dblDetail_.clickCount == 2) {
        this.dblDetail_.callback();
        this.changeKeyset(this.dblDetail_);
        clearTimeout(this.dblTimer_);

        this.classList.add('caps-locked');

        this.dblDetail_ = null;
      }
    }

    // TODO(zyaozhujun): There are some edge cases to deal with later.
    // (for instance, what if a second finger trigger a down and up
    // event sequence while swiping).
    // When pointer up from the screen, a swipe selection session finished,
    // all the data should be reset to prepare for the next session.
    if (event.isPrimary && swipeInProgress) {
      swipeInProgress = false;
      this.onSwipeUpdate(swipeTracker.populateDetails(true))
      swipeTracker.resetAll();
    }
    this.removeEventListener('pointermove', this.swipeHandler, false);
  },

  /**
   * Handles PointerOut event. This is used for when a swipe gesture goes
   * outside of the keyboard window.
   * @param {Object} event The pointerout event that bubbled to the
   *    kb-keyboard.
   */
  out: function(event) {
    repeatKey.cancel();
    // Ignore if triggered from one of the keys.
    if (this.compareDocumentPosition(event.relatedTarget) &
        Node.DOCUMENT_POSITION_CONTAINED_BY)
      return;
    if (swipeInProgress)
      this.onSwipeUpdate(swipeTracker.populateDetails(true))
    // Touched outside of the keyboard area, so disables swipe.
    swipeInProgress = false;
    swipeTracker.resetAll();
    this.removeEventListener('pointermove', this.swipeHandler, false);
  },

  /**
   * Handles a TypeKey event. This is used for when we programmatically
   * want to type a specific key.
   * @param {CustomEvent} event The TypeKey event that bubbled to the
   *    kb-keyboard.
   */
  type: function(event) {
    this.keyTyped(event.detail);
  },

  /**
   * Handles key-up event that is sent by kb-key-base.
   * @param {CustomEvent} event The key-up event dispatched by kb-key-base.
   * @param {Object} detail The detail of pressed kb-key.
   */
  keyUp: function(event, detail) {
    if (this.skipEvent(detail))
      return;
    if (swipeInProgress)
      return;
    if (detail.activeModifier) {
      var modifier = detail.activeModifier.toLowerCase() + "-active";
      this.classList.add(modifier);
    }
    // Adds the current keyboard modifiers to the detail.
    if (this.ctrl)
      detail.controlModifier = this.ctrl.isActive();
    if (this.alt)
      detail.altModifier = this.alt.isActive();
    if (this.lastPressedKey)
      this.lastPressedKey.classList.remove('active');
    // Keyset transition key. This is needed to transition from upper
    // to lower case when we are not in caps mode, as well as when
    // we're ending chording.
    this.changeKeyset(detail);

    if (this.lastPressedKey &&
        this.lastPressedKey.charValue != event.target.charValue) {
      return;
    }
    if (repeatKey.key == event.target) {
      repeatKey.cancel();
      this.lastPressedKey = null;
      return;
    }
    var toLayoutId = detail.toLayout;
    // Layout transition key.
    if (toLayoutId)
      this.layout = toLayoutId;
    var char = detail.char;
    this.lastPressedKey = null;
    // Characters that should not be typed.
    switch(char) {
      case 'Invalid':
      case 'Shift':
      case 'Ctrl':
      case 'Alt':
        enterUpperOnSpace = false;
        swipeTracker.swipeFlags = 0;
        return;
      case 'Microphone':
        this.voiceInput_.onDown();
        return;
      default:
        break;
    }
    // Tries to type the character. Resorts to insertText if that fails.
    if(!this.keyTyped(detail))
      insertText(char);
    // Post-typing logic.
    switch(char) {
      case '\n':
      case ' ':
        if(enterUpperOnSpace) {
          enterUpperOnSpace = false;
          if (this.shift) {
            var shiftDetail = this.shift.onSpaceAfterPunctuation();
            // Check if transition defined.
            this.changeKeyset(shiftDetail);
          } else {
            console.error('Capitalization on space after punctuation \
                        enabled, but cannot find target keyset.');
          }
          // Immediately return to maintain shift-state. Space is a
          // non-control key and would otherwise trigger a reset of the
          // shift key, causing a transition to lower case.
          return;
        }
        break;
      case '.':
      case '?':
      case '!':
        enterUpperOnSpace = this.shouldUpperOnSpace();
        break;
      default:
        enterUpperOnSpace = false;
        break;
    }
    // Reset control keys.
    this.onNonControlKeyTyped();
  },

  /**
   * Handles key-longpress event that is sent by kb-key-base.
   * @param {CustomEvent} event The key-longpress event dispatched by
   *     kb-key-base.
   * @param {Object} detail The detail of pressed key.
   */
  keyLongpress: function(event, detail) {
    // If the gesture is long press, remove the pointermove listener.
    this.removeEventListener('pointermove', this.swipeHandler, false);
    // Keyset transtion key.
    if (this.changeKeyset(detail)) {
      // Locks the keyset before removing active to prevent flicker.
      this.classList.add('caps-locked');
      // Makes last pressed key inactive if transit to a new keyset on long
      // press.
      if (this.lastPressedKey)
        this.lastPressedKey.classList.remove('active');
    }
  },

  /**
   * Plays the specified sound.
   * @param {Sound} sound The id of the audio tag.
   */
  playSound: function(sound) {
    if (!SOUND_ENABLED || !sound || sound == Sound.NONE)
      return;
    var pool = this.sounds[sound];
    if (!pool) {
      console.error("Cannot find audio tag: " + sound);
      return;
    }
    // Search the sound pool for a free resource.
    for (var i = 0; i < pool.length; i++) {
      if (pool[i].paused) {
        pool[i].play();
        return;
      }
    }
  },

  /**
   * Whether we should transit to upper case when seeing a space after
   * punctuation.
   * @return {boolean}
   */
  shouldUpperOnSpace: function() {
    // TODO(rsadam): Add other input types in which we should not
    // transition to upper after a space.
    return this.inputTypeValue != 'password';
  },

  /**
   * Handler for the 'set-layout' event.
   * @param {!Event} event The triggering event.
   * @param {{layout: string}} details Details of the event, which contains
   *     the name of the layout to activate.
   */
  setLayout: function(event, details) {
    this.layout = details.layout;
  },

  /**
   * Handles a change in the keyboard layout. Auto-selects the default
   * keyset for the new layout.
   */
  layoutChanged: function() {
    this.stale = true;
    if (!this.selectDefaultKeyset()) {
      console.error('No default keyset found for layout: ' + this.layout);
      return;
    }
    this.activeKeyset.show();
  },

  /**
   * Notifies the modifier keys that a non-control key was typed. This
   * lets them reset sticky behaviour. A non-control key is defined as
   * any key that is not Control, Alt, or Shift.
   */
  onNonControlKeyTyped: function() {
    if (this.shift)
      this.shift.onNonControlKeyTyped();
    if (this.ctrl)
      this.ctrl.onNonControlKeyTyped();
    if (this.alt)
      this.alt.onNonControlKeyTyped();
    this.classList.remove('ctrl-active');
    this.classList.remove('alt-active');
  },

  /**
   * Callback function for when volume is changed.
   */
  volumeChanged: function() {
    var toChange = Object.keys(this.sounds);
    for (var i = 0; i < toChange.length; i++) {
      var pool = this.sounds[toChange[i]];
      for (var j = 0; j < pool.length; j++) {
        pool[j].volume = this.volume;
      }
    }
  },

  /**
   * Id for the active keyset.
   * @type {string}
   */
  get activeKeysetId() {
    return this.layout + '-' + this.keyset;
  },

  /**
   * The active keyset DOM object.
   * @type {kb-keyset}
   */
  get activeKeyset() {
    return this.querySelector('#' + this.activeKeysetId);
  },

  /**
   * The current input type.
   * @type {string}
   */
  get inputTypeValue() {
    return this.inputType;
  },

  /**
   * Changes the input type if it's different from the current
   * type, else resets the keyset to the default keyset.
   * @type {string}
   */
  set inputTypeValue(value) {
    if (value == this.inputType)
      this.selectDefaultKeyset();
    else
      this.inputType = value;
  },

  /**
   * The keyboard is ready for input once the target keyset appears
   * in the distributed nodes for the keyboard.
   * @return {boolean} Indicates if the keyboard is ready for input.
   */
  isReady: function() {
    var keyset =  this.activeKeyset;
    if (!keyset)
      return false;
    var nodes = this.$.content.getDistributedNodes();
    for (var i = 0; i < nodes.length; i++) {
      if (nodes[i].id && nodes[i].id == keyset.id)
        return true;
    }
    return false;
  },

  /**
   * Generates fabricated key events to simulate typing on a
   * physical keyboard.
   * @param {Object} detail Attributes of the key being typed.
   * @return {boolean} Whether the key type succeeded.
   */
  keyTyped: function(detail) {
    var builder = this.$.keyCodeMetadata;
    if (this.ctrl)
      detail.controlModifier = this.ctrl.isActive();
    if (this.alt)
      detail.altModifier = this.alt.isActive();
    var downEvent = builder.createVirtualKeyEvent(detail, "keydown");
    if (downEvent) {
      sendKeyEvent(downEvent);
      sendKeyEvent(builder.createVirtualKeyEvent(detail, "keyup"));
      return true;
    }
    return false;
  },

  /**
   * Selects the default keyset for a layout.
   * @return {boolean} True if successful. This method can fail if the
   *     keysets corresponding to the layout have not been injected.
   */
  selectDefaultKeyset: function() {
    var keysets = this.querySelectorAll('kb-keyset');
    // Full name of the keyset is of the form 'layout-keyset'.
    var regex = new RegExp('^' + this.layout + '-(.+)');
    var keysetsLoaded = false;
    for (var i = 0; i < keysets.length; i++) {
      var matches = keysets[i].id.match(regex);
      if (matches && matches.length == REGEX_MATCH_COUNT) {
         keysetsLoaded = true;
         // Without both tests for a default keyset, it is possible to get
         // into a state where multiple layouts are displayed.  A
         // reproducable test case is do the following set of keyset
         // transitions: qwerty -> system -> dvorak -> qwerty.
         // TODO(kevers): Investigate why this is the case.
         if (keysets[i].isDefault ||
             keysets[i].getAttribute('isDefault') == 'true') {
           this.keyset = matches[REGEX_KEYSET_INDEX];
           this.classList.remove('caps-locked');
           this.classList.remove('alt-active');
           this.classList.remove('ctrl-active');
           // Caches shift key.
           this.shift = this.querySelector('kb-shift-key');
           if (this.shift)
             this.shift.reset();
           // Caches control key.
           this.ctrl = this.querySelector('kb-modifier-key[char=Ctrl]');
           if (this.ctrl)
             this.ctrl.reset();
           // Caches alt key.
           this.alt = this.querySelector('kb-modifier-key[char=Alt]');
           if (this.alt)
             this.alt.reset();
           this.fire('stateChange', {
             state: 'keysetLoaded',
             value: this.keyset,
           });
           keyboardLoaded();
           return true;
         }
      }
    }
    if (keysetsLoaded)
      console.error('No default keyset found for ' + this.layout);
    return false;
  }
});
