/** original code: public void configureLoader(SmartDialCursorLoader loader) { */
  public void configureLoader(Loader<Cursor> loader) {

    LogUtils.d(TAG, "MTK-DialerSearch, configureLoader, getQueryString: " + getQueryString());

    if (DEBUG) {
      Log.v(TAG, "Configure Loader with query" + getQueryString());
    }

    if (DialerUtils.isDialerSearchEnabled()) {
      DialerSearchCursorLoader dialerSearchLoader = null;

      if (loader instanceof DialerSearchCursorLoader) {
        dialerSearchLoader = (DialerSearchCursorLoader) loader;
      } else {
        Log.w(TAG, "MTK-DiaerSearch, Not DialerSearchCursorLoader");
      }

      if (getQueryString() == null) {
        dialerSearchLoader.configureQuery("", true);
      } else {
        dialerSearchLoader.configureQuery(getQueryString(), true);
      }
    } else {
      SmartDialCursorLoader smartDialCursorLoader = null;

      if (loader instanceof DialerSearchCursorLoader) {
        smartDialCursorLoader = (SmartDialCursorLoader) loader;
      } else {
        Log.w(TAG, "MTK-DiaerSearch, Not SmartDialCursorLoader");
      }

      if (getQueryString() == null) {
        mNameMatcher = new SmartDialNameMatcher("", SmartDialPrefix.getMap());
        smartDialCursorLoader.configureQuery("");
      } else {
        smartDialCursorLoader.configureQuery(getQueryString());
        mNameMatcher =
            new SmartDialNameMatcher(
                PhoneNumberUtils.normalizeNumber(getQueryString()), SmartDialPrefix.getMap());
      }
    }
  }
  /**
   * Configures the query string to be used to find SmartDial matches.
   *
   * @param query The query string user typed.
   */
  public void configureQuery(String query, boolean isSmartQuery) {

    LogUtils.d(TAG, "MTK-DialerSearch, Configure new query to be " + query);

    if (isSmartQuery) {
      mQuery = SmartDialNameMatcher.normalizeNumber(query, SmartDialPrefix.getMap());
    } else {
      mQuery = query;
      if (DialerSearchUtils.isInValidDialpadString(mQuery)) {
        mRegularSearch = true;
      }
    }
    mContactsPrefs = new ContactsPreferences(mContext);
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mFirstLaunch = true;

    final Intent intent = getIntent();
    fixIntent(intent);

    setContentView(R.layout.dialtacts_activity);

    getActionBar().hide();

    // Add the favorites fragment, and the dialpad fragment, but only if savedInstanceState
    // is null. Otherwise the fragment manager takes care of recreating these fragments.
    if (savedInstanceState == null) {
      final PhoneFavoriteFragment phoneFavoriteFragment = new PhoneFavoriteFragment();

      final FragmentTransaction ft = getFragmentManager().beginTransaction();
      ft.add(R.id.dialtacts_frame, phoneFavoriteFragment, TAG_FAVORITES_FRAGMENT);
      ft.add(R.id.dialtacts_container, new DialpadFragment(), TAG_DIALPAD_FRAGMENT);
      ft.commit();
    } else {
      mSearchQuery = savedInstanceState.getString(KEY_SEARCH_QUERY);
      mInRegularSearch = savedInstanceState.getBoolean(KEY_IN_REGULAR_SEARCH_UI);
      mInDialpadSearch = savedInstanceState.getBoolean(KEY_IN_DIALPAD_SEARCH_UI);
      mFirstLaunch = savedInstanceState.getBoolean(KEY_FIRST_LAUNCH);
    }

    mBottomPaddingView = findViewById(R.id.dialtacts_bottom_padding);
    mFragmentsFrame = findViewById(R.id.dialtacts_frame);
    mActionBar = findViewById(R.id.fake_action_bar);
    prepareSearchView();

    if (UI.FILTER_CONTACTS_ACTION.equals(intent.getAction()) && savedInstanceState == null) {
      setupFilterText(intent);
    }

    setupFakeActionBarItems();

    mDialerDatabaseHelper = DatabaseHelperManager.getDatabaseHelper(this);
    SmartDialPrefix.initializeNanpSettings(this);
  }
  /**
   * Inserts prefixes of contact names to the prefix table.
   *
   * @param db Database pointer to the smartdial database.
   * @param nameCursor Cursor pointing to the list of distinct updated contacts.
   */
  @VisibleForTesting
  void insertNamePrefixes(SQLiteDatabase db, Cursor nameCursor) {
    final int columnIndexName = nameCursor.getColumnIndex(SmartDialDbColumns.DISPLAY_NAME_PRIMARY);
    final int columnIndexContactId = nameCursor.getColumnIndex(SmartDialDbColumns.CONTACT_ID);

    db.beginTransaction();
    try {
      final String sqlInsert =
          "INSERT INTO "
              + Tables.PREFIX_TABLE
              + " ("
              + PrefixColumns.CONTACT_ID
              + ", "
              + PrefixColumns.PREFIX
              + ") "
              + " VALUES (?, ?)";
      final SQLiteStatement insert = db.compileStatement(sqlInsert);

      while (nameCursor.moveToNext()) {
        /** Computes a list of prefixes of a given contact name. */
        final ArrayList<String> namePrefixes =
            SmartDialPrefix.generateNamePrefixes(nameCursor.getString(columnIndexName));

        for (String namePrefix : namePrefixes) {
          insert.bindLong(1, nameCursor.getLong(columnIndexContactId));
          insert.bindString(2, namePrefix);
          insert.executeInsert();
          insert.clearBindings();
        }
      }

      db.setTransactionSuccessful();
    } finally {
      db.endTransaction();
    }
  }
  /**
   * Inserts updated contacts as rows to the smartdial table.
   *
   * @param db Database pointer to the smartdial database.
   * @param updatedContactCursor Cursor pointing to the list of recently updated contacts.
   * @param currentMillis Current time to be recorded in the smartdial table as update timestamp.
   */
  @VisibleForTesting
  protected void insertUpdatedContactsAndNumberPrefix(
      SQLiteDatabase db, Cursor updatedContactCursor, Long currentMillis) {
    db.beginTransaction();
    try {
      final String sqlInsert =
          "INSERT INTO "
              + Tables.SMARTDIAL_TABLE
              + " ("
              + SmartDialDbColumns.DATA_ID
              + ", "
              + SmartDialDbColumns.NUMBER
              + ", "
              + SmartDialDbColumns.CONTACT_ID
              + ", "
              + SmartDialDbColumns.LOOKUP_KEY
              + ", "
              + SmartDialDbColumns.DISPLAY_NAME_PRIMARY
              + ", "
              + SmartDialDbColumns.PHOTO_ID
              + ", "
              + SmartDialDbColumns.LAST_TIME_USED
              + ", "
              + SmartDialDbColumns.TIMES_USED
              + ", "
              + SmartDialDbColumns.STARRED
              + ", "
              + SmartDialDbColumns.IS_SUPER_PRIMARY
              + ", "
              + SmartDialDbColumns.IN_VISIBLE_GROUP
              + ", "
              + SmartDialDbColumns.IS_PRIMARY
              + ", "
              + SmartDialDbColumns.LAST_SMARTDIAL_UPDATE_TIME
              + ") "
              + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
      final SQLiteStatement insert = db.compileStatement(sqlInsert);

      final String numberSqlInsert =
          "INSERT INTO "
              + Tables.PREFIX_TABLE
              + " ("
              + PrefixColumns.CONTACT_ID
              + ", "
              + PrefixColumns.PREFIX
              + ") "
              + " VALUES (?, ?)";
      final SQLiteStatement numberInsert = db.compileStatement(numberSqlInsert);

      updatedContactCursor.moveToPosition(-1);
      while (updatedContactCursor.moveToNext()) {
        insert.bindLong(1, updatedContactCursor.getLong(PhoneQuery.PHONE_ID));
        insert.bindString(2, updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER));
        insert.bindLong(3, updatedContactCursor.getLong(PhoneQuery.PHONE_CONTACT_ID));
        insert.bindString(4, updatedContactCursor.getString(PhoneQuery.PHONE_LOOKUP_KEY));
        final String displayName = updatedContactCursor.getString(PhoneQuery.PHONE_DISPLAY_NAME);
        if (displayName == null) {
          insert.bindString(5, mContext.getResources().getString(R.string.missing_name));
        } else {
          insert.bindString(5, displayName);
        }
        insert.bindLong(6, updatedContactCursor.getLong(PhoneQuery.PHONE_PHOTO_ID));
        insert.bindLong(7, updatedContactCursor.getLong(PhoneQuery.PHONE_LAST_TIME_USED));
        insert.bindLong(8, updatedContactCursor.getInt(PhoneQuery.PHONE_TIMES_USED));
        insert.bindLong(9, updatedContactCursor.getInt(PhoneQuery.PHONE_STARRED));
        insert.bindLong(10, updatedContactCursor.getInt(PhoneQuery.PHONE_IS_SUPER_PRIMARY));
        insert.bindLong(11, updatedContactCursor.getInt(PhoneQuery.PHONE_IN_VISIBLE_GROUP));
        insert.bindLong(12, updatedContactCursor.getInt(PhoneQuery.PHONE_IS_PRIMARY));
        insert.bindLong(13, currentMillis);
        insert.executeInsert();
        insert.clearBindings();

        final String contactPhoneNumber = updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER);
        final ArrayList<String> numberPrefixes =
            SmartDialPrefix.parseToNumberTokens(contactPhoneNumber);

        for (String numberPrefix : numberPrefixes) {
          numberInsert.bindLong(1, updatedContactCursor.getLong(PhoneQuery.PHONE_CONTACT_ID));
          numberInsert.bindString(2, numberPrefix);
          numberInsert.executeInsert();
          numberInsert.clearBindings();
        }
      }

      db.setTransactionSuccessful();
    } finally {
      db.endTransaction();
    }
  }