Merge "[AD3] Implement the interface to choose a local dictionary"
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index f726c1c..12ffdbb 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -377,6 +377,12 @@
     <string name="prefs_keypress_sound_volume_settings">Keypress sound volume settings</string>
     <!-- Title of the settings for reading an external dictionary file -->
     <string name="prefs_read_external_dictionary">Read external dictionary file</string>
+    <!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
+    <string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string>
+    <!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] -->
+    <string name="read_external_dictionary_multiple_files_title">Select a dictionary file to install</string>
+    <!-- Title of the confirmation dialog to install a file as an external dictionary [CHAR LIMIT=50] -->
+    <string name="read_external_dictionary_confirm_install_message">Really install this file for <xliff:g id="locale_name">%s</xliff:g>?</string>
 
     <!-- Title of the button to revert to the default value of the device in the settings dialog [CHAR LIMIT=15] -->
     <string name="button_default">Default</string>
diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java
index 9468071..905852a 100644
--- a/java/src/com/android/inputmethod/latin/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/DebugSettings.java
@@ -75,7 +75,8 @@
                     new Preference.OnPreferenceClickListener() {
                         @Override
                         public boolean onPreferenceClick(final Preference arg0) {
-                            // TODO: actually read the dictionary
+                            ExternalDictionaryGetterForDebug.chooseAndInstallDictionary(
+                                    getActivity());
                             return true;
                         }
                     });
diff --git a/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java
new file mode 100644
index 0000000..5f91d03
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Environment;
+
+import com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Locale;
+
+/**
+ * A class to read a local file as a dictionary for debugging purposes.
+ */
+public class ExternalDictionaryGetterForDebug {
+    private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath()
+            + "/Download";
+    private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale";
+
+    private static FileHeader getDictionaryFileHeaderOrNull(final File file) {
+        try {
+            final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeader(file);
+            return header;
+        } catch (UnsupportedFormatException e) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    private static String[] findDictionariesInTheDownloadedFolder() {
+        final File[] files = new File(SOURCE_FOLDER).listFiles();
+        final ArrayList<String> eligibleList = CollectionUtils.newArrayList();
+        for (File f : files) {
+            final FileHeader header = getDictionaryFileHeaderOrNull(f);
+            if (null == header) continue;
+            eligibleList.add(f.getName());
+        }
+        return eligibleList.toArray(new String[0]);
+    }
+
+    public static void chooseAndInstallDictionary(final Context context) {
+        final String[] fileNames = findDictionariesInTheDownloadedFolder();
+        if (0 == fileNames.length) {
+            showNoFileDialog(context);
+        } else if (1 == fileNames.length) {
+            askInstallFile(context, fileNames[0]);
+        } else {
+            showChooseFileDialog(context, fileNames);
+        }
+    }
+
+    private static void showNoFileDialog(final Context context) {
+        new AlertDialog.Builder(context)
+                .setMessage(R.string.read_external_dictionary_no_files_message)
+                .setPositiveButton(android.R.string.ok, new OnClickListener() {
+                    @Override
+                    public void onClick(final DialogInterface dialog, final int which) {
+                        dialog.dismiss();
+                    }
+                }).create().show();
+    }
+
+    private static void showChooseFileDialog(final Context context, final String[] fileNames) {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        builder.setTitle(R.string.read_external_dictionary_multiple_files_title)
+                .setItems(fileNames, new OnClickListener() {
+                    @Override
+                    public void onClick(final DialogInterface dialog, final int which) {
+                        askInstallFile(context, fileNames[which]);
+                    }
+                })
+                .create().show();
+    }
+
+    private static void askInstallFile(final Context context, final String fileName) {
+        final File file = new File(SOURCE_FOLDER, fileName.toString());
+        final FileHeader header = getDictionaryFileHeaderOrNull(file);
+        final StringBuilder message = new StringBuilder();
+        final String locale =
+                header.mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_ATTRIBUTE);
+        for (String key : header.mDictionaryOptions.mAttributes.keySet()) {
+            message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key));
+            message.append("\n");
+        }
+        final String languageName = LocaleUtils.constructLocaleFromString(locale)
+                .getDisplayName(Locale.getDefault());
+        final String title = String.format(
+                context.getString(R.string.read_external_dictionary_confirm_install_message),
+                languageName);
+        new AlertDialog.Builder(context)
+                .setTitle(title)
+                .setMessage(message)
+                .setNegativeButton(android.R.string.cancel, new OnClickListener() {
+                    @Override
+                    public void onClick(final DialogInterface dialog, final int which) {
+                        dialog.dismiss();
+                    }
+                }).setPositiveButton(android.R.string.ok, new OnClickListener() {
+                    @Override
+                    public void onClick(final DialogInterface dialog, final int which) {
+                        installFile(file, header);
+                        dialog.dismiss();
+                    }
+                }).create().show();
+    }
+
+    private static void installFile(final File file, final FileHeader header) {
+        // TODO: actually install the dictionary
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 705f664..d55fe1c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -252,7 +252,7 @@
     /**
      * Class representing file header.
      */
-    static final class FileHeader {
+    public static final class FileHeader {
         public final int mHeaderSize;
         public final DictionaryOptions mDictionaryOptions;
         public final FormatOptions mFormatOptions;