/**
   * Queries the Contacts database and loads results in background.
   *
   * @return Cursor of contacts that matches the SmartDial query.
   */
  @Override
  public Cursor loadInBackground() {

    LogUtils.d(TAG, "MTK-DialerSearch, Load in background. mQuery: " + mQuery);

    final DialerSearchHelper dialerSearchHelper =
        DialerSearchHelperManager.getDialerSearchHelper(mContext, mContactsPrefs);
    Cursor cursor = null;
    if (mRegularSearch) {
      cursor = dialerSearchHelper.getRegularDialerSearchResults(mQuery, mUseCallableUri);
    } else {
      cursor = dialerSearchHelper.getDialerSearchResults(mQuery);
    }
    if (cursor != null) {
      LogUtils.d(TAG, "MTK-DialerSearch, loadInBackground, result.getCount: " + cursor.getCount());

      return cursor;
    } else {
      Log.w(TAG, "MTK-DialerSearch, ----cursor is null----");
      return null;
    }

    // Following code maybe useful in the future
    //        final MatrixCursor result = new MatrixCursor(PhoneQuery.PROJECTION_PRIMARY);
    //        Object[] row = new Object[PhoneQuery.PROJECTION_PRIMARY.length];
    //        if (cursor != null) {
    //            cursor.moveToPosition(-1);
    //            while (cursor.moveToNext()) {
    //                row[PhoneQuery.PHONE_ID] = cursor.getLong(CONTACT_DATA_ID);
    //                row[PhoneQuery.PHONE_NUMBER] = cursor.getString(CONTACT_NUMBER);
    //                row[PhoneQuery.PHONE_INDICATE_PHONE_SIM_COLUMN_INDEX] =
    // cursor.getInt(INDICATE_PHONE_OR_SIM);
    //                row[PhoneQuery.CONTACT_ID] = cursor.getLong(CONTACT_ID);
    //                row[PhoneQuery.LOOKUP_KEY] = cursor.getString(CONTACT_LOOKUP);
    //                row[PhoneQuery.PHOTO_ID] = cursor.getLong(CONTACT_PHOTO_ID);
    //                if (cursor.getString(CONTACT_DISPLAY_NAME) != null) {
    //                    row[PhoneQuery.DISPLAY_NAME] = cursor.getString(CONTACT_DISPLAY_NAME);
    //                } else {
    //                    row[PhoneQuery.DISPLAY_NAME] = cursor.getString(CONTACT_NUMBER);
    //                }
    //                result.addRow(row);
    //            }
    //        } else {
    //            Log.w(TAG, "MTK-DialerSearch, ----cursor is null----");
    //        }
    //        if (cursor != null) {
    //            cursor.close();
    //            cursor = null;
    //        }
  }
  @Override
  public String getPhoneNumber(int position) {
    Cursor cursor = ((Cursor) getItem(position));
    if (cursor != null) {
      String phoneNumber = cursor.getString(PHONE_NUMBER_INDEX);
      LogUtils.d(TAG, "SmartDialNumberListAdatper: phoneNumber:" + phoneNumber);

      return phoneNumber;
    } else {
      Log.w(TAG, "Cursor was null in getPhoneNumber() call. Returning null instead.");
      return null;
    }
  }
  @Override
  public void onCanceled(Cursor cursor) {
    // modify for sometimes loader cannot return correct cursor issue.
    if (mCursor != cursor) {
      deliverResult(cursor);
      LogUtils.d(TAG, "MTK-DialerSearch, onCanceled(). force deliverResult cursor!");
      return;
    }
    super.onCanceled(cursor);

    /** The load has been canceled, so we should release the resources associated with 'data'. */
    releaseResources(cursor);
  }
  /**
   * 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
  public View onCreateView(
      LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View parentView = inflater.inflate(R.layout.lists_fragment, container, false);
    mViewPager = (ViewPager) parentView.findViewById(R.id.lists_pager);
    mViewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager());
    mViewPager.setAdapter(mViewPagerAdapter);
    mViewPager.setOffscreenPageLimit(2);
    mViewPager.setOnPageChangeListener(this);
    mViewPager.setCurrentItem(getRtlPosition(TAB_INDEX_SPEED_DIAL));

    LogUtils.d(TAG, "--- onCreateView ---");

    mTabTitles = new String[TAB_INDEX_COUNT];
    mTabTitles[TAB_INDEX_SPEED_DIAL] = getResources().getString(R.string.tab_speed_dial);
    mTabTitles[TAB_INDEX_RECENTS] = getResources().getString(R.string.tab_recents);
    mTabTitles[TAB_INDEX_ALL_CONTACTS] = getResources().getString(R.string.tab_all_contacts);

    mViewPagerTabs = (ViewPagerTabs) parentView.findViewById(R.id.lists_pager_header);
    mViewPagerTabs.setViewPager(mViewPager);
    addOnPageChangeListener(mViewPagerTabs);

    if (DEBUG) {
      LogUtils.d(TAG, "x: " + mViewPagerTabs.getLeft() + " ,y: " + mViewPagerTabs.getTop());
    }

    mShortcutCardsListView = (ListView) parentView.findViewById(R.id.shortcut_card_list);
    mShortcutCardsListView.setAdapter(mMergedAdapter);

    mRemoveView = (RemoveView) parentView.findViewById(R.id.remove_view);
    mRemoveViewContent = parentView.findViewById(R.id.remove_view_content);

    setupPaneLayout((OverlappingPaneLayout) parentView);

    return parentView;
  }
  @Override
  public boolean onCallsFetched(Cursor cursor) {
    mCallLogAdapter.setLoading(false);

    // Save the date of the most recent call log item
    if (cursor != null && cursor.moveToFirst()) {
      mCurrentCallShortcutDate = cursor.getLong(CallLogQuery.DATE);
    }

    LogUtils.d(TAG, "onCallsFetched");
    mCallLogAdapter.invalidateCache();
    mCallLogAdapter.changeCursor(cursor);
    mMergedAdapter.notifyDataSetChanged();
    // Return true; took ownership of cursor
    return true;
  }
  /** 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());
      }
    }
  }
  /**
   * Gets Uri for the list item at the given position.
   *
   * @param position Location of the data of interest.
   * @return Data Uri of the entry.
   */
  @Override
  public Uri getDataUri(int position) {
    Cursor cursor = ((Cursor) getItem(position));
    if (cursor != null) {
      /// M: Add for support dialer list item @{
      /**
       * Original code: long id = cursor.getLong(PhoneQuery.PHONE_ID); return
       * ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, id);
       */
      long id = cursor.getLong(PHONE_DATA_ID_INDEX);
      LogUtils.d(TAG, "SmartDialNumberListAdatper: DataId:" + id);

      if (id < 0) {
        return null;
      } else {
        return ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, id);
      }
      /// M: @}
    } else {
      Log.w(TAG, "Cursor was null in getDataUri() call. Returning null instead.");
      return null;
    }
  }