172ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal/*******************************************************************************
272ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      Copyright (C) 2012 Google Inc.
372ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      Licensed to The Android Open Source Project.
472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *
572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      Licensed under the Apache License, Version 2.0 (the "License");
672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      you may not use this file except in compliance with the License.
772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      You may obtain a copy of the License at
872ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *
972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *           http://www.apache.org/licenses/LICENSE-2.0
1072ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *
1172ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      Unless required by applicable law or agreed to in writing, software
1272ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      distributed under the License is distributed on an "AS IS" BASIS,
1372ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      See the License for the specific language governing permissions and
1572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *      limitations under the License.
1672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal *******************************************************************************/
1772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
1872ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwalpackage com.android.mail.ui;
1972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
2072ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwalimport com.android.mail.browse.ConversationCursor;
2172ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwalimport com.android.mail.providers.Conversation;
22c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwalimport com.android.mail.providers.Settings;
23c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwalimport com.android.mail.providers.UIProvider.AutoAdvance;
24b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag;
25af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwalimport com.android.mail.utils.LogUtils;
267dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwalimport java.util.Collection;
2772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
2872ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal/**
2972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal * An iterator over a conversation list that keeps track of the position of a conversation, and
3072ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal * updates the position accordingly when the underlying list data changes and the conversation
3172ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal * is in a different position.
3272ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal */
3372ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwalpublic class ConversationPositionTracker {
34b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook    protected static final String LOG_TAG = LogTag.getLogTag();
3572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
36937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook
37937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook    public interface Callbacks {
38937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        ConversationCursor getConversationListCursor();
39937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook    }
40937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook
41937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook
42af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal    /** Did we recalculate positions after updating the cursor? */
43af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal    private boolean mCursorDirty = false;
44135fd02e74ea8449b36c3dc44cd796e06a7e714dVikram Aggarwal    /** The currently selected conversation */
45135fd02e74ea8449b36c3dc44cd796e06a7e714dVikram Aggarwal    private Conversation mConversation;
46937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook
47937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook    private final Callbacks mCallbacks;
4872ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
4972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    /**
5072ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     * Constructs a position tracker that doesn't point to any specific conversation.
5172ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     */
52937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook    public ConversationPositionTracker(Callbacks callbacks) {
53937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        mCallbacks = callbacks;
5472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    }
5572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
56af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal    /** Move cursor to a specific position and return the conversation there */
57af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal    private Conversation conversationAtPosition(int position){
58937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        final ConversationCursor cursor = mCallbacks.getConversationListCursor();
59937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        cursor.moveToPosition(position);
6007fe8df87bde8732398434e55cce366a8528c181Andy Huang        final Conversation conv = cursor.getConversation();
61af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal        conv.position = position;
62af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal        return conv;
6372ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    }
6472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
6572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    /**
6672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     * @return the total number of conversations in the list.
6772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     */
687dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    private int getCount() {
69937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        final ConversationCursor cursor = mCallbacks.getConversationListCursor();
70937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        if (isDataLoaded(cursor)) {
71937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook            return cursor.getCount();
7272ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        } else {
7372ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal            return 0;
7472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        }
7572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    }
7672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
7772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    /**
7872ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     * @return the {@link Conversation} of the newer conversation by one position. If no such
7972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     * conversation exists, this method returns null.
8072ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     */
818f23bba2805f50315181abee153116ad4f78a01bVikram Aggarwal    private Conversation getNewer(Collection<Conversation> victims) {
827dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int pos = calculatePosition();
837dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        if (!isDataLoaded() || pos < 0) {
8472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal            return null;
8572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        }
867dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        // Walk backward from the existing position, trying to find a conversation that is not a
877dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        // victim.
887dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        pos--;
8972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        while (pos >= 0) {
907dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            final Conversation candidate = conversationAtPosition(pos);
917dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (!Conversation.contains(victims, candidate)) {
927dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal                return candidate;
9372ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal            }
9472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal            pos--;
9572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        }
9672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        return null;
9772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    }
9872ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
9972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    /**
10072ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     * @return the {@link Conversation} of the older conversation by one spot. If no such
10172ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     * conversation exists, this method returns null.
10272ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     */
1038f23bba2805f50315181abee153116ad4f78a01bVikram Aggarwal    private Conversation getOlder(Collection<Conversation> victims) {
1047dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int pos = calculatePosition();
1057dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        if (!isDataLoaded() || pos < 0) {
10672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal            return null;
10772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        }
1087dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        // Walk forward from the existing position, trying to find a conversation that is not a
1097dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        // victim.
1107dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        pos++;
1117dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        while (pos < getCount()) {
1127dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            final Conversation candidate = conversationAtPosition(pos);
1137dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (!Conversation.contains(victims, candidate)) {
1147dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal                return candidate;
11572ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal            }
11672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal            pos++;
11772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        }
11872ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        return null;
11972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    }
12072ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
12172ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    /**
1227dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * Initializes the tracker with initial conversation id and initial position. This invalidates
1237dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * the positions in the tracker. We need a valid cursor before we can bless the position as
1247dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * valid. This requires a call to
125937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook     * {@link #onCursorUpdated()}.
1267dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * TODO(viki): Get rid of this method and the mConversation field entirely.
12772ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     */
128135fd02e74ea8449b36c3dc44cd796e06a7e714dVikram Aggarwal    public void initialize(Conversation conversation) {
129135fd02e74ea8449b36c3dc44cd796e06a7e714dVikram Aggarwal        mConversation = conversation;
130af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal        mCursorDirty = true;
131a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal        calculatePosition(); // Return value discarded. Running for side effects.
13272ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    }
13372ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
13472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    /** @return whether or not we have a valid cursor to check the position of. */
135937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook    private static boolean isDataLoaded(ConversationCursor cursor) {
136937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        return cursor != null && !cursor.isClosed();
137937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook    }
138937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook
13972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    private boolean isDataLoaded() {
140937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        final ConversationCursor cursor = mCallbacks.getConversationListCursor();
141937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        return isDataLoaded(cursor);
14272ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    }
14372ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
14472ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    /**
145937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook     * Called when the conversation list changes.
14672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal     */
147937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook    public void onCursorUpdated() {
148af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal        mCursorDirty = true;
149af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal    }
15072ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal
151af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal    /**
152af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * Recalculate the current position based on the cursor. This needs to be done once for
153af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * each (Conversation, Cursor) pair. We could do this on every change of conversation or
154af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * cursor, but that would be wasteful, since the recalculation of position is only required
155af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * when transitioning to the next conversation. Transitions don't happen frequently, but
156af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * changes in conversation and cursor do. So we defer this till it is actually needed.
157af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     *
158af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * This method could change the current conversation if it cannot find the current conversation
159af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * in the cursor. When this happens, this method sets the current conversation to some safe
160af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * value and logs the reasons why it couldn't find the conversation.
161af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     *
162af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * Calling this method repeatedly is safe: it returns early if it detects it has already been
163af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     * called.
1647dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @return the position of the current conversation in the cursor.
165af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal     */
1667dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    private int calculatePosition() {
1677dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final int invalidPosition = -1;
168937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        final ConversationCursor cursor = mCallbacks.getConversationListCursor();
169baeb383d387fac29b340a819c0760b94c67f1a51Vikram Aggarwal        // If we have a valid position and nothing has changed, return that right away
170baeb383d387fac29b340a819c0760b94c67f1a51Vikram Aggarwal        if (!mCursorDirty) {
171baeb383d387fac29b340a819c0760b94c67f1a51Vikram Aggarwal            return mConversation.position;
172baeb383d387fac29b340a819c0760b94c67f1a51Vikram Aggarwal        }
173baeb383d387fac29b340a819c0760b94c67f1a51Vikram Aggarwal        // Ensure valid input data
174baeb383d387fac29b340a819c0760b94c67f1a51Vikram Aggarwal        if (cursor == null || mConversation == null) {
1757dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            return invalidPosition;
17672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal        }
177af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal        mCursorDirty = false;
178a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal        final int listSize = cursor.getCount();
179937c94f025ed55c19bd46c7c077fa3575ab6be52Paul Westbrook        if (!isDataLoaded(cursor) || listSize == 0) {
1807dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            return invalidPosition;
181af1ee0c4b6258530d8da30bcdb2a9cb403f70d5eVikram Aggarwal        }
18244c1571a6a81eda7dd508f74b64adae1e124101bPaul Westbrook
183c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook        final int foundPosition = cursor.getConversationPosition(mConversation.id);
184c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook        if (foundPosition >= 0) {
185c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            mConversation.position = foundPosition;
186c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            // Pre-emptively try to load the next cursor position so that the cursor window
187c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            // can be filled. The odd behavior of the ConversationCursor requires us to do
188c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            // this to ensure the adjacent conversation information is loaded for calls to
189c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            // hasNext.
190c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            cursor.moveToPosition(foundPosition + 1);
191c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            return foundPosition;
192c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook        }
19344c1571a6a81eda7dd508f74b64adae1e124101bPaul Westbrook
194c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook        // If the conversation is no longer found in the list, try to save the same position if
195c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook        // it is still a valid position. Otherwise, go back to a valid position until we can
196c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook        // find a valid one.
197a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal        final int newPosition;
198a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal        if (foundPosition >= listSize) {
199c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            // Go to the last position since our expected position is past this somewhere.
200a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal            newPosition = listSize - 1;
201a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal        } else {
202a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal            newPosition = foundPosition;
203c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook        }
20444c1571a6a81eda7dd508f74b64adae1e124101bPaul Westbrook
205a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal        // Did not keep the current conversation, so let's try to load the conversation from the
206a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal        // new position.
207a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal        if (isDataLoaded(cursor) && newPosition >= 0){
208c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            LogUtils.d(LOG_TAG, "ConversationPositionTracker: Could not find conversation %s" +
209c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook                    " in the cursor. Moving to position %d ", mConversation.toString(),
210c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook                    newPosition);
211c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            cursor.moveToPosition(newPosition);
212c8f2a3c6755b3b78af810aa73ab78487567cf074Paul Westbrook            mConversation = new Conversation(cursor);
213a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal            mConversation.position = newPosition;
21499e379ecc14a21c595a14d58c33aeee764f647dbPaul Westbrook        }
2157dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return newPosition;
21672ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal    }
217c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal
218c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal    /**
219c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal     * Get the next conversation according to the AutoAdvance settings and the list of
220c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal     * conversations available in the folder. If no next conversation can be found, this method
221c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal     * returns null.
222025eba8bfd4d0b5e248b6de0bda6f1129170fb41Vikram Aggarwal     * @param autoAdvance the auto advance preference for the user as an
223a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal     * {@link Settings#getAutoAdvanceSetting()} value.
2248f23bba2805f50315181abee153116ad4f78a01bVikram Aggarwal     * @param mTarget conversations to overlook while finding the next conversation. (These are
2258f23bba2805f50315181abee153116ad4f78a01bVikram Aggarwal     * usually the conversations to be deleted.)
226a91d00b4de3092b41af5f36436d3b49fe4586f64Vikram Aggarwal     * @return the next conversation to be shown, or null if no next conversation exists.
227c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal     */
2288f23bba2805f50315181abee153116ad4f78a01bVikram Aggarwal    public Conversation getNextConversation(int autoAdvance, Collection<Conversation> mTarget) {
2297dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final boolean getNewer = autoAdvance == AutoAdvance.NEWER;
2307dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final boolean getOlder = autoAdvance == AutoAdvance.OLDER;
2318f23bba2805f50315181abee153116ad4f78a01bVikram Aggarwal        final Conversation next = getNewer ? getNewer(mTarget) :
2328f23bba2805f50315181abee153116ad4f78a01bVikram Aggarwal            (getOlder ? getOlder(mTarget) : null);
233c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal        LogUtils.d(LOG_TAG, "ConversationPositionTracker.getNextConversation: " +
234c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal                "getNewer = %b, getOlder = %b, Next conversation is %s",
235c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal                getNewer, getOlder, next);
236c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal        return next;
237c7694221dfa5cec3f4ae290f2266b081b2639d80Vikram Aggarwal    }
238025eba8bfd4d0b5e248b6de0bda6f1129170fb41Vikram Aggarwal
23972ef2e7ce576ad13ce6179a6a8c74f8ecad9ae85Vikram Aggarwal}