/*
 * Copyright (C) 2012 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.mail.widget;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.content.Loader.OnLoadCompleteListener;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Looper;
import android.support.v4.app.TaskStackBuilder;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.CharacterStyle;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

import com.android.mail.R;
import com.android.mail.browse.ConversationItemView;
import com.android.mail.browse.SendersView;
import com.android.mail.compose.ComposeActivity;
import com.android.mail.preferences.MailPrefs;
import com.android.mail.providers.Account;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.ConversationListQueryParameters;
import com.android.mail.providers.UIProvider.FolderType;
import com.android.mail.utils.AccountUtils;
import com.android.mail.utils.DelayedTaskHandler;
import com.android.mail.utils.FolderUri;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;

import java.util.ArrayList;
import java.util.List;

public class WidgetService extends RemoteViewsService {
    /**
     * Lock to avoid race condition between widgets.
     */
    private static final Object sWidgetLock = new Object();

    private static final String LOG_TAG = LogTag.getLogTag();

    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new MailFactory(getApplicationContext(), intent, this);
    }

    protected void configureValidAccountWidget(Context context, RemoteViews remoteViews,
            int appWidgetId, Account account, final int folderType, final int folderCapabilities,
            final Uri folderUri, final Uri folderConversationListUri, String folderName) {
        configureValidAccountWidget(context, remoteViews, appWidgetId, account, folderType,
                folderCapabilities, folderUri, folderConversationListUri, folderName,
                WidgetService.class);
    }

    /**
     * Modifies the remoteView for the given account and folder.
     */
    public static void configureValidAccountWidget(Context context, RemoteViews remoteViews,
            int appWidgetId, Account account, final int folderType, final int folderCapabilities,
            final Uri folderUri, final Uri folderConversationListUri, String folderDisplayName,
            Class<?> widgetService) {
        remoteViews.setViewVisibility(R.id.widget_folder, View.VISIBLE);

        // If the folder or account name are empty, we don't want to overwrite the valid data that
        // had been saved previously.  Since the launcher will save the state of the remote views
        // we should rely on the fact that valid data has been saved.  But we should still log this,
        // as it shouldn't happen
        if (TextUtils.isEmpty(folderDisplayName) || TextUtils.isEmpty(account.getDisplayName())) {
            LogUtils.e(LOG_TAG, new Error(),
                    "Empty folder or account name.  account: %s, folder: %s",
                    account.getEmailAddress(), folderDisplayName);
        }
        if (!TextUtils.isEmpty(folderDisplayName)) {
            remoteViews.setTextViewText(R.id.widget_folder, folderDisplayName);
        }

        remoteViews.setViewVisibility(R.id.widget_compose, View.VISIBLE);
        remoteViews.setViewVisibility(R.id.conversation_list, View.VISIBLE);
        remoteViews.setViewVisibility(R.id.empty_conversation_list, View.VISIBLE);
        remoteViews.setViewVisibility(R.id.widget_folder_not_synced, View.GONE);
        remoteViews.setViewVisibility(R.id.widget_configuration, View.GONE);
        remoteViews.setEmptyView(R.id.conversation_list, R.id.empty_conversation_list);

        WidgetService.configureValidWidgetIntents(context, remoteViews, appWidgetId, account,
                folderType, folderCapabilities, folderUri, folderConversationListUri,
                folderDisplayName, widgetService);
    }

    public static void configureValidWidgetIntents(Context context, RemoteViews remoteViews,
            int appWidgetId, Account account, final int folderType, final int folderCapabilities,
            final Uri folderUri, final Uri folderConversationListUri,
            final String folderDisplayName, Class<?> serviceClass) {
        remoteViews.setViewVisibility(R.id.widget_configuration, View.GONE);


        // Launch an intent to avoid ANRs
        final Intent intent = new Intent(context, serviceClass);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        intent.putExtra(Utils.EXTRA_ACCOUNT, account.serialize());
        intent.putExtra(BaseWidgetProvider.EXTRA_FOLDER_TYPE, folderType);
        intent.putExtra(BaseWidgetProvider.EXTRA_FOLDER_CAPABILITIES, folderCapabilities);
        intent.putExtra(BaseWidgetProvider.EXTRA_FOLDER_URI, folderUri);
        intent.putExtra(BaseWidgetProvider.EXTRA_FOLDER_CONVERSATION_LIST_URI,
                folderConversationListUri);
        intent.putExtra(BaseWidgetProvider.EXTRA_FOLDER_DISPLAY_NAME, folderDisplayName);
        intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
        remoteViews.setRemoteAdapter(R.id.conversation_list, intent);
        // Open mail app when click on header
        final Intent mailIntent = Utils.createViewFolderIntent(context, folderUri, account);
        mailIntent.setPackage(context.getPackageName());
        PendingIntent clickIntent = PendingIntent.getActivity(context, 0, mailIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.widget_header, clickIntent);

        // On click intent for Compose
        final Intent composeIntent = new Intent();
        composeIntent.setPackage(context.getPackageName());
        composeIntent.setAction(Intent.ACTION_SEND);
        composeIntent.putExtra(Utils.EXTRA_ACCOUNT, account.serialize());
        composeIntent.setData(account.composeIntentUri);
        composeIntent.putExtra(ComposeActivity.EXTRA_FROM_EMAIL_TASK, true);
        if (account.composeIntentUri != null) {
            composeIntent.putExtra(Utils.EXTRA_COMPOSE_URI, account.composeIntentUri);
        }

        // Build a task stack that forces the conversation list on the stack before the compose
        // activity.
        final TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
        clickIntent = taskStackBuilder.addNextIntent(mailIntent)
                .addNextIntent(composeIntent)
                .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.widget_compose, clickIntent);

        // On click intent for Conversation
        final Intent conversationIntent = new Intent();
        conversationIntent.setPackage(context.getPackageName());
        conversationIntent.setAction(Intent.ACTION_VIEW);
        clickIntent = PendingIntent.getActivity(context, 0, conversationIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setPendingIntentTemplate(R.id.conversation_list, clickIntent);
    }

    /**
     * Persists the information about the specified widget.
     */
    public static void saveWidgetInformation(Context context, int appWidgetId, Account account,
                final String folderUri) {
        MailPrefs.get(context).configureWidget(appWidgetId, account, folderUri);
    }

    /**
     * Returns true if this widget id has been configured and saved.
     */
    public boolean isWidgetConfigured(Context context, int appWidgetId, Account account) {
        return isAccountValid(context, account) &&
                MailPrefs.get(context).isWidgetConfigured(appWidgetId);
    }

    protected boolean isAccountValid(Context context, Account account) {
        if (account != null) {
            Account[] accounts = AccountUtils.getSyncingAccounts(context);
            for (Account existing : accounts) {
                if (existing != null && account.uri.equals(existing.uri)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Remote Views Factory for Mail Widget.
     */
    protected static class MailFactory
            implements RemoteViewsService.RemoteViewsFactory, OnLoadCompleteListener<Cursor> {
        private static final int MAX_CONVERSATIONS_COUNT = 25;
        private static final int MAX_SENDERS_LENGTH = 25;

        private static final int FOLDER_LOADER_ID = 0;
        private static final int CONVERSATION_CURSOR_LOADER_ID = 1;
        private static final int ACCOUNT_LOADER_ID = 2;

        private final Context mContext;
        private final int mAppWidgetId;
        private final Account mAccount;
        private final int mFolderType;
        private final int mFolderCapabilities;
        private final Uri mFolderUri;
        private final Uri mFolderConversationListUri;
        private final String mFolderDisplayName;
        private final WidgetConversationListItemViewBuilder mWidgetConversationListItemViewBuilder;
        private CursorLoader mConversationCursorLoader;
        private Cursor mConversationCursor;
        private CursorLoader mFolderLoader;
        private CursorLoader mAccountLoader;
        private FolderUpdateHandler mFolderUpdateHandler;
        private int mFolderCount;
        private boolean mShouldShowViewMore;
        private boolean mFolderInformationShown = false;
        private final WidgetService mService;
        private String mSendersSplitToken;
        private String mElidedPaddingToken;

        public MailFactory(Context context, Intent intent, WidgetService service) {
            mContext = context;
            mAppWidgetId = intent.getIntExtra(
                    AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
            mAccount = Account.newInstance(intent.getStringExtra(Utils.EXTRA_ACCOUNT));
            mFolderType = intent.getIntExtra(WidgetProvider.EXTRA_FOLDER_TYPE, FolderType.DEFAULT);
            mFolderCapabilities = intent.getIntExtra(WidgetProvider.EXTRA_FOLDER_CAPABILITIES, 0);
            mFolderDisplayName = intent.getStringExtra(WidgetProvider.EXTRA_FOLDER_DISPLAY_NAME);

            final Uri folderUri = intent.getParcelableExtra(WidgetProvider.EXTRA_FOLDER_URI);
            final Uri folderConversationListUri =
                    intent.getParcelableExtra(WidgetProvider.EXTRA_FOLDER_CONVERSATION_LIST_URI);
            if (folderUri != null && folderConversationListUri != null) {
                mFolderUri = folderUri;
                mFolderConversationListUri = folderConversationListUri;
            } else {
                // This is a old intent created in version UR8 (or earlier).
                String folderString = intent.getStringExtra(Utils.EXTRA_FOLDER);
                //noinspection deprecation
                Folder folder = Folder.fromString(folderString);
                if (folder != null) {
                    mFolderUri = folder.folderUri.fullUri;
                    mFolderConversationListUri = folder.conversationListUri;
                } else {
                    mFolderUri = Uri.EMPTY;
                    mFolderConversationListUri = Uri.EMPTY;
                    // this will mark the widget as unconfigured
                    BaseWidgetProvider.updateWidget(mContext, mAppWidgetId, mAccount, mFolderType,
                            mFolderCapabilities, mFolderUri, mFolderConversationListUri,
                            mFolderDisplayName);
                }
            }

            mWidgetConversationListItemViewBuilder = new WidgetConversationListItemViewBuilder(
                    context);
            mService = service;
        }

        @Override
        public void onCreate() {
            // Save the map between widgetId and account to preference
            saveWidgetInformation(mContext, mAppWidgetId, mAccount, mFolderUri.toString());

            // If the account of this widget has been removed, we want to update the widget to
            // "Tap to configure" mode.
            if (!mService.isWidgetConfigured(mContext, mAppWidgetId, mAccount)) {
                BaseWidgetProvider.updateWidget(mContext, mAppWidgetId, mAccount, mFolderType,
                        mFolderCapabilities, mFolderUri, mFolderConversationListUri,
                        mFolderDisplayName);
            }

            mFolderInformationShown = false;

            // We want to limit the query result to 25 and don't want these queries to cause network
            // traffic
            // We also want this cursor to receive notifications on all changes.  Any change that
            // the user made locally, the default policy of the UI provider is to not send
            // notifications for.  But in this case, since the widget is not using the
            // ConversationCursor instance that the UI is using, the widget would not be updated.
            final Uri.Builder builder = mFolderConversationListUri.buildUpon();
            final String maxConversations = Integer.toString(MAX_CONVERSATIONS_COUNT);
            final Uri widgetConversationQueryUri = builder
                    .appendQueryParameter(ConversationListQueryParameters.LIMIT, maxConversations)
                    .appendQueryParameter(ConversationListQueryParameters.USE_NETWORK,
                            Boolean.FALSE.toString())
                    .appendQueryParameter(ConversationListQueryParameters.ALL_NOTIFICATIONS,
                            Boolean.TRUE.toString()).build();

            final Resources res = mContext.getResources();
            mConversationCursorLoader = new CursorLoader(mContext, widgetConversationQueryUri,
                    UIProvider.CONVERSATION_PROJECTION, null, null, null);
            mConversationCursorLoader.registerListener(CONVERSATION_CURSOR_LOADER_ID, this);
            mConversationCursorLoader.setUpdateThrottle(
                    res.getInteger(R.integer.widget_refresh_delay_ms));
            mConversationCursorLoader.startLoading();
            mSendersSplitToken = res.getString(R.string.senders_split_token);
            mElidedPaddingToken = res.getString(R.string.elided_padding_token);
            mFolderLoader = new CursorLoader(mContext, mFolderUri, UIProvider.FOLDERS_PROJECTION,
                    null, null, null);
            mFolderLoader.registerListener(FOLDER_LOADER_ID, this);
            mFolderUpdateHandler = new FolderUpdateHandler(
                    res.getInteger(R.integer.widget_folder_refresh_delay_ms));
            mFolderUpdateHandler.scheduleTask();

            mAccountLoader = new CursorLoader(mContext, mAccount.uri,
                    UIProvider.ACCOUNTS_PROJECTION_NO_CAPABILITIES, null, null, null);
            mAccountLoader.registerListener(ACCOUNT_LOADER_ID, this);
            mAccountLoader.startLoading();
        }

        @Override
        public void onDestroy() {
            synchronized (sWidgetLock) {
                if (mConversationCursorLoader != null) {
                    mConversationCursorLoader.reset();
                    mConversationCursorLoader.unregisterListener(this);
                    mConversationCursorLoader = null;
                }

                // The Loader should close the cursor, so just unset the reference
                // to it here.
                mConversationCursor = null;
            }

            if (mFolderLoader != null) {
                mFolderLoader.reset();
                mFolderLoader.unregisterListener(this);
                mFolderLoader = null;
            }

            if (mAccountLoader != null) {
                mAccountLoader.reset();
                mAccountLoader.unregisterListener(this);
                mAccountLoader = null;
            }
        }

        @Override
        public void onDataSetChanged() {
            // We are not using this as signal to requery the cursor.  The query will be started
            // in the following ways:
            // 1) The Service is started and the loader is started in onCreate()
            //       This will happen when the service is not running, and
            //       AppWidgetManager#notifyAppWidgetViewDataChanged() is called
            // 2) The service is running, with a previously created loader.  The loader is watching
            //    for updates from the existing cursor.  If one is seen, the loader will load a new
            //    cursor in the background.
            mFolderUpdateHandler.scheduleTask();
        }

        /**
         * Returns the number of items should be shown in the widget list.  This method also updates
         * the boolean that indicates whether the "show more" item should be shown.
         * @return the number of items to be displayed in the list.
         */
        @Override
        public int getCount() {
            synchronized (sWidgetLock) {
                final int count = getConversationCount();
                final int cursorCount = mConversationCursor != null ?
                        mConversationCursor.getCount() : 0;
                mShouldShowViewMore = count < cursorCount || count < mFolderCount;
                return count + (mShouldShowViewMore ? 1 : 0);
            }
        }

        /**
         * Returns the number of conversations that should be shown in the widget.  This method
         * doesn't update the boolean that indicates that the "show more" item should be included
         * in the list.
         * @return count
         */
        private int getConversationCount() {
            synchronized (sWidgetLock) {
                final int cursorCount = mConversationCursor != null ?
                        mConversationCursor.getCount() : 0;
                return Math.min(cursorCount, MAX_CONVERSATIONS_COUNT);
            }
        }

        /**
         * @return the {@link RemoteViews} for a specific position in the list.
         */
        @Override
        public RemoteViews getViewAt(int position) {
            synchronized (sWidgetLock) {
                // "View more conversations" view.
                if (mConversationCursor == null || mConversationCursor.isClosed()
                        || (mShouldShowViewMore && position >= getConversationCount())) {
                    return getViewMoreConversationsView();
                }

                if (!mConversationCursor.moveToPosition(position)) {
                    // If we ever fail to move to a position, return the
                    // "View More conversations"
                    // view.
                    LogUtils.e(LOG_TAG, "Failed to move to position %d in the cursor.", position);
                    return getViewMoreConversationsView();
                }

                Conversation conversation = new Conversation(mConversationCursor);
                // Split the senders and status from the instructions.

                ArrayList<SpannableString> senders = new ArrayList<SpannableString>();
                SendersView.format(mContext, conversation.conversationInfo, "",
                        MAX_SENDERS_LENGTH, senders, null, null, mAccount,
                        Folder.shouldShowRecipients(mFolderCapabilities), true);
                final SpannableStringBuilder senderBuilder = elideParticipants(senders);

                // Get styled date.
                CharSequence date = DateUtils.getRelativeTimeSpanString(mContext,
                        conversation.dateMs);

                final int ignoreFolderType;
                if ((mFolderType & FolderType.INBOX) != 0) {
                    ignoreFolderType = FolderType.INBOX;
                } else {
                    ignoreFolderType = -1;
                }

                // Load up our remote view.
                RemoteViews remoteViews = mWidgetConversationListItemViewBuilder.getStyledView(
                        mContext, date, conversation, new FolderUri(mFolderUri), ignoreFolderType,
                        senderBuilder,
                        ConversationItemView.filterTag(mContext, conversation.subject));

                // On click intent.
                remoteViews.setOnClickFillInIntent(R.id.widget_conversation_list_item,
                        Utils.createViewConversationIntent(mContext, conversation, mFolderUri,
                                mAccount));

                return remoteViews;
            }
        }

        private SpannableStringBuilder elideParticipants(List<SpannableString> parts) {
            final SpannableStringBuilder builder = new SpannableStringBuilder();
            SpannableString prevSender = null;

            boolean skipToHeader = false;

            // start with "To: " if we're showing recipients
            if (Folder.shouldShowRecipients(mFolderCapabilities)) {
                builder.append(SendersView.getFormattedToHeader());
                skipToHeader = true;
            }

            for (SpannableString sender : parts) {
                if (sender == null) {
                    LogUtils.e(LOG_TAG, "null sender while iterating over styledSenders");
                    continue;
                }
                CharacterStyle[] spans = sender.getSpans(0, sender.length(), CharacterStyle.class);
                if (SendersView.sElidedString.equals(sender.toString())) {
                    prevSender = sender;
                    sender = copyStyles(spans, mElidedPaddingToken + sender + mElidedPaddingToken);
                } else if (!skipToHeader && builder.length() > 0
                        && (prevSender == null || !SendersView.sElidedString.equals(prevSender
                                .toString()))) {
                    prevSender = sender;
                    sender = copyStyles(spans, mSendersSplitToken + sender);
                } else {
                    prevSender = sender;
                    skipToHeader = false;
                }
                builder.append(sender);
            }
            return builder;
        }

        private static SpannableString copyStyles(CharacterStyle[] spans, CharSequence newText) {
            SpannableString s = new SpannableString(newText);
            if (spans != null && spans.length > 0) {
                s.setSpan(spans[0], 0, s.length(), 0);
            }
            return s;
        }

        /**
         * @return the "View more conversations" view.
         */
        private RemoteViews getViewMoreConversationsView() {
            RemoteViews view = new RemoteViews(mContext.getPackageName(), R.layout.widget_loading);
            view.setTextViewText(
                    R.id.loading_text, mContext.getText(R.string.view_more_conversations));
            view.setOnClickFillInIntent(R.id.widget_loading,
                    Utils.createViewFolderIntent(mContext, mFolderUri, mAccount));
            return view;
        }

        @Override
        public RemoteViews getLoadingView() {
            RemoteViews view = new RemoteViews(mContext.getPackageName(), R.layout.widget_loading);
            view.setTextViewText(
                    R.id.loading_text, mContext.getText(R.string.loading_conversation));
            return view;
        }

        @Override
        public int getViewTypeCount() {
            return 2;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public void onLoadComplete(Loader<Cursor> loader, Cursor data) {
            final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
            final RemoteViews remoteViews =
                    new RemoteViews(mContext.getPackageName(), R.layout.widget);

            if (!mService.isWidgetConfigured(mContext, mAppWidgetId, mAccount)) {
                BaseWidgetProvider.updateWidget(mContext, mAppWidgetId, mAccount, mFolderType,
                        mFolderCapabilities, mFolderUri, mFolderConversationListUri,
                        mFolderDisplayName);
            }

            if (loader == mFolderLoader) {
                if (!isDataValid(data)) {
                    // Our folder may have disappeared on us
                    BaseWidgetProvider.updateWidget(mContext, mAppWidgetId, mAccount, mFolderType,
                            mFolderCapabilities, mFolderUri, mFolderConversationListUri,
                            mFolderDisplayName);

                    return;
                }

                final int unreadCount = data.getInt(UIProvider.FOLDER_UNREAD_COUNT_COLUMN);
                final String folderName = data.getString(UIProvider.FOLDER_NAME_COLUMN);
                mFolderCount = data.getInt(UIProvider.FOLDER_TOTAL_COUNT_COLUMN);

                if (!mFolderInformationShown && !TextUtils.isEmpty(folderName) &&
                        !TextUtils.isEmpty(mAccount.getDisplayName())) {
                    // We want to do a full update to the widget at least once, as the widget
                    // manager doesn't cache the state of the remote views when doing a partial
                    // widget update. This causes the folder name to be shown as blank if the state
                    // of the widget is restored.
                    mService.configureValidAccountWidget(mContext, remoteViews, mAppWidgetId,
                            mAccount, mFolderType, mFolderCapabilities, mFolderUri,
                            mFolderConversationListUri, folderName);
                    appWidgetManager.updateAppWidget(mAppWidgetId, remoteViews);
                    mFolderInformationShown = true;
                }

                // There is no reason to overwrite a valid non-null folder name with an empty string
                if (!TextUtils.isEmpty(folderName)) {
                    remoteViews.setViewVisibility(R.id.widget_folder, View.VISIBLE);
                    remoteViews.setViewVisibility(R.id.widget_compose, View.VISIBLE);
                    remoteViews.setTextViewText(R.id.widget_folder, folderName);
                } else {
                    LogUtils.e(LOG_TAG, "Empty folder name");
                }

                appWidgetManager.partiallyUpdateAppWidget(mAppWidgetId, remoteViews);
            } else if (loader == mConversationCursorLoader) {
                // We want to cache the new cursor
                synchronized (sWidgetLock) {
                    if (!isDataValid(data)) {
                        mConversationCursor = null;
                    } else {
                        mConversationCursor = data;
                    }
                }

                appWidgetManager.notifyAppWidgetViewDataChanged(mAppWidgetId,
                        R.id.conversation_list);

                if (mConversationCursor == null || mConversationCursor.getCount() == 0) {
                    remoteViews.setTextViewText(R.id.empty_conversation_list,
                            mContext.getString(R.string.empty_folder));
                    appWidgetManager.partiallyUpdateAppWidget(mAppWidgetId, remoteViews);
                }
            } else if (loader == mAccountLoader) {
                BaseWidgetProvider.updateWidget(mContext, mAppWidgetId, mAccount, mFolderType,
                        mFolderCapabilities, mFolderUri, mFolderConversationListUri,
                        mFolderDisplayName);
            }
        }

        /**
         * Returns a boolean indicating whether this cursor has valid data.
         * Note: This seeks to the first position in the cursor
         */
        private static boolean isDataValid(Cursor cursor) {
            return cursor != null && !cursor.isClosed() && cursor.moveToFirst();
        }

        /**
         * A {@link DelayedTaskHandler} to throttle folder update to a reasonable rate.
         */
        private class FolderUpdateHandler extends DelayedTaskHandler {
            public FolderUpdateHandler(int refreshDelay) {
                super(Looper.myLooper(), refreshDelay);
            }

            @Override
            protected void performTask() {
                // Start the loader. The cached data will be returned if present.
                if (mFolderLoader != null) {
                    mFolderLoader.startLoading();
                }
            }
        }
    }
}
