// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/**
 * @fileoverview This file contains NaclMozc class implementation.
 *
 * NaclMozc class provides Japanese input method for Chrome OS. The main logic
 * of Japanese conversion is written in C++ and is executed in NaCl environment.
 * This class communicate with the NaCl module using JSON message and provides
 * Japanese input method using IME extension API (chrome.input.ime).
 *
 */

'use strict';

/**
 * Namespace for this extension.
 * @suppress {const|duplicate}
 */
var mozc = window.mozc || {};

/**
 * The candidate window size.
 * @private {number}
 */
mozc.CANDIDATE_WINDOW_PAGE_SIZE_ = 9;

/**
 * Enum of preedit method.
 * This is same as mozc.commands.Output.PreeditMethod in command.proto.
 * @enum {string}
 * @private
 */
mozc.PreeditMethod_ = {
  ROMAN: 'ROMAN',
  KANA: 'KANA'
};

/**
 * Enum of composition mode.
 * This is same as mozc.commands.CompositionMode in command.proto.
 * @enum {string}
 * @private
 */
mozc.CompositionMode_ = {
  DIRECT: 'DIRECT',
  HIRAGANA: 'HIRAGANA',
  FULL_KATAKANA: 'FULL_KATAKANA',
  HALF_ASCII: 'HALF_ASCII',
  FULL_ASCII: 'FULL_ASCII',
  HALF_KATAKANA: 'HALF_KATAKANA'
};

/**
 * Enum of menu item IDs.
 * @enum {string}
 * @private
 */
mozc.MenuItemId_ = {
  MENU_COMPOSITION_HIRAGANA: 'MENU_COMPOSITION_HIRAGANA',
  MENU_COMPOSITION_FULL_KATAKANA: 'MENU_COMPOSITION_FULL_KATAKANA',
  MENU_COMPOSITION_FULL_ASCII: 'MENU_COMPOSITION_FULL_ASCII',
  MENU_COMPOSITION_HALF_KATAKANA: 'MENU_COMPOSITION_HALF_KATAKANA',
  MENU_COMPOSITION_HALF_ASCII: 'MENU_COMPOSITION_HALF_ASCII',
  MENU_COMPOSITION_DIRECT: 'MENU_COMPOSITION_DIRECT'
};

/**
 * Composition menu table.
 * @const
 * @private {!Array.<{menu: mozc.MenuItemId_,
 *                    mode: mozc.CompositionMode_,
 *                    labelId: string}>}
 */
mozc.COMPOSITION_MENU_TABLE_ = [
  {
    menu: mozc.MenuItemId_.MENU_COMPOSITION_HIRAGANA,
    mode: mozc.CompositionMode_.HIRAGANA,
    labelId: 'compositionModeHiragana'
  },
  {
    menu: mozc.MenuItemId_.MENU_COMPOSITION_FULL_KATAKANA,
    mode: mozc.CompositionMode_.FULL_KATAKANA,
    labelId: 'compositionModeFullKatakana'
  },
  {
    menu: mozc.MenuItemId_.MENU_COMPOSITION_FULL_ASCII,
    mode: mozc.CompositionMode_.FULL_ASCII,
    labelId: 'compositionModeFullAscii'
  },
  {
    menu: mozc.MenuItemId_.MENU_COMPOSITION_HALF_KATAKANA,
    mode: mozc.CompositionMode_.HALF_KATAKANA,
    labelId: 'compositionModeHalfKatakana'
  },
  {
    menu: mozc.MenuItemId_.MENU_COMPOSITION_HALF_ASCII,
    mode: mozc.CompositionMode_.HALF_ASCII,
    labelId: 'compositionModeHalfAscii'
  },
  {
    menu: mozc.MenuItemId_.MENU_COMPOSITION_DIRECT,
    mode: mozc.CompositionMode_.DIRECT,
    labelId: 'compositionModeDirect'
  }
];


/**
 * NaclMozc with IME extension API.
 * @param {!HTMLElement} naclModule DOM Element of NaCl module.
 * @constructor
 * @struct
 * @const
 */
mozc.NaclMozc = function(naclModule) {
  /**
   * Context information which is provided by Chrome.
   * @private {InputContext}
   */
  this.context_ = null;

  /**
   * Session id of Mozc's session. This id is handled as uint64 in NaCl. But
   * JavaScript can't handle uint64. So we handle it as string in JavaScript.
   * @private {string}
   */
  this.sessionID_ = '';

  /**
   * The list of candidates.
   * This data structure is same as the 2nd argument of
   * chrome.input.ime.setCandidates().
   * @private {!Array.<{candidate: string,
   *                    id: number,
   *                    label: string,
   *                    annotation: string,
   *                    usage: {title: string, body: string}}>}
   */
  this.candidates_ = [];

  /**
   * The candidate window properties.
   * @private {!Object.<string, *>}
   */
  this.candidateWindowProperties_ = {};

  /**
   * Array of callback functions.
   * Callbacks are added in postMessage_ and removed in onModuleMessage_.
   * @private {!Array.<function(!mozc.Command)|function(!mozc.Event)|undefined>}
   */
  this.naclMessageCallbacks_ = [];

  /**
   * Array of callback functions which will be called when NaCl Mozc will be
   *     initialized.
   * @private {!Array.<function()|undefined>}
   */
  this.initializationCallbacks_ = [];

  /**
   * Keyboard layout. 'us' and 'jp' are supported.
   * @private {string}
   */
  this.keyboardLayout_ = 'us';

  /**
   * Preedit method.
   * @private {mozc.PreeditMethod_}
   */
  this.preeditMethod_ = mozc.PreeditMethod_.ROMAN;

  /**
   * Composition mode.
   * @private {mozc.CompositionMode_}
   */
  this.compositionMode_ = mozc.CompositionMode_.HIRAGANA;

  /**
   * Whether the NaCl module has been initialized or not.
   * @private {boolean}
   */
  this.isNaclInitialized_ = false;

  /**
   * Whether the JavaScript side code is handling an event or not.
   * @private {boolean}
   */
  this.isHandlingEvent_ = false;

  /**
   * Array of waiting event handlers.
   * @private {!Array.<function()>}
   */
  this.waitingEventHandlers_ = [];

  /**
   * Engine id which is passed from IME Extension API.
   * @private {string}
   */
  this.engine_id_ = '';

  /**
   * Key event translator.
   * @private {!mozc.KeyTranslator}
   */
  this.keyTranslator_ = new mozc.KeyTranslator();

  /**
   * callbackCommand_ stores the callback message which is recieved from NaCl
   * module. This callback will be cancelled when the user presses the
   * subsequent key. In the current implementation, if the subsequent key event
   * also makes callback, the second callback will be called in the timimg of
   * the first callback.
   * @private {!mozc.Callback}
   */
  this.callbackCommand_ = /** @type {!mozc.Callback} */ ({});

  /**
   * The surrounding information.
   * @private {Object.<{text: string, focus: number, anchor: number}>}
   */
  this.surroundingInfo_ = null;

  /**
   * DOM Element of NaCl module.
   * @private {!HTMLElement}
   */
  this.naclModule_ = naclModule;
  this.naclModule_.addEventListener(
      'load', this.onModuleLoad_.bind(this), true);
  this.naclModule_.addEventListener(
      'message', this.onModuleMessage_.bind(this), true);
  this.naclModule_.addEventListener(
      'progress', this.onModuleProgress_.bind(this), true);
  this.naclModule_.addEventListener(
      'error', this.onModuleError_.bind(this), true);

  // Registers event handlers.
  chrome.input.ime.onActivate.addListener(
      this.wrapAsyncHandler_(this.onActivate_));
  chrome.input.ime.onDeactivated.addListener(
      this.wrapAsyncHandler_(this.onDeactivated_));
  chrome.input.ime.onFocus.addListener(
      this.wrapAsyncHandler_(this.onFocus_));
  chrome.input.ime.onBlur.addListener(
      this.wrapAsyncHandler_(this.onBlur_));
  chrome.input.ime.onInputContextUpdate.addListener(
      this.wrapAsyncHandler_(this.onInputContextUpdate_));
  chrome.input.ime.onKeyEvent.addListener(
      this.wrapAsyncHandler_(this.onKeyEventAsync_), ['async']);
  chrome.input.ime.onCandidateClicked.addListener(
      this.wrapAsyncHandler_(this.onCandidateClicked_));
  chrome.input.ime.onMenuItemActivated.addListener(
      this.wrapAsyncHandler_(this.onMenuItemActivated_));
  // chrome.input.ime.onSurroundingTextChanged is available from ChromeOS 27.
  if (chrome.input.ime.onSurroundingTextChanged) {
    chrome.input.ime.onSurroundingTextChanged.addListener(
        this.wrapAsyncHandler_(this.onSurroundingTextChanged_));
  }
  // chrome.input.ime.onReset is available from ChromeOS 29.
  if (chrome.input.ime.onReset) {
    chrome.input.ime.onReset.addListener(this.wrapAsyncHandler_(this.onReset_));
  }
};

/**
 * Calls the callback when NaCl Mozc is initialized
 * @param {function()} callback Function to be called when NaCl Mozc is
 *     initialized.
 */
mozc.NaclMozc.prototype.callWhenInitialized = function(callback) {
  if (this.isNaclInitialized_) {
    callback();
    return;
  }
  this.initializationCallbacks_.push(callback);
};

/**
 * Creates a mozc.Command object with the specified input type.
 * @param {string} type Input type of mozc.Command object.
 * @return {!mozc.Command} Created mozc.Command.
 * @private
 */
mozc.NaclMozc.prototype.createMozcCommand_ = function(type) {
  return /** @type {!mozc.Command} */ ({'input': {'type': type}, 'output': {}});
};

/**
 * Creates a mozc.Event object with the specified type.
 * @param {string} type Type of mozc.Event object.
 * @return {!mozc.Event} Created mozc.Event.
 * @private
 */
mozc.NaclMozc.prototype.createMozcEvent_ = function(type) {
  return /** @type {!mozc.Event} */ ({'type': type});
};

/**
 * Creates a mozc.SessionCommand object with the specified type.
 * @param {string} type Type of mozc.SessionCommand object.
 * @return {!mozc.SessionCommand} Created mozc.SessionCommand.
 * @private
 */
mozc.NaclMozc.prototype.createMozcSessionCommand_ = function(type) {
  return /** @type {!mozc.SessionCommand} */ ({'type': type});
};

/**
 * Sends RELOAD command to NaCl module.
 * @param {function(!mozc.Command)=} opt_callback Function to be called with
 *     results from NaCl module.
 */
mozc.NaclMozc.prototype.sendReload = function(opt_callback) {
  this.postMozcCommand_(this.createMozcCommand_('RELOAD'), opt_callback);
};

/**
 * Sends GET_CONFIG command to NaCl module.
 * @param {function(!mozc.Command)=} opt_callback Function to be called with
 *     results from NaCl module.
 */
mozc.NaclMozc.prototype.getConfig = function(opt_callback) {
  this.postMozcCommand_(this.createMozcCommand_('GET_CONFIG'), opt_callback);
};

/**
 * Sets config and sends SET_CONFIG command to NaCl module.
 * @param {!Object.<string,*>} config Config object to be set to.
 * @param {function(!mozc.Command)=} opt_callback Function to be called with
 *     results from NaCl module.
 */
mozc.NaclMozc.prototype.setConfig = function(config, opt_callback) {
  if (config['preedit_method']) {
    this.setPreeditMethod(
        /** @type {mozc.PreeditMethod_} */ (config['preedit_method']));
  }
  var mozcCommand = this.createMozcCommand_('SET_CONFIG');
  mozcCommand.input.config = config;
  this.postMozcCommand_(mozcCommand, opt_callback);
};

/**
 * Sends CLEAR_USER_HISTORY command to NaCl module.
 * @param {function(!mozc.Command)=} opt_callback Function to be called with
 *     results from NaCl module.
 */
mozc.NaclMozc.prototype.clearUserHistory = function(opt_callback) {
  this.postMozcCommand_(this.createMozcCommand_('CLEAR_USER_HISTORY'),
                        opt_callback);
};

/**
 * Sends CLEAR_USER_PREDICTION command to NaCl module.
 * @param {function(!mozc.Command)=} opt_callback Function to be called with
 *     results from NaCl module.
 */
mozc.NaclMozc.prototype.clearUserPrediction = function(opt_callback) {
  this.postMozcCommand_(this.createMozcCommand_('CLEAR_USER_PREDICTION'),
                        opt_callback);
};

/**
 * Sets preedit method
 * @param {mozc.PreeditMethod_} newMethod The new preedit method to be set to.
 */
mozc.NaclMozc.prototype.setPreeditMethod = function(newMethod) {
  for (var key in mozc.PreeditMethod_) {
    if (newMethod == mozc.PreeditMethod_[key]) {
      this.preeditMethod_ = mozc.PreeditMethod_[key];
      return;
    }
  }
  console.error('Preedit method ' + newMethod + ' is not supported.');
};

/**
 * Sends SEND_USER_DICTIONARY_COMMAND command to NaCl module.
 * @param {!mozc.UserDictionaryCommand} command User dictionary command object
 *    to be sent.
 * @param {function(!mozc.UserDictionaryCommandStatus)=} opt_callback Function
 *     to be called with results from NaCl module.
 */
mozc.NaclMozc.prototype.sendUserDictionaryCommand = function(command,
                                                             opt_callback) {
  var mozcCommand = this.createMozcCommand_('SEND_USER_DICTIONARY_COMMAND');
  mozcCommand.input.user_dictionary_command = command;
  this.postMozcCommand_(
      mozcCommand,
      opt_callback ?
          /**
          * @this {!mozc.NaclMozc}
          * @param {function(!mozc.UserDictionaryCommandStatus)} callback
          * @param {!mozc.Command} response
          */
          (function(callback, response) {
            if (response.output.user_dictionary_command_status == undefined) {
              console.log('sendUserDictionaryCommand error');
              return;
            }
            callback(response.output.user_dictionary_command_status);
          }).bind(this, opt_callback) :
          undefined);
};

/**
 * Gets the version information of NaCl Mozc module.
 * @param {function(!mozc.Event)} callback Function to be called with results
 *     from NaCl module.
 */
mozc.NaclMozc.prototype.getVersionInfo = function(callback) {
  this.postNaclMozcEvent_(this.createMozcEvent_('GetVersionInfo'), callback);
};

/**
 * Gets POS list from NaCl Mozc module.
 * @param {function(!mozc.Event)} callback Function to be called with results
 *     from NaCl module.
 */
mozc.NaclMozc.prototype.getPosList = function(callback) {
  this.postNaclMozcEvent_(this.createMozcEvent_('GetPosList'), callback);
};

/**
 * Check if all characters in the given string is a legitimate character
 * for reading.
 * @param {string} text The string to check.
 * @param {function(!mozc.Event)} callback Function to be called with results
 *     from NaCl module.
 */
mozc.NaclMozc.prototype.isValidReading = function(text, callback) {
  var event = this.createMozcEvent_('IsValidReading');
  event.data = text;
  this.postNaclMozcEvent_(event, callback);
};

/**
 * Sends callback command to NaCl module.
 * @param {function(!mozc.Command)=} opt_callback Function to be called with
 *     results from NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.sendCallbackCommand_ = function(opt_callback) {
  if (!this.sessionID_) {
    console.error('Session has not been created.');
    return;
  }
  if (!this.callbackCommand_.session_command) {
    return;
  }
  var command = this.callbackCommand_.session_command;
  if (command.type == 'CONVERT_REVERSE' && this.surroundingInfo_) {
    if (this.surroundingInfo_.focus < this.surroundingInfo_.anchor) {
      command.text = this.surroundingInfo_.text.substring(
                         this.surroundingInfo_.focus,
                         this.surroundingInfo_.anchor);
    } else {
      command.text = this.surroundingInfo_.text.substring(
                         this.surroundingInfo_.anchor,
                         this.surroundingInfo_.focus);
    }
  }
  this.callbackCommand_ = /** @type {!mozc.Callback} */ ({});
  this.postMozcSessionCommand_(command, opt_callback);
};

/**
 * Wraps event handler to be able to managed by waitingEventHandlers_.
 * @param {!Function} handler Event handler.
 * @return {!Function} Wraped Event handler.
 * @private
 */
mozc.NaclMozc.prototype.wrapAsyncHandler_ = function(handler) {
  return (/**
          * @this {!mozc.NaclMozc}
          * @param {!Function} handler
          */
          (function(handler) {
            this.waitingEventHandlers_.push(
                Function.prototype.apply.bind(
                    handler,
                    this,
                    Array.prototype.slice.call(arguments, 1)));
            this.executeWatingEventHandlers_();
          })).bind(this, handler);
};

/**
 * Exexutes the waiting event handlers.
 * This function is used to prevent the event handlers from being executed while
 * the NaCl module is being initialized or another event handler is being
 * executed or waiting for the callback from the NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.executeWatingEventHandlers_ = function() {
  while (this.isNaclInitialized_ &&
         !this.isHandlingEvent_ &&
         !this.hasNaclMessageCallback_() &&
         this.waitingEventHandlers_.length != 0) {
    this.isHandlingEvent_ = true;
    this.waitingEventHandlers_.shift()();
    this.isHandlingEvent_ = false;
  }
};

/**
 * Returns true if naclMessageCallbacks_ has callback object.
 * @return {boolean} naclMessageCallbacks_ has callback object or not.
 * @private
 */
mozc.NaclMozc.prototype.hasNaclMessageCallback_ = function() {
  for (var callbackId in this.naclMessageCallbacks_) {
    return true;
  }
  return false;
};

/**
 * Posts a message to NaCl module.
 * @param {!mozc.Message} message Message object to be posted to NaCl module.
 * @param {!(function(!mozc.Command)|function(!mozc.Event))=} opt_callback
 *     Function to be called with results from NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.postMessage_ = function(message, opt_callback) {
  if (!this.isNaclInitialized_) {
    console.error('NaCl module is not initialized yet.');
    return;
  }
  var callbackId = 0;
  while (callbackId in this.naclMessageCallbacks_) {
    callbackId++;
  }
  this.naclMessageCallbacks_[callbackId] = opt_callback;
  message.id = callbackId;
  this.naclModule_['postMessage'](JSON.stringify(message));
};

/**
 * Posts a message which wraps the Mozc command to NaCl module.
 * @param {!mozc.Command} command Command object to be posted to NaCl module.
 * @param {function(!mozc.Command)=} opt_callback Function to be called with
 *     results from NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.postMozcCommand_ = function(command, opt_callback) {
  this.postMessage_(
      /** @type {!mozc.Message} */ ({'cmd': command}),
      opt_callback);
};

/**
 * Posts an event which is spesific to NaCl Mozc such as 'SyncToFile'.
 * @param {!mozc.Event} event Event object to be posted to NaCl module.
 * @param {function(!mozc.Event)=} opt_callback Function to be called with
 *     results from NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.postNaclMozcEvent_ = function(event, opt_callback) {
  this.postMessage_(
      /** @type {!mozc.Message} */ ({'event': event}),
      opt_callback);
};

/**
 * Posts a SessionCommand to NaCl module.
 * @param {!mozc.SessionCommand} sessionCommand SessionCommand object to be
 *    posted to NaCl module.
 * @param {function(!mozc.Command)=} opt_callback Function to be called with
 *     results from NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.postMozcSessionCommand_ = function(sessionCommand,
                                                           opt_callback) {
  var mozcCommand = this.createMozcCommand_('SEND_COMMAND');
  mozcCommand.input.id = this.sessionID_;
  mozcCommand.input.command = sessionCommand;
  this.postMozcCommand_(mozcCommand, opt_callback);
};

/**
 * Processes the response command from NaCl module.
 * @param {!mozc.Command} mozcCommand Response command object from NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.processResponse_ = function(mozcCommand) {
  if (!mozcCommand || !mozcCommand.output) {
    return;
  }
  if (mozcCommand.output.deletion_range) {
    // chrome.input.ime.deleteSurroundingText is available from ChromeOS 27.
    if (chrome.input.ime.deleteSurroundingText) {
      chrome.input.ime.deleteSurroundingText({
          'engineID': this.engine_id_,
          'contextID': this.context_.contextID,
          'offset': mozcCommand.output.deletion_range.offset,
          'length': mozcCommand.output.deletion_range.length
          },
          this.outputResponse_.bind(this, mozcCommand.output));
      return;
    }
  }
  this.outputResponse_(mozcCommand.output);
};

/**
 * Outputs the response command from NaCl module.
 * @param {!mozc.Output} output mozc.Output object from NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.outputResponse_ = function(output) {
  this.updatePreedit_(output.preedit);
  this.commitResult_(output.result);
  this.updateCandidates_(output.candidates);
  if (output.mode) {
    var new_mode = output.mode;
    if (this.compositionMode_ != new_mode) {
      this.compositionMode_ = /** @type {mozc.CompositionMode_} */ (new_mode);
      this.updateMenuItems_();
    }
  }
  if (output.callback) {
    this.callbackCommand_ = output.callback;
    if (this.callbackCommand_.delay_millisec) {
      window.setTimeout(
          this.sendCallbackCommand_.bind(
              this,
              this.processResponse_.bind(this)),
          this.callbackCommand_.delay_millisec);
    } else {
      this.sendCallbackCommand_(this.processResponse_.bind(this));
    }
  }
};

/**
 * Updates preedit composition.
 * @param {mozc.Preedit=} opt_mozcPreedit The preedit data passed from NaCl
 *     Mozc
 * module.
 * @private
 */
mozc.NaclMozc.prototype.updatePreedit_ = function(opt_mozcPreedit) {
  if (!opt_mozcPreedit) {
    chrome.input.ime.setComposition({
      'contextID': this.context_.contextID,
      'text': '',
      'cursor': 0
    });
    return;
  }

  var preeditString = '';
  var preeditSegments = [];

  for (var i = 0; i < opt_mozcPreedit.segment.length; ++i) {
    var segment = {
      'start': preeditString.length,
      'end': preeditString.length + opt_mozcPreedit.segment[i].value_length
    };
    if (opt_mozcPreedit.segment[i].annotation == 'UNDERLINE') {
      segment.style = 'underline';
    } else if (opt_mozcPreedit.segment[i].annotation == 'HIGHLIGHT') {
      segment.style = 'doubleUnderline';
    }
    preeditSegments.push(segment);
    preeditString += opt_mozcPreedit.segment[i].value;
  }

  // We do not use a cursor position obtained from Mozc. It is because the
  // cursor position is used to locate the candidate window.
  var cursor = 0;
  if (opt_mozcPreedit.highlighted_position != undefined) {
    cursor = opt_mozcPreedit.highlighted_position;
  } else if (opt_mozcPreedit.cursor != undefined) {
    cursor = opt_mozcPreedit.cursor;
  }

  chrome.input.ime.setComposition({
    'contextID': this.context_.contextID,
    'text': preeditString,
    'cursor': cursor,
    'segments': preeditSegments
  });
};

/**
 * Updates the candidate window properties.
 * This method calls chrome.input.ime.setCandidateWindowProperties() with
 * the properties which have been changed.
 * @param {!Object.<string, *>} properties The new properties.
 * @private
 */
mozc.NaclMozc.prototype.updateCandidateWindowProperties_ =
    function(properties) {
  var diffProperties = {};
  var propertyNames = ['cursorVisible',
                       'vertical',
                       'pageSize',
                       'auxiliaryTextVisible',
                       'auxiliaryText',
                       'visible',
                       'windowPosition'];
  var changed = false;

  for (var i = 0; i < propertyNames.length; ++i) {
    var name = propertyNames[i];
    if (this.candidateWindowProperties_[name] != properties[name]) {
      diffProperties[name] = properties[name];
      this.candidateWindowProperties_[name] = properties[name];
      changed = true;
    }
  }
  if (changed) {
    chrome.input.ime.setCandidateWindowProperties({
      'engineID': this.engine_id_,
      'properties': diffProperties
    });
  }
};

/**
 * Checks two objects are the same objects.
 * @param {!Object} object1 The first object to compare.
 * @param {!Object} object2 The second object to compare.
 * @return {boolean} Whether object1 and object2 are the same objects.
 * @private
 */
mozc.NaclMozc.prototype.compareObjects_ = function(object1, object2) {
  for (var key in object1) {
    if (typeof(object1[key]) != typeof(object2[key])) {
      return false;
    }
    if (object1[key]) {
      if (typeof(object1[key]) == 'object') {
        if (!this.compareObjects_(object1[key], object2[key])) {
          return false;
        }
      } else if (typeof(object1[key]) == 'function') {
        if (object1[key].toString() != object2[key].toString()) {
          return false;
        }
      } else {
        if (object1[key] !== object2[key]) {
          return false;
        }
      }
    } else {
      if (object1[key] !== object2[key]) {
        return false;
      }
    }
  }
  for (var key in object2) {
    if (typeof(object1[key]) == 'undefined' &&
        typeof(object2[key]) != 'undefined') {
      return false;
    }
  }
  return true;
};

/**
 * Updates the candidate window.
 * @param {mozc.Candidates=} opt_mozcCandidates The candidates data passed
 *     from NaCl Mozc module.
 * @private
 */
mozc.NaclMozc.prototype.updateCandidates_ = function(opt_mozcCandidates) {
  if (!opt_mozcCandidates) {
    this.updateCandidateWindowProperties_(
        {'visible': false, 'auxiliaryTextVisible': false});
    return;
  }

  var focusedID = null;
  var newCandidates = [];
  var candidatesIdMap = {};
  for (var i = 0; i < opt_mozcCandidates.candidate.length; ++i) {
    var item = opt_mozcCandidates.candidate[i];
    if (item.index == opt_mozcCandidates.focused_index) {
      focusedID = item.id;
    }
    var newCandidate = {
      'candidate': item.value,
      'id': item.id
    };
    if (item.annotation) {
      newCandidate.annotation = item.annotation.description;
      newCandidate.label = item.annotation.shortcut;
    }
    newCandidates.push(newCandidate);
    candidatesIdMap[item.id] = newCandidate;
  }
  if (opt_mozcCandidates.usages) {
    for (var i = 0; i < opt_mozcCandidates.usages.information.length;
          ++i) {
      var usage = opt_mozcCandidates.usages.information[i];
      for (var j = 0; j < usage.candidate_id.length; ++j) {
        if (candidatesIdMap[usage.candidate_id[j]]) {
          candidatesIdMap[usage.candidate_id[j]].usage = {
            'title': usage.title,
            'body': usage.description
          };
        }
      }
    }
  }
  if (!this.compareObjects_(this.candidates_, newCandidates)) {
    // Calls chrome.input.ime.setCandidates() if the candidates has changed.
    chrome.input.ime.setCandidates({
      'contextID': this.context_.contextID,
      'candidates': newCandidates
    });
    this.candidates_ = newCandidates;
  }

  // We have to call setCursorPosition even if there is no focused candidate.
  // This is because the last set cusor position will be used to scroll the page
  // of the candidates if we don't set.
  chrome.input.ime.setCursorPosition({
    'contextID': this.context_.contextID,
    'candidateID': (focusedID != null) ? focusedID : 0});

  var auxiliaryText = '';
  if (opt_mozcCandidates.footer) {
    if (opt_mozcCandidates.footer.label != undefined) {
      auxiliaryText = opt_mozcCandidates.footer.label;
    } else if (opt_mozcCandidates.footer.sub_label != undefined) {
      auxiliaryText = opt_mozcCandidates.footer.sub_label;
    }
    if (opt_mozcCandidates.footer.index_visible &&
        opt_mozcCandidates.focused_index != undefined) {
      if (auxiliaryText.length != 0) {
        auxiliaryText += ' ';
      }
      auxiliaryText += (opt_mozcCandidates.focused_index + 1) + '/' +
                       opt_mozcCandidates.size;
    }
  }

  var pageSize = mozc.CANDIDATE_WINDOW_PAGE_SIZE_;
  if (opt_mozcCandidates.category == 'SUGGESTION') {
    pageSize = Math.min(pageSize,
                        opt_mozcCandidates.candidate.length);
  }

  var windowPosition = (opt_mozcCandidates.category == 'SUGGESTION' ||
                        opt_mozcCandidates.category == 'PREDICTION') ?
                       'composition' : 'cursor';

  this.updateCandidateWindowProperties_({
    'visible': true,
    'cursorVisible': (focusedID != null),
    'vertical': true,
    'pageSize': pageSize,
    'auxiliaryTextVisible': (auxiliaryText.length != 0),
    'auxiliaryText': auxiliaryText,
    'windowPosition': windowPosition
  });
};

/**
 * Commits result string.
 * @param {mozc.Result=} opt_mozcResult The result data passed from NaCl
 *     Mozc module.
 * @private
 */
mozc.NaclMozc.prototype.commitResult_ = function(opt_mozcResult) {
  if (!opt_mozcResult) {
    return;
  }
  chrome.input.ime.commitText({
    'contextID': this.context_.contextID,
    'text': opt_mozcResult.value
  });
};

/**
 * Callback method called when IME is activated.
 * @param {string} engineID ID of the engine.
 * @private
 */
mozc.NaclMozc.prototype.onActivate_ = function(engineID) {
  this.engine_id_ = engineID;
  // Sets keyboardLayout_.
  var getManifest = chrome.runtime.getManifest;
  if (getManifest) {
    var input_components = getManifest()['input_components'];
    for (var i = 0; i < input_components.length; ++i) {
      if (input_components[i].id == engineID) {
        this.keyboardLayout_ = input_components[i]['layouts'][0];
      }
    }
  }
  this.updateMenuItems_();
};

/**
 * Callback method called when IME is deactivated.
 * @param {string} engineID ID of the engine.
 * @private
 */
mozc.NaclMozc.prototype.onDeactivated_ = function(engineID) {
  this.postNaclMozcEvent_(this.createMozcEvent_('SyncToFile'));
};

/**
 * Callback method called when a context acquires a focus.
 * @param {!InputContext} context The context information.
 * @private
 */
mozc.NaclMozc.prototype.onFocus_ = function(context) {
  this.context_ = context;
  var mozcCommand = this.createMozcCommand_('CREATE_SESSION');
  mozcCommand.input.capability =
      /** @type {!mozc.Capability} */
      ({text_deletion: 'DELETE_PRECEDING_TEXT'});
  mozcCommand.input.application_info =
      /** @type {!mozc.ApplicationInfo} */
      ({timezone_offset: -(new Date()).getTimezoneOffset() * 60});
  this.postMozcCommand_(
      mozcCommand,
      /**
      * @this {!mozc.NaclMozc}
      * @param {!mozc.Command} response
      */
      (function(response) {
        if (response.output.id == undefined) {
          console.error('CREATE_SESSION error');
          return;
        }
        this.sessionID_ = response.output.id;
      }).bind(this));
};

/**
 * Callback method called when a context lost a focus.
 * @param {number} contextID ID of the context.
 * @private
 */
mozc.NaclMozc.prototype.onBlur_ = function(contextID) {
  if (!this.sessionID_) {
    console.error('Session has not been created.');
    return;
  }
  var mozcCommand = this.createMozcCommand_('DELETE_SESSION');
  mozcCommand.input.id = this.sessionID_;
  this.postMozcCommand_(mozcCommand, this.processResponse_.bind(this));
  this.sessionID_ = '';
};

/**
 * Callback method called when properties of the context is changed.
 * @param {!InputContext} context context information.
 * @private
 */
mozc.NaclMozc.prototype.onInputContextUpdate_ = function(context) {
  // TODO(horo): Notify this event to Mozc since input field type may be changed
  //             to password field.
  this.context_ = context;
};


/**
 * Callback method called when IME catches a new key event.
 * @param {string} engineID ID of the engine.
 * @param {!ChromeKeyboardEvent} keyData key event data.
 * @private
 */
mozc.NaclMozc.prototype.onKeyEventAsync_ = function(engineID, keyData) {
  if (!this.sessionID_) {
    console.error('Session has not been created.');
    chrome.input.ime.keyEventHandled(keyData.requestId, false);
    return;
  }

  var keyEvent =
      this.keyTranslator_.translateKeyEvent(keyData,
                                            this.preeditMethod_ == 'KANA',
                                            this.keyboardLayout_);
  if (this.compositionMode_ == 'DIRECT') {
    // TODO(horo): Support custom keymap table.
    if (keyEvent.special_key == 'HANKAKU' ||
        keyEvent.special_key == 'HENKAN') {
      chrome.input.ime.keyEventHandled(keyData.requestId, true);
      this.switchCompositionMode_(mozc.CompositionMode_.HIRAGANA);
      this.updateMenuItems_();
    } else {
      chrome.input.ime.keyEventHandled(keyData.requestId, false);
    }
    return;
  }

  if (keyEvent.key_code == undefined &&
      keyEvent.special_key == undefined &&
      keyEvent.modifier_keys == undefined) {
    chrome.input.ime.keyEventHandled(keyData.requestId, false);
    return;
  }

  // Cancels the callback request.
  this.callbackCommand_ = /** @type {!mozc.Callback} */ ({});

  keyEvent.mode = this.compositionMode_;

  var context = /** @type {!mozc.Context} */ ({});
  if (this.surroundingInfo_) {
    context.preceding_text =
        this.surroundingInfo_.text.substring(
            0,
            Math.min(this.surroundingInfo_.focus,
                     this.surroundingInfo_.anchor));
    context.following_text =
        this.surroundingInfo_.text.substring(
            Math.max(this.surroundingInfo_.focus,
                     this.surroundingInfo_.anchor));
  }

  var mozcCommand = this.createMozcCommand_('SEND_KEY');
  mozcCommand.input.id = this.sessionID_;
  mozcCommand.input.key = keyEvent;
  mozcCommand.input.context = context;
  this.postMozcCommand_(
      mozcCommand,
      /**
      * @this {!mozc.NaclMozc}
      * @param {string} requestId
      * @param {!mozc.Command} response
      */
      (function(requestId, response) {
        this.processResponse_(response);
        chrome.input.ime.keyEventHandled(
            requestId,
            !!response.output.consumed);
      }).bind(this, keyData.requestId));
  return;
};

/**
 * Callback method called when candidates on candidate window is clicked.
 * @param {string} engineID ID of the engine.
 * @param {number} candidateID Index of the candidate.
 * @param {string} button Which mouse button was clicked.
 * @private
 */
mozc.NaclMozc.prototype.onCandidateClicked_ = function(engineID,
                                                       candidateID,
                                                       button) {
  var sessionCommand = this.createMozcSessionCommand_('SELECT_CANDIDATE');
  sessionCommand.id = candidateID;
  this.postMozcSessionCommand_(sessionCommand,
                               this.processResponse_.bind(this));
};

/**
 * Callback method called when menu item on uber tray is activated.
 * @param {string} engineID ID of the engine.
 * @param {string} name name of the menu item.
 * @private
 */
mozc.NaclMozc.prototype.onMenuItemActivated_ = function(engineID, name) {
  for (var i = 0; i < mozc.COMPOSITION_MENU_TABLE_.length; ++i) {
    if (name == mozc.COMPOSITION_MENU_TABLE_[i].menu) {
      this.switchCompositionMode_(mozc.COMPOSITION_MENU_TABLE_[i].mode);
      this.updateMenuItems_();
      return;
    }
  }
  console.error('Menu item ' + name + ' is not supported.');
};

/**
 * Callback method called the editable string around caret is changed or when
 * the caret position is moved. The text length is limited to 100 characters for
 * each back and forth direction.
 * @param {string} engineID ID of the engine.
 * @param {!Object.<{text: string, focus: number, anchor: number}>} info The
 *     surrounding information.
 * @private
 */
mozc.NaclMozc.prototype.onSurroundingTextChanged_ = function(engineID, info) {
  this.surroundingInfo_ = info;
};

/**
 * Callback method called when Chrome terminates ongoing text input session.
 * @param {string} engineID ID of the engine.
 * @private
 */
mozc.NaclMozc.prototype.onReset_ = function(engineID) {
  if (!this.sessionID_) {
    console.error('Session has not been created.');
    return;
  }
  this.postMozcSessionCommand_(
      this.createMozcSessionCommand_('RESET_CONTEXT'),
      /**
      * @this {!mozc.NaclMozc}
      * @param {!mozc.Command} response
      */
      (function(response) {
        if (response.output.mode) {
          // We ignore the mode in the response, because we should still use
          // the current compositionMode_.
          response.output.mode = undefined;
        }
        this.processResponse_(response);
      }).bind(this));
};

/**
 * Switches the composition mode.
 * @param {mozc.CompositionMode_} newMode The new composition mode to be set.
 * @private
 */
mozc.NaclMozc.prototype.switchCompositionMode_ = function(newMode) {
  var lastMode = this.compositionMode_;
  if (lastMode != mozc.CompositionMode_.DIRECT &&
      newMode == mozc.CompositionMode_.DIRECT) {
    var mozcCommand = this.createMozcCommand_('SEND_KEY');
    mozcCommand.input.id = this.sessionID_;
    mozcCommand.input.key =
        /** @type {!mozc.KeyEvent} */ ({'special_key': 'OFF'});
    this.postMozcCommand_(mozcCommand);
  } else if (newMode != mozc.CompositionMode_.DIRECT) {
    if (lastMode == mozc.CompositionMode_.DIRECT) {
      var mozcCommand = this.createMozcCommand_('SEND_KEY');
      mozcCommand.input.id = this.sessionID_;
      mozcCommand.input.key =
          /** @type {!mozc.KeyEvent} */ ({'special_key': 'ON'});
      this.postMozcCommand_(
          mozcCommand,
          /**
          * @this {!mozc.NaclMozc}
          * @param {!mozc.CompositionMode_} newMode
          * @param {!mozc.Command} response
          */
          (function(newMode, response) {
            var sessionCommand =
                this.createMozcSessionCommand_('SWITCH_INPUT_MODE');
            sessionCommand.composition_mode = newMode;
            this.postMozcSessionCommand_(sessionCommand);
          }).bind(this, newMode));
    } else {
      var sessionCommand =
          this.createMozcSessionCommand_('SWITCH_INPUT_MODE');
      sessionCommand.composition_mode = newMode;
      this.postMozcSessionCommand_(sessionCommand);
    }
  }
  this.compositionMode_ = newMode;
};

/**
 * Updates the menu items
 * @private
 */
mozc.NaclMozc.prototype.updateMenuItems_ = function() {
  var menuItems = [];
  for (var i = 0; i < mozc.COMPOSITION_MENU_TABLE_.length; ++i) {
    menuItems.push({
      'id': mozc.COMPOSITION_MENU_TABLE_[i].menu,
      'label': chrome.i18n.getMessage(mozc.COMPOSITION_MENU_TABLE_[i].labelId),
      'checked': this.compositionMode_ == mozc.COMPOSITION_MENU_TABLE_[i].mode,
      'enabled': true,
      'visible': true
    });
  }

  chrome.input.ime.setMenuItems({
    engineID: this.engine_id_,
    'items': menuItems
  });
};

/**
 * Callback method called when the NaCl module has loaded.
 * @private
 */
mozc.NaclMozc.prototype.onModuleLoad_ = function() {
};

/**
 * Handler of the messages from the NaCl module.
 * @param {Object} message message object from the NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.onModuleMessage_ = function(message) {
  if (!message) {
    console.error('onModuleMessage_ error');
    return;
  }
  var mozcResponse = {};
  try {
    mozcResponse = /** @type {!mozc.Message} */ (JSON.parse(message.data));
  } catch (e) {
    console.error('handleMessage: Error: ' + e.message);
    return;
  }
  if (mozcResponse.event &&
      mozcResponse.event.type == 'InitializeDone') {
    this.isNaclInitialized_ = true;
    if (mozcResponse.event.config['preedit_method']) {
      this.setPreeditMethod(
        /** @type {mozc.PreeditMethod_} */
        (mozcResponse.event.config['preedit_method']));
    }
    while (this.initializationCallbacks_.length > 0) {
      this.initializationCallbacks_.shift()();
    }
    this.executeWatingEventHandlers_();
    return;
  }

  var callback = this.naclMessageCallbacks_[mozcResponse.id];
  delete this.naclMessageCallbacks_[mozcResponse.id];
  if (callback) {
    if (mozcResponse.cmd) {
      callback(mozcResponse.cmd);
    } else if (mozcResponse.event) {
      callback(mozcResponse.event);
    }
  }
  this.executeWatingEventHandlers_();
};

/**
 * Progress event handler of the NaCl module.
 * @param {Object} event Progress event object from the NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.onModuleProgress_ = function(event) {
  if (!event) {
    console.error('progress event error: event is null');
    return;
  }
  if (event.lengthComputable && event.total > 0) {
    console.log('Loading: ' + (event.loaded / event.total * 100) + '%');
  } else {
    console.log('Loading...');
  }
};

/**
 * Error event handler of the NaCl module.
 * @private
 */
mozc.NaclMozc.prototype.onModuleError_ = function() {
  console.error('onModuleError', this.naclModule_['lastError']);
};

/**
 * New option page.
 * @param {!Window} optionWindow Window object of the option page.
 * @return {!mozc.OptionPage} Option page object.
 */
mozc.NaclMozc.prototype.newOptionPage = function(optionWindow) {
  var optionPage = new mozc.OptionPage(this, optionWindow);
  optionPage.initialize();
  return optionPage;
};
