/*
 * Copyright (C) 2010 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.voicedialer;


import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.speech.srec.Recognizer;
import android.util.Log;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
/**
 * This is a RecognizerEngine that processes commands to make phone calls and
 * open applications.
 * <ul>
 * <li>setupGrammar
 * <li>Scans contacts and determine if the Grammar g2g file is stale.
 * <li>If so, create and rebuild the Grammar,
 * <li>Else create and load the Grammar from the file.
 * <li>onRecognitionSuccess is called when we get results from the recognizer,
 * it will process the results, which will pass a list of intents to
 * the {@RecognizerClient}.  It will accept the following types of commands:
 * "call" a particular contact
 * "dial a particular number
 * "open" a particular application
 * "redial" the last number called
 * "voicemail" to call voicemail
 * <li>Pass a list of {@link Intent} corresponding to the recognition results
 * to the {@link RecognizerClient}, which notifies the user.
 * </ul>
 * Notes:
 * <ul>
 * <li>Audio many be read from a file.
 * <li>A directory tree of audio files may be stepped through.
 * <li>A contact list may be read from a file.
 * <li>A {@link RecognizerLogger} may generate a set of log files from
 * a recognition session.
 * <li>A static instance of this class is held and reused by the
 * {@link VoiceDialerActivity}, which saves setup time.
 * </ul>
 */
public class CommandRecognizerEngine extends RecognizerEngine {

    private static final String OPEN_ENTRIES = "openentries.txt";
    public static final String PHONE_TYPE_EXTRA = "phone_type";
    private static final int MINIMUM_CONFIDENCE = 100;
    private File mContactsFile;
    private boolean mMinimizeResults;
    private boolean mAllowOpenEntries;
    private HashMap<String,String> mOpenEntries;

    /**
     * Constructor.
     */
    public CommandRecognizerEngine() {
        mContactsFile = null;
        mMinimizeResults = false;
        mAllowOpenEntries = true;
    }

    public void setContactsFile(File contactsFile) {
        if (contactsFile != mContactsFile) {
            mContactsFile = contactsFile;
            // if we change the contacts file, then we need to recreate the grammar.
            if (mSrecGrammar != null) {
                mSrecGrammar.destroy();
                mSrecGrammar = null;
                mOpenEntries = null;
            }
        }
    }

    public void setMinimizeResults(boolean minimizeResults) {
        mMinimizeResults = minimizeResults;
    }

    public void setAllowOpenEntries(boolean allowOpenEntries) {
        if (mAllowOpenEntries != allowOpenEntries) {
            // if we change this setting, then we need to recreate the grammar.
            if (mSrecGrammar != null) {
                mSrecGrammar.destroy();
                mSrecGrammar = null;
                mOpenEntries = null;
            }
        }
        mAllowOpenEntries = allowOpenEntries;
    }

    protected void setupGrammar() throws IOException, InterruptedException {
        // fetch the contact list
        if (false) Log.d(TAG, "start getVoiceContacts");
        if (false) Log.d(TAG, "contactsFile is " + (mContactsFile == null ?
            "null" : "not null"));
        List<VoiceContact> contacts = mContactsFile != null ?
                VoiceContact.getVoiceContactsFromFile(mContactsFile) :
                VoiceContact.getVoiceContacts(mActivity);

        // log contacts if requested
        if (mLogger != null) mLogger.logContacts(contacts);
        // generate g2g grammar file name
        File g2g = mActivity.getFileStreamPath("voicedialer." +
                Integer.toHexString(contacts.hashCode()) + ".g2g");

        // rebuild g2g file if current one is out of date
        if (!g2g.exists()) {
            // clean up existing Grammar and old file
            deleteAllG2GFiles(mActivity);
            if (mSrecGrammar != null) {
                mSrecGrammar.destroy();
                mSrecGrammar = null;
            }

            // load the empty Grammar
            if (false) Log.d(TAG, "start new Grammar");
            mSrecGrammar = mSrec.new Grammar(SREC_DIR + "/grammars/VoiceDialer.g2g");
            mSrecGrammar.setupRecognizer();

            // reset slots
            if (false) Log.d(TAG, "start grammar.resetAllSlots");
            mSrecGrammar.resetAllSlots();

            // add names to the grammar
            addNameEntriesToGrammar(contacts);

            if (mAllowOpenEntries) {
                // add open entries to the grammar
                addOpenEntriesToGrammar();
            }

            // compile the grammar
            if (false) Log.d(TAG, "start grammar.compile");
            mSrecGrammar.compile();

            // update g2g file
            if (false) Log.d(TAG, "start grammar.save " + g2g.getPath());
            g2g.getParentFile().mkdirs();
            mSrecGrammar.save(g2g.getPath());
        }

        // g2g file exists, but is not loaded
        else if (mSrecGrammar == null) {
            if (false) Log.d(TAG, "start new Grammar loading " + g2g);
            mSrecGrammar = mSrec.new Grammar(g2g.getPath());
            mSrecGrammar.setupRecognizer();
        }
        if (mOpenEntries == null && mAllowOpenEntries) {
            // make sure to load the openEntries mapping table.
            loadOpenEntriesTable();
        }

    }

    /**
     * Add a list of names to the grammar
     * @param contacts list of VoiceContacts to be added.
     */
    private void addNameEntriesToGrammar(List<VoiceContact> contacts)
            throws InterruptedException {
        if (false) Log.d(TAG, "addNameEntriesToGrammar " + contacts.size());

        HashSet<String> entries = new HashSet<String>();
        StringBuffer sb = new StringBuffer();
        int count = 0;
        for (VoiceContact contact : contacts) {
            if (Thread.interrupted()) throw new InterruptedException();
            String name = scrubName(contact.mName);
            if (name.length() == 0 || !entries.add(name)) continue;
            sb.setLength(0);
            sb.append("V='");
            sb.append(contact.mContactId).append(' ');
            sb.append(contact.mPrimaryId).append(' ');
            sb.append(contact.mHomeId).append(' ');
            sb.append(contact.mMobileId).append(' ');
            sb.append(contact.mWorkId).append(' ');
            sb.append(contact.mOtherId);
            sb.append("'");
            try {
                mSrecGrammar.addWordToSlot("@Names", name, null, 1, sb.toString());
            } catch (Exception e) {
                Log.e(TAG, "Cannot load all contacts to voice recognizer, loaded " +
                        count, e);
                break;
            }

            count++;
        }
    }

    /**
     * add a list of application labels to the 'open x' grammar
     */
    private void loadOpenEntriesTable() throws InterruptedException, IOException {
        if (false) Log.d(TAG, "addOpenEntriesToGrammar");

        // fill this
        File oe = mActivity.getFileStreamPath(OPEN_ENTRIES);

        // build and write list of entries
        if (!oe.exists()) {
            mOpenEntries = new HashMap<String, String>();

            // build a list of 'open' entries
            PackageManager pm = mActivity.getPackageManager();
            List<ResolveInfo> riList = pm.queryIntentActivities(
                            new Intent(Intent.ACTION_MAIN).
                            addCategory("android.intent.category.VOICE_LAUNCH"),
                            PackageManager.GET_ACTIVITIES);
            if (Thread.interrupted()) throw new InterruptedException();
            riList.addAll(pm.queryIntentActivities(
                            new Intent(Intent.ACTION_MAIN).
                            addCategory("android.intent.category.LAUNCHER"),
                            PackageManager.GET_ACTIVITIES));
            String voiceDialerClassName = mActivity.getComponentName().getClassName();

            // scan list, adding complete phrases, as well as individual words
            for (ResolveInfo ri : riList) {
                if (Thread.interrupted()) throw new InterruptedException();

                // skip self
                if (voiceDialerClassName.equals(ri.activityInfo.name)) continue;

                // fetch a scrubbed window label
                String label = scrubName(ri.loadLabel(pm).toString());
                if (label.length() == 0) continue;

                // insert it into the result list
                addClassName(mOpenEntries, label,
                        ri.activityInfo.packageName, ri.activityInfo.name);

                // split it into individual words, and insert them
                String[] words = label.split(" ");
                if (words.length > 1) {
                    for (String word : words) {
                        word = word.trim();
                        // words must be three characters long, or two if capitalized
                        int len = word.length();
                        if (len <= 1) continue;
                        if (len == 2 && !(Character.isUpperCase(word.charAt(0)) &&
                                        Character.isUpperCase(word.charAt(1)))) continue;
                        if ("and".equalsIgnoreCase(word) ||
                                "the".equalsIgnoreCase(word)) continue;
                        // add the word
                        addClassName(mOpenEntries, word,
                                ri.activityInfo.packageName, ri.activityInfo.name);
                    }
                }
            }

            // write list
            if (false) Log.d(TAG, "addOpenEntriesToGrammar writing " + oe);
            try {
                 FileOutputStream fos = new FileOutputStream(oe);
                 try {
                    ObjectOutputStream oos = new ObjectOutputStream(fos);
                    oos.writeObject(mOpenEntries);
                    oos.close();
                } finally {
                    fos.close();
                }
            } catch (IOException ioe) {
                deleteCachedGrammarFiles(mActivity);
                throw ioe;
            }
        }

        // read the list
        else {
            if (false) Log.d(TAG, "addOpenEntriesToGrammar reading " + oe);
            try {
                FileInputStream fis = new FileInputStream(oe);
                try {
                    ObjectInputStream ois = new ObjectInputStream(fis);
                    mOpenEntries = (HashMap<String, String>)ois.readObject();
                    ois.close();
                } finally {
                    fis.close();
                }
            } catch (Exception e) {
                deleteCachedGrammarFiles(mActivity);
                throw new IOException(e.toString());
            }
        }
    }

    private void addOpenEntriesToGrammar() throws InterruptedException, IOException {
        // load up our open entries table
        loadOpenEntriesTable();

        // add list of 'open' entries to the grammar
        for (String label : mOpenEntries.keySet()) {
            if (Thread.interrupted()) throw new InterruptedException();
            String entry = mOpenEntries.get(label);
            // don't add if too many results
            int count = 0;
            for (int i = 0; 0 != (i = entry.indexOf(' ', i) + 1); count++) ;
            if (count > RESULT_LIMIT) continue;
            // add the word to the grammar
            // See Bug: 2457238.
            // We used to store the entire list of components into the grammar.
            // Unfortuantely, the recognizer has a fixed limit on the length of
            // the "semantic" string, which is easy to overflow.  So now,
            // the we store our own mapping table between words and component
            // names, and the entries in the grammar have the same value
            // for literal and semantic.
            mSrecGrammar.addWordToSlot("@Opens", label, null, 1, "V='" + label + "'");
        }
    }

    /**
     * Add a className to a hash table of class name lists.
     * @param openEntries HashMap of lists of class names.
     * @param label a label or word corresponding to the list of classes.
     * @param className class name to add
     */
    private static void addClassName(HashMap<String,String> openEntries,
            String label, String packageName, String className) {
        String component = packageName + "/" + className;
        String labelLowerCase = label.toLowerCase();
        String classList = openEntries.get(labelLowerCase);

        // first item in the list
        if (classList == null) {
            openEntries.put(labelLowerCase, component);
            return;
        }
        // already in list
        int index = classList.indexOf(component);
        int after = index + component.length();
        if (index != -1 && (index == 0 || classList.charAt(index - 1) == ' ') &&
                (after == classList.length() || classList.charAt(after) == ' ')) return;

        // add it to the end
        openEntries.put(labelLowerCase, classList + ' ' + component);
    }

    // map letters in Latin1 Supplement to basic ascii
    // from http://en.wikipedia.org/wiki/Latin-1_Supplement_unicode_block
    // not all letters map well, including Eth and Thorn
    // TODO: this should really be all handled in the pronunciation engine
    private final static char[] mLatin1Letters =
            "AAAAAAACEEEEIIIIDNOOOOO OUUUUYDsaaaaaaaceeeeiiiidnooooo ouuuuydy".
            toCharArray();
    private final static int mLatin1Base = 0x00c0;

    /**
     * Reformat a raw name from the contact list into a form a
     * {@link Recognizer.Grammar} can digest.
     * @param name the raw name.
     * @return the reformatted name.
     */
    private static String scrubName(String name) {
        // replace '&' with ' and '
        name = name.replace("&", " and ");

        // replace '@' with ' at '
        name = name.replace("@", " at ");

        // remove '(...)'
        while (true) {
            int i = name.indexOf('(');
            if (i == -1) break;
            int j = name.indexOf(')', i);
            if (j == -1) break;
            name = name.substring(0, i) + " " + name.substring(j + 1);
        }

        // map letters of Latin1 Supplement to basic ascii
        char[] nm = null;
        for (int i = name.length() - 1; i >= 0; i--) {
            char ch = name.charAt(i);
            if (ch < ' ' || '~' < ch) {
                if (nm == null) nm = name.toCharArray();
                nm[i] = mLatin1Base <= ch && ch < mLatin1Base + mLatin1Letters.length ?
                    mLatin1Letters[ch - mLatin1Base] : ' ';
            }
        }
        if (nm != null) {
            name = new String(nm);
        }

        // if '.' followed by alnum, replace with ' dot '
        while (true) {
            int i = name.indexOf('.');
            if (i == -1 ||
                    i + 1 >= name.length() ||
                    !Character.isLetterOrDigit(name.charAt(i + 1))) break;
            name = name.substring(0, i) + " dot " + name.substring(i + 1);
        }

        // trim
        name = name.trim();

        // ensure at least one alphanumeric character, or the pron engine will fail
        for (int i = name.length() - 1; true; i--) {
            if (i < 0) return "";
            char ch = name.charAt(i);
            if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9')) {
                break;
            }
        }

        return name;
    }

    /**
     * Delete all g2g files in the directory indicated by {@link File},
     * which is typically /data/data/com.android.voicedialer/files.
     * There should only be one g2g file at any one time, with a hashcode
     * embedded in it's name, but if stale ones are present, this will delete
     * them all.
     * @param context fetch directory for the stuffed and compiled g2g file.
     */
    private static void deleteAllG2GFiles(Context context) {
        FileFilter ff = new FileFilter() {
            public boolean accept(File f) {
                String name = f.getName();
                return name.endsWith(".g2g");
            }
        };
        File[] files = context.getFilesDir().listFiles(ff);
        if (files != null) {
            for (File file : files) {
                if (false) Log.d(TAG, "deleteAllG2GFiles " + file);
                file.delete();
            }
        }
    }

    /**
     * Delete G2G and OpenEntries files, to force regeneration of the g2g file
     * from scratch.
     * @param context fetch directory for file.
     */
    public static void deleteCachedGrammarFiles(Context context) {
        deleteAllG2GFiles(context);
        File oe = context.getFileStreamPath(OPEN_ENTRIES);
        if (false) Log.v(TAG, "deleteCachedGrammarFiles " + oe);
        if (oe.exists()) oe.delete();
    }

    // NANP number formats
    private final static String mNanpFormats =
        "xxx xxx xxxx\n" +
        "xxx xxxx\n" +
        "x11\n";

    // a list of country codes
    private final static String mPlusFormats =

        ////////////////////////////////////////////////////////////
        // zone 1: nanp (north american numbering plan), us, canada, caribbean
        ////////////////////////////////////////////////////////////

        "+1 xxx xxx xxxx\n" +         // nanp

        ////////////////////////////////////////////////////////////
        // zone 2: africa, some atlantic and indian ocean islands
        ////////////////////////////////////////////////////////////

        "+20 x xxx xxxx\n" +          // Egypt
        "+20 1x xxx xxxx\n" +         // Egypt
        "+20 xx xxx xxxx\n" +         // Egypt
        "+20 xxx xxx xxxx\n" +        // Egypt

        "+212 xxxx xxxx\n" +          // Morocco

        "+213 xx xx xx xx\n" +        // Algeria
        "+213 xx xxx xxxx\n" +        // Algeria

        "+216 xx xxx xxx\n" +         // Tunisia

        "+218 xx xxx xxx\n" +         // Libya

        "+22x \n" +
        "+23x \n" +
        "+24x \n" +
        "+25x \n" +
        "+26x \n" +

        "+27 xx xxx xxxx\n" +         // South africa

        "+290 x xxx\n" +              // Saint Helena, Tristan da Cunha

        "+291 x xxx xxx\n" +          // Eritrea

        "+297 xxx xxxx\n" +           // Aruba

        "+298 xxx xxx\n" +            // Faroe Islands

        "+299 xxx xxx\n" +            // Greenland

        ////////////////////////////////////////////////////////////
        // zone 3: europe, southern and small countries
        ////////////////////////////////////////////////////////////

        "+30 xxx xxx xxxx\n" +        // Greece

        "+31 6 xxxx xxxx\n" +         // Netherlands
        "+31 xx xxx xxxx\n" +         // Netherlands
        "+31 xxx xx xxxx\n" +         // Netherlands

        "+32 2 xxx xx xx\n" +         // Belgium
        "+32 3 xxx xx xx\n" +         // Belgium
        "+32 4xx xx xx xx\n" +        // Belgium
        "+32 9 xxx xx xx\n" +         // Belgium
        "+32 xx xx xx xx\n" +         // Belgium

        "+33 xxx xxx xxx\n" +         // France

        "+34 xxx xxx xxx\n" +        // Spain

        "+351 3xx xxx xxx\n" +       // Portugal
        "+351 7xx xxx xxx\n" +       // Portugal
        "+351 8xx xxx xxx\n" +       // Portugal
        "+351 xx xxx xxxx\n" +       // Portugal

        "+352 xx xxxx\n" +           // Luxembourg
        "+352 6x1 xxx xxx\n" +       // Luxembourg
        "+352 \n" +                  // Luxembourg

        "+353 xxx xxxx\n" +          // Ireland
        "+353 xxxx xxxx\n" +         // Ireland
        "+353 xx xxx xxxx\n" +       // Ireland

        "+354 3xx xxx xxx\n" +       // Iceland
        "+354 xxx xxxx\n" +          // Iceland

        "+355 6x xxx xxxx\n" +       // Albania
        "+355 xxx xxxx\n" +          // Albania

        "+356 xx xx xx xx\n" +       // Malta

        "+357 xx xx xx xx\n" +       // Cyprus

        "+358 \n" +                  // Finland

        "+359 \n" +                  // Bulgaria

        "+36 1 xxx xxxx\n" +         // Hungary
        "+36 20 xxx xxxx\n" +        // Hungary
        "+36 21 xxx xxxx\n" +        // Hungary
        "+36 30 xxx xxxx\n" +        // Hungary
        "+36 70 xxx xxxx\n" +        // Hungary
        "+36 71 xxx xxxx\n" +        // Hungary
        "+36 xx xxx xxx\n" +         // Hungary

        "+370 6x xxx xxx\n" +        // Lithuania
        "+370 xxx xx xxx\n" +        // Lithuania

        "+371 xxxx xxxx\n" +         // Latvia

        "+372 5 xxx xxxx\n" +        // Estonia
        "+372 xxx xxxx\n" +          // Estonia

        "+373 6xx xx xxx\n" +        // Moldova
        "+373 7xx xx xxx\n" +        // Moldova
        "+373 xxx xxxxx\n" +         // Moldova

        "+374 xx xxx xxx\n" +        // Armenia

        "+375 xx xxx xxxx\n" +       // Belarus

        "+376 xx xx xx\n" +          // Andorra

        "+377 xxxx xxxx\n" +         // Monaco

        "+378 xxx xxx xxxx\n" +      // San Marino

        "+380 xxx xx xx xx\n" +      // Ukraine

        "+381 xx xxx xxxx\n" +       // Serbia

        "+382 xx xxx xxxx\n" +       // Montenegro

        "+385 xx xxx xxxx\n" +       // Croatia

        "+386 x xxx xxxx\n" +        // Slovenia

        "+387 xx xx xx xx\n" +       // Bosnia and herzegovina

        "+389 2 xxx xx xx\n" +       // Macedonia
        "+389 xx xx xx xx\n" +       // Macedonia

        "+39 xxx xxx xxx\n" +        // Italy
        "+39 3xx xxx xxxx\n" +       // Italy
        "+39 xx xxxx xxxx\n" +       // Italy

        ////////////////////////////////////////////////////////////
        // zone 4: europe, northern countries
        ////////////////////////////////////////////////////////////

        "+40 xxx xxx xxx\n" +        // Romania

        "+41 xx xxx xx xx\n" +       // Switzerland

        "+420 xxx xxx xxx\n" +       // Czech republic

        "+421 xxx xxx xxx\n" +       // Slovakia

        "+421 xxx xxx xxxx\n" +      // Liechtenstein

        "+43 \n" +                   // Austria

        "+44 xxx xxx xxxx\n" +       // UK

        "+45 xx xx xx xx\n" +        // Denmark

        "+46 \n" +                   // Sweden

        "+47 xxxx xxxx\n" +          // Norway

        "+48 xx xxx xxxx\n" +        // Poland

        "+49 1xx xxxx xxx\n" +       // Germany
        "+49 1xx xxxx xxxx\n" +      // Germany
        "+49 \n" +                   // Germany

        ////////////////////////////////////////////////////////////
        // zone 5: latin america
        ////////////////////////////////////////////////////////////

        "+50x \n" +

        "+51 9xx xxx xxx\n" +        // Peru
        "+51 1 xxx xxxx\n" +         // Peru
        "+51 xx xx xxxx\n" +         // Peru

        "+52 1 xxx xxx xxxx\n" +     // Mexico
        "+52 xxx xxx xxxx\n" +       // Mexico

        "+53 xxxx xxxx\n" +          // Cuba

        "+54 9 11 xxxx xxxx\n" +     // Argentina
        "+54 9 xxx xxx xxxx\n" +     // Argentina
        "+54 11 xxxx xxxx\n" +       // Argentina
        "+54 xxx xxx xxxx\n" +       // Argentina

        "+55 xx xxxx xxxx\n" +       // Brazil

        "+56 2 xxxxxx\n" +           // Chile
        "+56 9 xxxx xxxx\n" +        // Chile
        "+56 xx xxxxxx\n" +          // Chile
        "+56 xx xxxxxxx\n" +         // Chile

        "+57 x xxx xxxx\n" +         // Columbia
        "+57 3xx xxx xxxx\n" +       // Columbia

        "+58 xxx xxx xxxx\n" +       // Venezuela

        "+59x \n" +

        ////////////////////////////////////////////////////////////
        // zone 6: southeast asia and oceania
        ////////////////////////////////////////////////////////////

        // TODO is this right?
        "+60 3 xxxx xxxx\n" +        // Malaysia
        "+60 8x xxxxxx\n" +          // Malaysia
        "+60 x xxx xxxx\n" +         // Malaysia
        "+60 14 x xxx xxxx\n" +      // Malaysia
        "+60 1x xxx xxxx\n" +        // Malaysia
        "+60 x xxxx xxxx\n" +        // Malaysia
        "+60 \n" +                   // Malaysia

        "+61 4xx xxx xxx\n" +        // Australia
        "+61 x xxxx xxxx\n" +        // Australia

        // TODO: is this right?
        "+62 8xx xxxx xxxx\n" +      // Indonesia
        "+62 21 xxxxx\n" +           // Indonesia
        "+62 xx xxxxxx\n" +          // Indonesia
        "+62 xx xxx xxxx\n" +        // Indonesia
        "+62 xx xxxx xxxx\n" +       // Indonesia

        "+63 2 xxx xxxx\n" +         // Phillipines
        "+63 xx xxx xxxx\n" +        // Phillipines
        "+63 9xx xxx xxxx\n" +       // Phillipines

        // TODO: is this right?
        "+64 2 xxx xxxx\n" +         // New Zealand
        "+64 2 xxx xxxx x\n" +       // New Zealand
        "+64 2 xxx xxxx xx\n" +      // New Zealand
        "+64 x xxx xxxx\n" +         // New Zealand

        "+65 xxxx xxxx\n" +          // Singapore

        "+66 8 xxxx xxxx\n" +        // Thailand
        "+66 2 xxx xxxx\n" +         // Thailand
        "+66 xx xx xxxx\n" +         // Thailand

        "+67x \n" +
        "+68x \n" +

        "+690 x xxx\n" +             // Tokelau

        "+691 xxx xxxx\n" +          // Micronesia

        "+692 xxx xxxx\n" +          // marshall Islands

        ////////////////////////////////////////////////////////////
        // zone 7: russia and kazakstan
        ////////////////////////////////////////////////////////////

        "+7 6xx xx xxxxx\n" +        // Kazakstan
        "+7 7xx 2 xxxxxx\n" +        // Kazakstan
        "+7 7xx xx xxxxx\n" +        // Kazakstan

        "+7 xxx xxx xx xx\n" +       // Russia

        ////////////////////////////////////////////////////////////
        // zone 8: east asia
        ////////////////////////////////////////////////////////////

        "+81 3 xxxx xxxx\n" +        // Japan
        "+81 6 xxxx xxxx\n" +        // Japan
        "+81 xx xxx xxxx\n" +        // Japan
        "+81 x0 xxxx xxxx\n" +       // Japan

        "+82 2 xxx xxxx\n" +         // South korea
        "+82 2 xxxx xxxx\n" +        // South korea
        "+82 xx xxxx xxxx\n" +       // South korea
        "+82 xx xxx xxxx\n" +        // South korea

        "+84 4 xxxx xxxx\n" +        // Vietnam
        "+84 xx xxxx xxx\n" +        // Vietnam
        "+84 xx xxxx xxxx\n" +       // Vietnam

        "+850 \n" +                  // North Korea

        "+852 xxxx xxxx\n" +         // Hong Kong

        "+853 xxxx xxxx\n" +         // Macau

        "+855 1x xxx xxx\n" +        // Cambodia
        "+855 9x xxx xxx\n" +        // Cambodia
        "+855 xx xx xx xx\n" +       // Cambodia

        "+856 20 x xxx xxx\n" +      // Laos
        "+856 xx xxx xxx\n" +        // Laos

        "+852 xxxx xxxx\n" +         // Hong kong

        "+86 10 xxxx xxxx\n" +       // China
        "+86 2x xxxx xxxx\n" +       // China
        "+86 xxx xxx xxxx\n" +       // China
        "+86 xxx xxxx xxxx\n" +      // China

        "+880 xx xxxx xxxx\n" +      // Bangladesh

        "+886 \n" +                  // Taiwan

        ////////////////////////////////////////////////////////////
        // zone 9: south asia, west asia, central asia, middle east
        ////////////////////////////////////////////////////////////

        "+90 xxx xxx xxxx\n" +       // Turkey

        "+91 9x xx xxxxxx\n" +       // India
        "+91 xx xxxx xxxx\n" +       // India

        "+92 xx xxx xxxx\n" +        // Pakistan
        "+92 3xx xxx xxxx\n" +       // Pakistan

        "+93 70 xxx xxx\n" +         // Afghanistan
        "+93 xx xxx xxxx\n" +        // Afghanistan

        "+94 xx xxx xxxx\n" +        // Sri Lanka

        "+95 1 xxx xxx\n" +          // Burma
        "+95 2 xxx xxx\n" +          // Burma
        "+95 xx xxxxx\n" +           // Burma
        "+95 9 xxx xxxx\n" +         // Burma

        "+960 xxx xxxx\n" +          // Maldives

        "+961 x xxx xxx\n" +         // Lebanon
        "+961 xx xxx xxx\n" +        // Lebanon

        "+962 7 xxxx xxxx\n" +       // Jordan
        "+962 x xxx xxxx\n" +        // Jordan

        "+963 11 xxx xxxx\n" +       // Syria
        "+963 xx xxx xxx\n" +        // Syria

        "+964 \n" +                  // Iraq

        "+965 xxxx xxxx\n" +         // Kuwait

        "+966 5x xxx xxxx\n" +       // Saudi Arabia
        "+966 x xxx xxxx\n" +        // Saudi Arabia

        "+967 7xx xxx xxx\n" +       // Yemen
        "+967 x xxx xxx\n" +         // Yemen

        "+968 xxxx xxxx\n" +         // Oman

        "+970 5x xxx xxxx\n" +       // Palestinian Authority
        "+970 x xxx xxxx\n" +        // Palestinian Authority

        "+971 5x xxx xxxx\n" +       // United Arab Emirates
        "+971 x xxx xxxx\n" +        // United Arab Emirates

        "+972 5x xxx xxxx\n" +       // Israel
        "+972 x xxx xxxx\n" +        // Israel

        "+973 xxxx xxxx\n" +         // Bahrain

        "+974 xxx xxxx\n" +          // Qatar

        "+975 1x xxx xxx\n" +        // Bhutan
        "+975 x xxx xxx\n" +         // Bhutan

        "+976 \n" +                  // Mongolia

        "+977 xxxx xxxx\n" +         // Nepal
        "+977 98 xxxx xxxx\n" +      // Nepal

        "+98 xxx xxx xxxx\n" +       // Iran

        "+992 xxx xxx xxx\n" +       // Tajikistan

        "+993 xxxx xxxx\n" +         // Turkmenistan

        "+994 xx xxx xxxx\n" +       // Azerbaijan
        "+994 xxx xxxxx\n" +         // Azerbaijan

        "+995 xx xxx xxx\n" +        // Georgia

        "+996 xxx xxx xxx\n" +       // Kyrgyzstan

        "+998 xx xxx xxxx\n";        // Uzbekistan


    // TODO: need to handle variable number notation
    private static String formatNumber(String formats, String number) {
        number = number.trim();
        final int nlen = number.length();
        final int formatslen = formats.length();
        StringBuffer sb = new StringBuffer();

        // loop over country codes
        for (int f = 0; f < formatslen; ) {
            sb.setLength(0);
            int n = 0;

            // loop over letters of pattern
            while (true) {
                final char fch = formats.charAt(f);
                if (fch == '\n' && n >= nlen) return sb.toString();
                if (fch == '\n' || n >= nlen) break;
                final char nch = number.charAt(n);
                // pattern matches number
                if (fch == nch || (fch == 'x' && Character.isDigit(nch))) {
                    f++;
                    n++;
                    sb.append(nch);
                }
                // don't match ' ' in pattern, but insert into result
                else if (fch == ' ') {
                    f++;
                    sb.append(' ');
                    // ' ' at end -> match all the rest
                    if (formats.charAt(f) == '\n') {
                        return sb.append(number, n, nlen).toString();
                    }
                }
                // match failed
                else break;
            }

            // step to the next pattern
            f = formats.indexOf('\n', f) + 1;
            if (f == 0) break;
        }

        return null;
    }

    /**
     * Format a phone number string.
     * At some point, PhoneNumberUtils.formatNumber will handle this.
     * @param num phone number string.
     * @return formatted phone number string.
     */
    private static String formatNumber(String num) {
        String fmt = null;

        fmt = formatNumber(mPlusFormats, num);
        if (fmt != null) return fmt;

        fmt = formatNumber(mNanpFormats, num);
        if (fmt != null) return fmt;

        return null;
    }

    /**
     * Called when recognition succeeds.  It receives a list
     * of results, builds a corresponding list of Intents, and
     * passes them to the {@link RecognizerClient}, which selects and
     * performs a corresponding action.
     * @param recognizerClient the client that will be sent the results
     */
    protected  void onRecognitionSuccess(RecognizerClient recognizerClient)
            throws InterruptedException {
        if (false) Log.d(TAG, "onRecognitionSuccess");

        if (mLogger != null) mLogger.logNbestHeader();

        ArrayList<Intent> intents = new ArrayList<Intent>();

        int highestConfidence = 0;
        int examineLimit = RESULT_LIMIT;
        if (mMinimizeResults) {
            examineLimit = 1;
        }
        for (int result = 0; result < mSrec.getResultCount() &&
                intents.size() < examineLimit; result++) {

            // parse the semanticMeaning string and build an Intent
            String conf = mSrec.getResult(result, Recognizer.KEY_CONFIDENCE);
            String literal = mSrec.getResult(result, Recognizer.KEY_LITERAL);
            String semantic = mSrec.getResult(result, Recognizer.KEY_MEANING);
            String msg = "conf=" + conf + " lit=" + literal + " sem=" + semantic;
            if (false) Log.d(TAG, msg);
            int confInt = Integer.parseInt(conf);
            if (highestConfidence < confInt) highestConfidence = confInt;
            if (confInt < MINIMUM_CONFIDENCE || confInt * 2 < highestConfidence) {
                if (false) Log.d(TAG, "confidence too low, dropping");
                break;
            }
            if (mLogger != null) mLogger.logLine(msg);
            String[] commands = semantic.trim().split(" ");

            // DIAL 650 867 5309
            // DIAL 867 5309
            // DIAL 911
            if ("DIAL".equalsIgnoreCase(commands[0])) {
                Uri uri = Uri.fromParts("tel", commands[1], null);
                String num =  formatNumber(commands[1]);
                if (num != null) {
                    addCallIntent(intents, uri,
                            literal.split(" ")[0].trim() + " " + num, "", 0);
                }
            }

            // CALL JACK JONES
            else if ("CALL".equalsIgnoreCase(commands[0]) && commands.length >= 7) {
                // parse the ids
                long contactId = Long.parseLong(commands[1]); // people table
                long phoneId   = Long.parseLong(commands[2]); // phones table
                long homeId    = Long.parseLong(commands[3]); // phones table
                long mobileId  = Long.parseLong(commands[4]); // phones table
                long workId    = Long.parseLong(commands[5]); // phones table
                long otherId   = Long.parseLong(commands[6]); // phones table
                Resources res  = mActivity.getResources();

                int count = 0;

                //
                // generate the best entry corresponding to what was said
                //

                // 'CALL JACK JONES AT HOME|MOBILE|WORK|OTHER'
                if (commands.length == 8) {
                    long spokenPhoneId =
                            "H".equalsIgnoreCase(commands[7]) ? homeId :
                            "M".equalsIgnoreCase(commands[7]) ? mobileId :
                            "W".equalsIgnoreCase(commands[7]) ? workId :
                            "O".equalsIgnoreCase(commands[7]) ? otherId :
                             VoiceContact.ID_UNDEFINED;
                    if (spokenPhoneId != VoiceContact.ID_UNDEFINED) {
                        addCallIntent(intents, ContentUris.withAppendedId(
                                Phone.CONTENT_URI, spokenPhoneId),
                                literal, commands[7], 0);
                        count++;
                    }
                }

                // 'CALL JACK JONES', with valid default phoneId
                else if (commands.length == 7) {
                    String phoneType = null;
                    CharSequence phoneIdMsg = null;
                    if (phoneId == VoiceContact.ID_UNDEFINED) {
                        phoneType = null;
                        phoneIdMsg = null;
                    } else if (phoneId == homeId) {
                        phoneType = "H";
                        phoneIdMsg = res.getText(R.string.at_home);
                    } else if (phoneId == mobileId) {
                        phoneType = "M";
                        phoneIdMsg = res.getText(R.string.on_mobile);
                    } else if (phoneId == workId) {
                        phoneType = "W";
                        phoneIdMsg = res.getText(R.string.at_work);
                    } else if (phoneId == otherId) {
                        phoneType = "O";
                        phoneIdMsg = res.getText(R.string.at_other);
                    }
                    if (phoneIdMsg != null) {
                        addCallIntent(intents, ContentUris.withAppendedId(
                                Phone.CONTENT_URI, phoneId),
                                literal + phoneIdMsg, phoneType, 0);
                        count++;
                    }
                }

                if (count == 0 || !mMinimizeResults) {
                    //
                    // generate all other entries for this person
                    //

                    // trim last two words, ie 'at home', etc
                    String lit = literal;
                    if (commands.length == 8) {
                        String[] words = literal.trim().split(" ");
                        StringBuffer sb = new StringBuffer();
                        for (int i = 0; i < words.length - 2; i++) {
                            if (i != 0) {
                                sb.append(' ');
                            }
                            sb.append(words[i]);
                        }
                        lit = sb.toString();
                    }

                    //  add 'CALL JACK JONES at home' using phoneId
                    if (homeId != VoiceContact.ID_UNDEFINED) {
                        addCallIntent(intents, ContentUris.withAppendedId(
                                Phone.CONTENT_URI, homeId),
                                lit + res.getText(R.string.at_home), "H",  0);
                        count++;
                    }

                    //  add 'CALL JACK JONES on mobile' using mobileId
                    if (mobileId != VoiceContact.ID_UNDEFINED) {
                        addCallIntent(intents, ContentUris.withAppendedId(
                                Phone.CONTENT_URI, mobileId),
                                lit + res.getText(R.string.on_mobile), "M", 0);
                        count++;
                    }

                    //  add 'CALL JACK JONES at work' using workId
                    if (workId != VoiceContact.ID_UNDEFINED) {
                        addCallIntent(intents, ContentUris.withAppendedId(
                                Phone.CONTENT_URI, workId),
                                lit + res.getText(R.string.at_work), "W", 0);
                        count++;
                    }

                    //  add 'CALL JACK JONES at other' using otherId
                    if (otherId != VoiceContact.ID_UNDEFINED) {
                        addCallIntent(intents, ContentUris.withAppendedId(
                                Phone.CONTENT_URI, otherId),
                                lit + res.getText(R.string.at_other), "O", 0);
                        count++;
                    }
                }

                //
                // if no other entries were generated, use the personId
                //

                // add 'CALL JACK JONES', with valid personId
                if (count == 0 && contactId != VoiceContact.ID_UNDEFINED) {
                    // TODO: what should really happen here is, we find
                    // all phones for this contact, and create a label that
                    // says "call person X at phone type Y", and add intents
                    // for each of them to the return list.
                    // It's too late in <del>Gingerbread</del> ICS to add the strings that
                    // would be required for this, so we'll just ignore this person.
                    // See also issue 3090362 and 5551677

                    // ACTION_CALL_PRIVILEGED does not work with Contacts.CONTENT_URI.
                    // addCallIntent(intents, ContentUris.withAppendedId(
                    //         Contacts.CONTENT_URI, contactId), literal, "", 0);
                }
            }

            else if ("X".equalsIgnoreCase(commands[0])) {
                Intent intent = new Intent(RecognizerEngine.ACTION_RECOGNIZER_RESULT, null);
                intent.putExtra(RecognizerEngine.SENTENCE_EXTRA, literal);
                intent.putExtra(RecognizerEngine.SEMANTIC_EXTRA, semantic);
                addIntent(intents, intent);
            }

            // "CALL VoiceMail"
            else if ("voicemail".equalsIgnoreCase(commands[0]) && commands.length == 1) {
                addCallIntent(intents, Uri.fromParts("voicemail", "x", null),
                        literal, "", Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            }

            // "REDIAL"
            else if ("redial".equalsIgnoreCase(commands[0]) && commands.length == 1) {
                String number = VoiceContact.redialNumber(mActivity);
                if (number != null) {
                    addCallIntent(intents, Uri.fromParts("tel", number, null),
                            literal, "", Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                }
            }

            // "Intent ..."
            else if ("Intent".equalsIgnoreCase(commands[0])) {
                for (int i = 1; i < commands.length; i++) {
                    try {
                        Intent intent = Intent.getIntent(commands[i]);
                        if (intent.getStringExtra(SENTENCE_EXTRA) == null) {
                            intent.putExtra(SENTENCE_EXTRA, literal);
                        }
                        addIntent(intents, intent);
                    } catch (URISyntaxException e) {
                        if (false) {
                            Log.d(TAG, "onRecognitionSuccess: poorly " +
                                    "formed URI in grammar" + e);
                        }
                    }
                }
            }

            // "OPEN ..."
            else if ("OPEN".equalsIgnoreCase(commands[0]) && mAllowOpenEntries) {
                PackageManager pm = mActivity.getPackageManager();
                if (commands.length > 1 & mOpenEntries != null) {
                    // the semantic value is equal to the literal in this case.
                    // We have to do the mapping from this text to the
                    // componentname ourselves.  See Bug: 2457238.
                    // The problem is that the list of all componentnames
                    // can be pretty large and overflow the limit that
                    // the recognizer has.
                    String meaning = mOpenEntries.get(commands[1]);
                    String[] components = meaning.trim().split(" ");
                    for (int i=0; i < components.length; i++) {
                        String component = components[i];
                        Intent intent = new Intent(Intent.ACTION_MAIN);
                        intent.addCategory("android.intent.category.VOICE_LAUNCH");
                        String packageName = component.substring(
                                0, component.lastIndexOf('/'));
                        String className = component.substring(
                                component.lastIndexOf('/')+1, component.length());
                        intent.setClassName(packageName, className);
                        List<ResolveInfo> riList = pm.queryIntentActivities(intent, 0);
                        for (ResolveInfo ri : riList) {
                            String label = ri.loadLabel(pm).toString();
                            intent = new Intent(Intent.ACTION_MAIN);
                            intent.addCategory("android.intent.category.VOICE_LAUNCH");
                            intent.setClassName(packageName, className);
                            intent.putExtra(SENTENCE_EXTRA, literal.split(" ")[0] + " " + label);
                            addIntent(intents, intent);
                        }
                    }
                }
            }

            // can't parse result
            else {
                if (false) Log.d(TAG, "onRecognitionSuccess: parse error");
            }
        }

        // log if requested
        if (mLogger != null) mLogger.logIntents(intents);

        // bail out if cancelled
        if (Thread.interrupted()) throw new InterruptedException();

        if (intents.size() == 0) {
            // TODO: strip HOME|MOBILE|WORK and try default here?
            recognizerClient.onRecognitionFailure("No Intents generated");
        }
        else {
            recognizerClient.onRecognitionSuccess(
                    intents.toArray(new Intent[intents.size()]));
        }
    }

    // only add if different
    private static void addCallIntent(ArrayList<Intent> intents, Uri uri, String literal,
            String phoneType, int flags) {
        Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, uri).
        setFlags(flags).
        putExtra(SENTENCE_EXTRA, literal).
        putExtra(PHONE_TYPE_EXTRA, phoneType);
        addIntent(intents, intent);
    }
}
