// Copyright 2010-2014, 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.

package org.mozc.android.inputmethod.japanese.userdictionary;

import org.mozc.android.inputmethod.japanese.MozcUtil;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoUserDictionaryStorage.UserDictionary.Entry;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoUserDictionaryStorage.UserDictionary.PosType;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoUserDictionaryStorage.UserDictionaryCommandStatus.Status;
import org.mozc.android.inputmethod.japanese.resources.R;
import com.google.common.base.Preconditions;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.charset.Charset;
import java.nio.charset.CodingErrorAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

/**
 * Utilities (of, especially, UI related stuff) for the user dictionary tool.
 *
 */
class UserDictionaryUtil {

  /**
   * Callback which is called when the "positive button" on a dialog is clicked.
   */
  private interface UserDictionaryBaseDialogListener {
    public Status onPositiveButtonClicked(View view);
  }

  /**
   * Base implementation of popup dialog on user dictionary tool.
   *
   * This class has:
   * <ul>
   * <li>Title messaging
   * <li>Content view based on the given resource id
   * <li>Cancel and OK buttons
   * </ul>
   *
   * When the OK button is clicked, UserDictionaryBaseDialogListener callback is invoked.
   * The expected usage is invoke something action by interacting with the mozc server.
   * If the interaction fails (in more precise, the returned status is not
   * USER_DICTIONARY_COMMAND_SUCCESS), this class will show a toast message, and the popup dialog
   * won't be dismissed.
   */
  private static class UserDictionaryBaseDialog extends AlertDialog {
    private final UserDictionaryBaseDialogListener listener;
    private final ToastManager toastManager;

    UserDictionaryBaseDialog(Context context, int titleResourceId, int viewResourceId,
                             UserDictionaryBaseDialogListener listener,
                             ToastManager toastManager) {
      super(context);
      this.listener = listener;
      this.toastManager = toastManager;

      // Initialize the view. Set the title, the content view and ok, cancel buttons.
      setTitle(titleResourceId);
      setView(LayoutInflater.from(context).inflate(viewResourceId, null));

      // Set a dummy Message instance to fix crashing issue on Android 2.1.
      // On Android 2.1, com.android.internal.app.AlertController wrongly checks the message
      // for the availability of button view. So without the dummy message,
      // getButton(BUTTON_POSITIVE) used in onCreate would return null.
      setButton(DialogInterface.BUTTON_POSITIVE, context.getText(android.R.string.ok),
                Message.obtain());
      setButton(DialogInterface.BUTTON_NEGATIVE, context.getText(android.R.string.cancel),
                DialogInterface.OnClickListener.class.cast(null));
      setCancelable(true);
    }

    @Override
    protected void onCreate(Bundle savedInstance) {
      super.onCreate(savedInstance);

      // To override the default behavior that the dialog is dismissed after user's clicking
      // a button regardless of any action inside listener, we set the callback directly
      // to the button and manage dismissing behavior.
      // Note that it is necessary to do this here, instead of in the constructor,
      // because the UI is initialized in super class's onCreate method, and we cannot obtain
      // the button until the initialization.
      getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
          Status status = listener.onPositiveButtonClicked(view);
          toastManager.maybeShowMessageShortly(status);
          if (status == Status.USER_DICTIONARY_COMMAND_SUCCESS) {
            // Dismiss the dialog, iff the operation is successfully done.
            dismiss();
          }
        }
      });
    }
  }

  /**
   * Simple class to show the internationalized POS names on a spinner.
   */
  private static class PosItem {
    final PosType posType;
    final String name;

    PosItem(PosType posType, String name) {
      this.posType = posType;
      this.name = name;
    }

    // This is a hook to show the appropriate (internationalized) items on spinner.
    @Override
    public String toString() {
      return name;
    }
  }

  /**
   * Spinner implementation which has a list of POS.
   *
   * To keep users out from confusing UI, this class hides the IME when the list dialog is
   * shown by user's tap.
   */
  public static class PosSpinner extends Spinner {
    public PosSpinner(Context context) {
      super(context);
    }
    public PosSpinner(Context context, AttributeSet attrs) {
      super(context, attrs);
    }
    public PosSpinner(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
    }

    @Override
    protected void onFinishInflate() {
      // Set adapter containing a list of POS types.
      ArrayAdapter<PosItem> adapter = new ArrayAdapter<PosItem>(
          getContext(), android.R.layout.simple_spinner_item, createPosItemList(getResources()));
      adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
      setAdapter(adapter);
    }

    private static List<PosItem> createPosItemList(Resources resources) {
      PosType[] posTypeValues = PosType.values();
      List<PosItem> result = new ArrayList<PosItem>(posTypeValues.length);
      for (PosType posType : posTypeValues) {
        result.add(new PosItem(posType,
                               resources.getText(getPosStringResourceId(posType)).toString()));
      }
      return result;
    }

    @Override
    public boolean performClick() {
      // When the spinner is tapped (i.e. when the popup dialog is shown),
      // we hide the soft input method.
      // This is because the list of the POS is long so if the soft input is shown
      // continuously, a part of list would be out of the display.
      InputMethodManager imm = InputMethodManager.class.cast(
          getContext().getSystemService(Context.INPUT_METHOD_SERVICE));
      imm.hideSoftInputFromWindow(getWindowToken(), 0);

      return super.performClick();
    }
  }

  interface WordRegisterDialogListener {

    /**
     * Callback to be called when the positive button is clicked.
     * @return result status of the executed command.
     */
    public Status onPositiveButtonClicked(String word, String reading, PosType pos);
  }

  /**
   * Word Register Dialog implementation for adding/editing entries.
   *
   * The dialog should have:
   * <ul>
   * <li>A EditText for "word" editing,
   * <li>A EditText for "reading" editing, and
   * <li>A Spinner for "pos" selecting.
   */
  static class WordRegisterDialog extends UserDictionaryBaseDialog {
    WordRegisterDialog(Context context, int titleResourceId,
                       final WordRegisterDialogListener listener,
                       ToastManager toastManager) {
      super(context, titleResourceId, R.layout.user_dictionary_tool_word_register_dialog_view,
            new UserDictionaryBaseDialogListener() {
              @Override
              public Status onPositiveButtonClicked(View view) {
                return listener.onPositiveButtonClicked(
                    getText(view, R.id.user_dictionary_tool_word_register_dialog_word),
                    getText(view, R.id.user_dictionary_tool_word_register_dialog_reading),
                    getPos(view, R.id.user_dictionary_tool_word_register_dialog_pos));
              }
            }, toastManager);
      // TODO(hidehiko): Attach a callback for un-focused event on "word" EditText.
      //   and invoke reverse conversion (if necessary) to fill reading automatically.
    }

    /**
     * Sets the entry so that users can see it when the dialog is shown.
     * To make editing convenient, select all region.
     */
    void setEntry(Entry entry) {
      EditText wordEditText = EditText.class.cast(
          findViewById(R.id.user_dictionary_tool_word_register_dialog_word));
      wordEditText.setText(entry.getValue());
      EditText.class.cast(findViewById(R.id.user_dictionary_tool_word_register_dialog_reading))
          .setText(entry.getKey());
      Spinner posSpinner = Spinner.class.cast(
          findViewById(R.id.user_dictionary_tool_word_register_dialog_pos));
      int numItems = posSpinner.getCount();
      for (int i = 0; i < numItems; ++i) {
        if (PosItem.class.cast(posSpinner.getItemAtPosition(i)).posType == entry.getPos()) {
          posSpinner.setSelection(i);
          break;
        }
      }

      // Focus "word" field by default.
      wordEditText.requestFocus();
    }
  }

  interface DictionaryNameDialogListener {

    /**
     * Callback to be called when the positive button is clicked.
     * @param dictionaryName the text which is filled in EditText on the dialog.
     * @return result status of the executed command.
     */
    public Status onPositiveButtonClicked(String dictionaryName);
  }

  /**
   * Dialog implementation which has one edit box for dictionary name editing.
   */
  static class DictionaryNameDialog extends UserDictionaryBaseDialog {
    DictionaryNameDialog(Context context, int titleResourceId,
                         final DictionaryNameDialogListener listener,
                         ToastManager toastManager) {
      super(context, titleResourceId, R.layout.user_dictionary_tool_dictionary_name_dialog_view,
            new UserDictionaryBaseDialogListener() {
              @Override
              public Status onPositiveButtonClicked(View view) {
                return listener.onPositiveButtonClicked(
                    getText(view, R.id.user_dictionary_tool_dictionary_name_dialog_name));
              }
            }, toastManager);
    }

    /**
     * Sets the dictionaryName so that users can see it when the dialog is shown.
     * To make editing convenient, select all region.
     */
    void setDictionaryName(String dictionaryName) {
      EditText editText = EditText.class.cast(
          findViewById(R.id.user_dictionary_tool_dictionary_name_dialog_name));
      editText.setText(dictionaryName);
      editText.selectAll();
    }
  }

  /** A map from PosType to the string resource id for i18n. */
  private static final Map<PosType, Integer> POS_RESOURCE_MAP;
  static {
    EnumMap<PosType, Integer> map = new EnumMap<PosType, Integer>(PosType.class);
    map.put(PosType.NOUN, R.string.japanese_pos_noun);
    map.put(PosType.ABBREVIATION, R.string.japanese_pos_abbreviation);
    map.put(PosType.SUGGESTION_ONLY, R.string.japanese_pos_suggestion_only);
    map.put(PosType.PROPER_NOUN, R.string.japanese_pos_proper_noun);
    map.put(PosType.PERSONAL_NAME, R.string.japanese_pos_personal_name);
    map.put(PosType.FAMILY_NAME, R.string.japanese_pos_family_name);
    map.put(PosType.FIRST_NAME, R.string.japanese_pos_first_name);
    map.put(PosType.ORGANIZATION_NAME, R.string.japanese_pos_organization_name);
    map.put(PosType.PLACE_NAME, R.string.japanese_pos_place_name);
    map.put(PosType.SA_IRREGULAR_CONJUGATION_NOUN,
            R.string.japanese_pos_sa_irregular_conjugation_noun);
    map.put(PosType.ADJECTIVE_VERBAL_NOUN, R.string.japanese_pos_adjective_verbal_noun);
    map.put(PosType.NUMBER, R.string.japanese_pos_number);
    map.put(PosType.ALPHABET, R.string.japanese_pos_alphabet);
    map.put(PosType.SYMBOL, R.string.japanese_pos_symbol);
    map.put(PosType.EMOTICON, R.string.japanese_pos_emoticon);
    map.put(PosType.ADVERB, R.string.japanese_pos_adverb);
    map.put(PosType.PRENOUN_ADJECTIVAL, R.string.japanese_pos_prenoun_adjectival);
    map.put(PosType.CONJUNCTION, R.string.japanese_pos_conjunction);
    map.put(PosType.INTERJECTION, R.string.japanese_pos_interjection);
    map.put(PosType.PREFIX, R.string.japanese_pos_prefix);
    map.put(PosType.COUNTER_SUFFIX, R.string.japanese_pos_counter_suffix);
    map.put(PosType.GENERIC_SUFFIX, R.string.japanese_pos_generic_suffix);
    map.put(PosType.PERSON_NAME_SUFFIX, R.string.japanese_pos_person_name_suffix);
    map.put(PosType.PLACE_NAME_SUFFIX, R.string.japanese_pos_place_name_suffix);
    map.put(PosType.WA_GROUP1_VERB, R.string.japanese_pos_wa_group1_verb);
    map.put(PosType.KA_GROUP1_VERB, R.string.japanese_pos_ka_group1_verb);
    map.put(PosType.SA_GROUP1_VERB, R.string.japanese_pos_sa_group1_verb);
    map.put(PosType.TA_GROUP1_VERB, R.string.japanese_pos_ta_group1_verb);
    map.put(PosType.NA_GROUP1_VERB, R.string.japanese_pos_na_group1_verb);
    map.put(PosType.MA_GROUP1_VERB, R.string.japanese_pos_ma_group1_verb);
    map.put(PosType.RA_GROUP1_VERB, R.string.japanese_pos_ra_group1_verb);
    map.put(PosType.GA_GROUP1_VERB, R.string.japanese_pos_ga_group1_verb);
    map.put(PosType.BA_GROUP1_VERB, R.string.japanese_pos_ba_group1_verb);
    map.put(PosType.HA_GROUP1_VERB, R.string.japanese_pos_ha_group1_verb);
    map.put(PosType.GROUP2_VERB, R.string.japanese_pos_group2_verb);
    map.put(PosType.KURU_GROUP3_VERB, R.string.japanese_pos_kuru_group3_verb);
    map.put(PosType.SURU_GROUP3_VERB, R.string.japanese_pos_suru_group3_verb);
    map.put(PosType.ZURU_GROUP3_VERB, R.string.japanese_pos_zuru_group3_verb);
    map.put(PosType.RU_GROUP3_VERB, R.string.japanese_pos_ru_group3_verb);
    map.put(PosType.ADJECTIVE, R.string.japanese_pos_adjective);
    map.put(PosType.SENTENCE_ENDING_PARTICLE, R.string.japanese_pos_sentence_ending_particle);
    map.put(PosType.PUNCTUATION, R.string.japanese_pos_punctuation);
    map.put(PosType.FREE_STANDING_WORD, R.string.japanese_pos_free_standing_word);
    map.put(PosType.SUPPRESSION_WORD, R.string.japanese_pos_suppression_word);

    if (map.size() != PosType.values().length) {
      // There seems something unknown POS.
      throw new AssertionError();
    }
    POS_RESOURCE_MAP = Collections.unmodifiableMap(map);
  }

  /** A map from PosType to the string resource id dictionary export. */
  private static final Map<PosType, Integer> POS_RESOURCE_MAP_FOR_DICTIONARY_EXPORT;
  static {
    EnumMap<PosType, Integer> map = new EnumMap<PosType, Integer>(PosType.class);
    map.put(PosType.NOUN, R.string.japanese_pos_for_dictionary_export_noun);
    map.put(PosType.ABBREVIATION, R.string.japanese_pos_for_dictionary_export_abbreviation);
    map.put(PosType.SUGGESTION_ONLY, R.string.japanese_pos_for_dictionary_export_suggestion_only);
    map.put(PosType.PROPER_NOUN, R.string.japanese_pos_for_dictionary_export_proper_noun);
    map.put(PosType.PERSONAL_NAME, R.string.japanese_pos_for_dictionary_export_personal_name);
    map.put(PosType.FAMILY_NAME, R.string.japanese_pos_for_dictionary_export_family_name);
    map.put(PosType.FIRST_NAME, R.string.japanese_pos_for_dictionary_export_first_name);
    map.put(PosType.ORGANIZATION_NAME,
            R.string.japanese_pos_for_dictionary_export_organization_name);
    map.put(PosType.PLACE_NAME, R.string.japanese_pos_for_dictionary_export_place_name);
    map.put(PosType.SA_IRREGULAR_CONJUGATION_NOUN,
            R.string.japanese_pos_for_dictionary_export_sa_irregular_conjugation_noun);
    map.put(PosType.ADJECTIVE_VERBAL_NOUN,
            R.string.japanese_pos_for_dictionary_export_adjective_verbal_noun);
    map.put(PosType.NUMBER, R.string.japanese_pos_for_dictionary_export_number);
    map.put(PosType.ALPHABET, R.string.japanese_pos_for_dictionary_export_alphabet);
    map.put(PosType.SYMBOL, R.string.japanese_pos_for_dictionary_export_symbol);
    map.put(PosType.EMOTICON, R.string.japanese_pos_for_dictionary_export_emoticon);
    map.put(PosType.ADVERB, R.string.japanese_pos_for_dictionary_export_adverb);
    map.put(PosType.PRENOUN_ADJECTIVAL,
            R.string.japanese_pos_for_dictionary_export_prenoun_adjectival);
    map.put(PosType.CONJUNCTION, R.string.japanese_pos_for_dictionary_export_conjunction);
    map.put(PosType.INTERJECTION, R.string.japanese_pos_for_dictionary_export_interjection);
    map.put(PosType.PREFIX, R.string.japanese_pos_for_dictionary_export_prefix);
    map.put(PosType.COUNTER_SUFFIX, R.string.japanese_pos_for_dictionary_export_counter_suffix);
    map.put(PosType.GENERIC_SUFFIX, R.string.japanese_pos_for_dictionary_export_generic_suffix);
    map.put(PosType.PERSON_NAME_SUFFIX,
            R.string.japanese_pos_for_dictionary_export_person_name_suffix);
    map.put(PosType.PLACE_NAME_SUFFIX,
            R.string.japanese_pos_for_dictionary_export_place_name_suffix);
    map.put(PosType.WA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_wa_group1_verb);
    map.put(PosType.KA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_ka_group1_verb);
    map.put(PosType.SA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_sa_group1_verb);
    map.put(PosType.TA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_ta_group1_verb);
    map.put(PosType.NA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_na_group1_verb);
    map.put(PosType.MA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_ma_group1_verb);
    map.put(PosType.RA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_ra_group1_verb);
    map.put(PosType.GA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_ga_group1_verb);
    map.put(PosType.BA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_ba_group1_verb);
    map.put(PosType.HA_GROUP1_VERB, R.string.japanese_pos_for_dictionary_export_ha_group1_verb);
    map.put(PosType.GROUP2_VERB, R.string.japanese_pos_for_dictionary_export_group2_verb);
    map.put(PosType.KURU_GROUP3_VERB, R.string.japanese_pos_for_dictionary_export_kuru_group3_verb);
    map.put(PosType.SURU_GROUP3_VERB, R.string.japanese_pos_for_dictionary_export_suru_group3_verb);
    map.put(PosType.ZURU_GROUP3_VERB, R.string.japanese_pos_for_dictionary_export_zuru_group3_verb);
    map.put(PosType.RU_GROUP3_VERB, R.string.japanese_pos_for_dictionary_export_ru_group3_verb);
    map.put(PosType.ADJECTIVE,
            R.string.japanese_pos_for_dictionary_export_adjective);
    map.put(PosType.SENTENCE_ENDING_PARTICLE,
            R.string.japanese_pos_for_dictionary_export_sentence_ending_particle);
    map.put(PosType.PUNCTUATION, R.string.japanese_pos_for_dictionary_export_punctuation);
    map.put(PosType.FREE_STANDING_WORD,
            R.string.japanese_pos_for_dictionary_export_free_standing_word);
    map.put(PosType.SUPPRESSION_WORD, R.string.japanese_pos_for_dictionary_export_suppression_word);

    if (map.size() != PosType.values().length) {
      // There seems something unknown POS.
      throw new AssertionError();
    }
    POS_RESOURCE_MAP_FOR_DICTIONARY_EXPORT = Collections.unmodifiableMap(map);
  }

  /**
   * List of Japanese encodings to convert text for data importing.
   * These encodings are tries in the order, in other words, UTF-8 is the most high-prioritized
   * encoding.
   */
  private static final String[] JAPANESE_ENCODING_LIST = {
    "UTF-8", "EUC-JP", "ISO-2022-JP", "Shift_JIS", "UTF-16",
  };

  private UserDictionaryUtil() {
  }

  /**
   * Returns the text content of the view with the given resourceId.
   */
  private static String getText(View view, int resourceId) {
    view = view.getRootView();
    TextView textView = TextView.class.cast(view.findViewById(resourceId));
    return textView.getText().toString();
  }

  /**
   * Returns the PosType of the view with the given resourceId.
   */
  private static PosType getPos(View view, int resourceId) {
    view = view.getRootView();
    Spinner spinner = Spinner.class.cast(view.findViewById(resourceId));
    return PosItem.class.cast(spinner.getSelectedItem()).posType;
  }

  /**
   * Returns string resource id for the given {@code pos}.
   */
  static int getPosStringResourceId(PosType pos) {
    return POS_RESOURCE_MAP.get(Preconditions.checkNotNull(pos));
  }

  /**
   * Returns string resource id for the given {@code pos} for dictionary export.
   */
  static int getPosStringResourceIdForDictionaryExport(PosType pos) {
    return POS_RESOURCE_MAP_FOR_DICTIONARY_EXPORT.get(Preconditions.checkNotNull(pos));
  }

  /**
   * Returns the instance for Word Register Dialog.
   */
  static WordRegisterDialog createWordRegisterDialog(
      Context context, int titleResourceId, WordRegisterDialogListener listener,
      ToastManager toastManager) {
    return new WordRegisterDialog(context, titleResourceId, listener, toastManager);
  }

  /**
   * Returns a new instance for Dictionary Name Dialog.
   */
  static DictionaryNameDialog createDictionaryNameDialog(
      Context context, int titleResourceId, DictionaryNameDialogListener listener,
      ToastManager toastManager) {
    return new DictionaryNameDialog(context, titleResourceId, listener, toastManager);
  }

  /**
   * Returns a new instance for a dialog to select a file in a zipfile.
   */
  static Dialog createZipFileSelectionDialog(
      Context context, int titleResourceId,
      DialogInterface.OnClickListener positiveButtonListener,
      DialogInterface.OnClickListener negativeButtonListener,
      DialogInterface.OnCancelListener cancelListener) {
    return createSimpleSpinnerDialog(
        context, titleResourceId, positiveButtonListener, negativeButtonListener,
        cancelListener);
  }

  /**
   * Returns a new instance for a dialog to select import destination.
   */
  static Dialog createImportDictionarySelectionDialog(
      Context context, int titleResourceId,
      DialogInterface.OnClickListener positiveButtonListener,
      DialogInterface.OnClickListener negativeButtonListener,
      DialogInterface.OnCancelListener cancelListener) {
    return createSimpleSpinnerDialog(
        context, titleResourceId, positiveButtonListener, negativeButtonListener, cancelListener);
  }

  private static Dialog createSimpleSpinnerDialog(
      Context context, int titleResourceId,
      DialogInterface.OnClickListener positiveButtonListener,
      DialogInterface.OnClickListener negativeButtonListener,
      DialogInterface.OnCancelListener cancelListener) {
    View view = LayoutInflater.from(context).inflate(
        R.layout.user_dictionary_tool_simple_spinner_dialog_view, null);
    AlertDialog dialog = new AlertDialog.Builder(context)
        .setTitle(titleResourceId)
        .setView(view)
        .setPositiveButton(android.R.string.ok, positiveButtonListener)
        .setNegativeButton(android.R.string.cancel, negativeButtonListener)
        .setOnCancelListener(cancelListener)
        .setCancelable(true)
        .create();
    return dialog;
  }

  /**
   * Sets the parameter to show IME when the given dialog is shown.
   */
  static void showInputMethod(Dialog dialog) {
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
  }

  /**
   * Returns the {@code String} instance with detecting the Japanese encoding.
   * @throws UnsupportedEncodingException if it fails to detect the encoding.
   */
  static String toStringWithEncodingDetection(ByteBuffer buffer)
      throws UnsupportedEncodingException {
    for (String encoding : JAPANESE_ENCODING_LIST) {
      buffer.position(0);
      try {
        Charset charset = Charset.forName(encoding);
        CharBuffer result = charset.newDecoder()
           .onMalformedInput(CodingErrorAction.REPORT)
           .onUnmappableCharacter(CodingErrorAction.REPORT)
           .decode(buffer);
        String str = result.toString();
        if (str.length() > 0 && str.charAt(0) == 0xFEFF) {
          // Remove leading BOM if necessary.
          str = str.substring(1);
        }
        return str;
      } catch (Exception e) {
        // Ignore exceptions, and retry next encoding.
      }
    }

    throw new UnsupportedEncodingException("Failed to detect encoding");
  }

  /**
   * Reads the text file with detecting the file encoding.
   */
  static String readFromFile(String path) throws IOException {
    RandomAccessFile file = new RandomAccessFile(path, "r");
    boolean succeeded = false;
    try {
      String result = readFromFileInternal(file);
      succeeded = true;
      return result;
    } finally {
      MozcUtil.close(file, !succeeded);
    }
  }

  private static String readFromFileInternal(RandomAccessFile file) throws IOException {
    FileChannel channel = file.getChannel();
    boolean succeeded = false;
    try {
      String result = toStringWithEncodingDetection(
          channel.map(MapMode.READ_ONLY, 0, channel.size()));
      succeeded = true;
      return result;
    } finally {
      MozcUtil.close(channel, !succeeded);
    }
  }

  /**
   * Returns import source uri based on the Intent.
   */
  static Uri getImportUri(Intent intent) {
    String action = intent.getAction();
    if (Intent.ACTION_SEND.equals(action)) {
      return intent.getParcelableExtra(Intent.EXTRA_STREAM);
    }
    if (Intent.ACTION_VIEW.equals(action)) {
      return intent.getData();
    }
    return null;
  }

  /**
   * Returns a name for a new dictionary based on import URI.
   */
  static String generateDictionaryNameByUri(Uri importUri, List<String> dictionaryNameList) {
    String name = importUri.getLastPathSegment();

    // Strip extension
    {
      int index = name.lastIndexOf('.');
      if (index > 0) {
        // Keep file path beginning with '.'.
        name = name.substring(0, index);
      }
    }

    if (!dictionaryNameList.contains(name)) {
      // No-dupped dictionary name.
      return name;
    }

    // The names extracted from uri is dupped. So look for alternative names by adding
    // number suffix, such as "pathname (1)".
    int suffix = 1;
    while (true) {
      String candidate = name + " (" + suffix + ")";
      if (!dictionaryNameList.contains(candidate)) {
        return candidate;
      }
      // The limit of the number of dictionaries is much smaller than Integer.MAX_VALUE,
      // so this while loop should stop eventually.
      ++suffix;
    }
  }
}
