/**
 * Copyright (c) 2011, Google Inc.
 *
 * 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.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Fragment;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.Browser;
import android.support.annotation.Nullable;
import android.support.v4.text.TextUtilsCompat;
import android.support.v4.view.ViewCompat;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.TextAppearanceSpan;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.webkit.WebSettings;
import android.webkit.WebView;

import com.android.emailcommon.mail.Address;
import com.android.mail.R;
import com.android.mail.browse.ConversationCursor;
import com.android.mail.compose.ComposeActivity;
import com.android.mail.perf.SimpleTimer;
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.EditSettingsExtras;
import com.android.mail.ui.HelpActivity;
import com.google.android.mail.common.html.parser.HtmlDocument;
import com.google.android.mail.common.html.parser.HtmlParser;
import com.google.android.mail.common.html.parser.HtmlTree;
import com.google.android.mail.common.html.parser.HtmlTreeBuilder;

import org.json.JSONObject;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Locale;
import java.util.Map;

public class Utils {
    /**
     * longest extension we recognize is 4 characters (e.g. "html", "docx")
     */
    private static final int FILE_EXTENSION_MAX_CHARS = 4;
    public static final String SENDER_LIST_TOKEN_ELIDED = "e";
    public static final String SENDER_LIST_TOKEN_NUM_MESSAGES = "n";
    public static final String SENDER_LIST_TOKEN_NUM_DRAFTS = "d";
    public static final String SENDER_LIST_TOKEN_LITERAL = "l";
    public static final String SENDER_LIST_TOKEN_SENDING = "s";
    public static final String SENDER_LIST_TOKEN_SEND_FAILED = "f";
    public static final Character SENDER_LIST_SEPARATOR = '\n';

    public static final String EXTRA_ACCOUNT = "account";
    public static final String EXTRA_ACCOUNT_URI = "accountUri";
    public static final String EXTRA_FOLDER_URI = "folderUri";
    public static final String EXTRA_FOLDER = "folder";
    public static final String EXTRA_COMPOSE_URI = "composeUri";
    public static final String EXTRA_CONVERSATION = "conversationUri";
    public static final String EXTRA_FROM_NOTIFICATION = "notification";
    public static final String EXTRA_IGNORE_INITIAL_CONVERSATION_LIMIT =
            "ignore-initial-conversation-limit";

    private static final String MAILTO_SCHEME = "mailto";

    /** Extra tag for debugging the blank fragment problem. */
    public static final String VIEW_DEBUGGING_TAG = "MailBlankFragment";

    /*
     * Notifies that changes happened. Certain UI components, e.g., widgets, can
     * register for this {@link Intent} and update accordingly. However, this
     * can be very broad and is NOT the preferred way of getting notification.
     */
    // TODO: UI Provider has this notification URI?
    public static final String ACTION_NOTIFY_DATASET_CHANGED =
            "com.android.mail.ACTION_NOTIFY_DATASET_CHANGED";

    /** Parameter keys for context-aware help. */
    private static final String SMART_HELP_LINK_PARAMETER_NAME = "p";

    private static final String SMART_LINK_APP_VERSION = "version";
    private static String sVersionCode = null;

    private static final int SCALED_SCREENSHOT_MAX_HEIGHT_WIDTH = 600;

    private static final String APP_VERSION_QUERY_PARAMETER = "appVersion";
    private static final String FOLDER_URI_QUERY_PARAMETER = "folderUri";

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

    public static final boolean ENABLE_CONV_LOAD_TIMER = false;
    public static final SimpleTimer sConvLoadTimer =
            new SimpleTimer(ENABLE_CONV_LOAD_TIMER).withSessionName("ConvLoadTimer");

    public static boolean isRunningJellybeanOrLater() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
    }

    public static boolean isRunningJBMR1OrLater() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
    }

    public static boolean isRunningKitkatOrLater() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    }

    public static boolean isRunningLOrLater() {
        //TODO: Update this to the L SDK once defined. Right now it is fine to use the watch
        // build version number, as this app woll not be running on watch devices
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH;
    }

    /**
     * @return Whether we are running on a low memory device.  This is used to disable certain
     * memory intensive features in the app.
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static boolean isLowRamDevice(Context context) {
        if (isRunningKitkatOrLater()) {
            final ActivityManager am = (ActivityManager) context.getSystemService(
                    Context.ACTIVITY_SERVICE);
            // This will be null when running unit tests
            return am != null && am.isLowRamDevice();
        } else {
            return false;
        }
    }

    /**
     * Sets WebView in a restricted mode suitable for email use.
     *
     * @param webView The WebView to restrict
     */
    public static void restrictWebView(WebView webView) {
        WebSettings webSettings = webView.getSettings();
        webSettings.setSavePassword(false);
        webSettings.setSaveFormData(false);
        webSettings.setJavaScriptEnabled(false);
        webSettings.setSupportZoom(false);
    }

    /**
     * Sets custom user agent to WebView so we don't get GAIA interstitials b/13990689.
     *
     * @param webView The WebView to customize.
     */
    public static void setCustomUserAgent(WebView webView, Context context) {
        final WebSettings settings = webView.getSettings();
        final String version = getVersionCode(context);
        final String originalUserAgent = settings.getUserAgentString();
        final String userAgent = context.getResources().getString(
                R.string.user_agent_format, originalUserAgent, version);
        settings.setUserAgentString(userAgent);
    }

    /**
     * Returns the version code for the package, or null if it cannot be retrieved.
     */
    public static String getVersionCode(Context context) {
        if (sVersionCode == null) {
            try {
                sVersionCode = String.valueOf(context.getPackageManager()
                        .getPackageInfo(context.getPackageName(), 0 /* flags */)
                        .versionCode);
            } catch (NameNotFoundException e) {
                LogUtils.e(Utils.LOG_TAG, "Error finding package %s",
                        context.getApplicationInfo().packageName);
            }
        }
        return sVersionCode;
    }

    /**
     * Format a plural string.
     *
     * @param resource The identity of the resource, which must be a R.plurals
     * @param count The number of items.
     */
    public static String formatPlural(Context context, int resource, int count) {
        final CharSequence formatString = context.getResources().getQuantityText(resource, count);
        return String.format(formatString.toString(), count);
    }

    /**
     * @return an ellipsized String that's at most maxCharacters long. If the
     *         text passed is longer, it will be abbreviated. If it contains a
     *         suffix, the ellipses will be inserted in the middle and the
     *         suffix will be preserved.
     */
    public static String ellipsize(String text, int maxCharacters) {
        int length = text.length();
        if (length < maxCharacters)
            return text;

        int realMax = Math.min(maxCharacters, length);
        // Preserve the suffix if any
        int index = text.lastIndexOf(".");
        String extension = "\u2026"; // "...";
        if (index >= 0) {
            // Limit the suffix to dot + four characters
            if (length - index <= FILE_EXTENSION_MAX_CHARS + 1) {
                extension = extension + text.substring(index + 1);
            }
        }
        realMax -= extension.length();
        if (realMax < 0)
            realMax = 0;
        return text.substring(0, realMax) + extension;
    }

    /**
     * This lock must be held before accessing any of the following fields
     */
    private static final Object sStaticResourcesLock = new Object();
    private static ComponentCallbacksListener sComponentCallbacksListener;
    private static int sMaxUnreadCount = -1;
    private static String sUnreadText;
    private static String sUnseenText;
    private static String sLargeUnseenText;
    private static int sDefaultFolderBackgroundColor = -1;

    private static class ComponentCallbacksListener implements ComponentCallbacks {

        @Override
        public void onConfigurationChanged(Configuration configuration) {
            synchronized (sStaticResourcesLock) {
                sMaxUnreadCount = -1;
                sUnreadText = null;
                sUnseenText = null;
                sLargeUnseenText = null;
                sDefaultFolderBackgroundColor = -1;
            }
        }

        @Override
        public void onLowMemory() {}
    }

    public static void getStaticResources(Context context) {
        synchronized (sStaticResourcesLock) {
            if (sUnreadText == null) {
                final Resources r = context.getResources();
                sMaxUnreadCount = r.getInteger(R.integer.maxUnreadCount);
                sUnreadText = r.getString(R.string.widget_large_unread_count);
                sUnseenText = r.getString(R.string.unseen_count);
                sLargeUnseenText = r.getString(R.string.large_unseen_count);
                sDefaultFolderBackgroundColor = r.getColor(R.color.default_folder_background_color);

                if (sComponentCallbacksListener == null) {
                    sComponentCallbacksListener = new ComponentCallbacksListener();
                    context.getApplicationContext()
                            .registerComponentCallbacks(sComponentCallbacksListener);
                }
            }
        }
    }

    private static int getMaxUnreadCount(Context context) {
        synchronized (sStaticResourcesLock) {
            getStaticResources(context);
            return sMaxUnreadCount;
        }
    }

    private static String getUnreadText(Context context) {
        synchronized (sStaticResourcesLock) {
            getStaticResources(context);
            return sUnreadText;
        }
    }

    private static String getUnseenText(Context context) {
        synchronized (sStaticResourcesLock) {
            getStaticResources(context);
            return sUnseenText;
        }
    }

    private static String getLargeUnseenText(Context context) {
        synchronized (sStaticResourcesLock) {
            getStaticResources(context);
            return sLargeUnseenText;
        }
    }

    public static int getDefaultFolderBackgroundColor(Context context) {
        synchronized (sStaticResourcesLock) {
            getStaticResources(context);
            return sDefaultFolderBackgroundColor;
        }
    }

    /**
     * Returns a boolean indicating whether the table UI should be shown.
     */
    public static boolean useTabletUI(Resources res) {
        return res.getBoolean(R.bool.use_tablet_ui);
    }

    /**
     * Returns displayable text from the provided HTML string.
     * @param htmlText HTML string
     * @return Plain text string representation of the specified Html string
     */
    public static String convertHtmlToPlainText(String htmlText) {
        if (TextUtils.isEmpty(htmlText)) {
            return "";
        }
        return getHtmlTree(htmlText, new HtmlParser(), new HtmlTreeBuilder()).getPlainText();
    }

    public static String convertHtmlToPlainText(String htmlText, HtmlParser parser,
            HtmlTreeBuilder builder) {
        if (TextUtils.isEmpty(htmlText)) {
            return "";
        }
        return getHtmlTree(htmlText, parser, builder).getPlainText();
    }

    /**
     * Returns a {@link HtmlTree} representation of the specified HTML string.
     */
    public static HtmlTree getHtmlTree(String htmlText) {
        return getHtmlTree(htmlText, new HtmlParser(), new HtmlTreeBuilder());
    }

    /**
     * Returns a {@link HtmlTree} representation of the specified HTML string.
     */
    private static HtmlTree getHtmlTree(String htmlText, HtmlParser parser,
            HtmlTreeBuilder builder) {
        final HtmlDocument doc = parser.parse(htmlText);
        doc.accept(builder);

        return builder.getTree();
    }

    /**
     * Perform a simulated measure pass on the given child view, assuming the
     * child has a ViewGroup parent and that it should be laid out within that
     * parent with a matching width but variable height. Code largely lifted
     * from AnimatedAdapter.measureChildHeight().
     *
     * @param child a child view that has already been placed within its parent
     *            ViewGroup
     * @param parent the parent ViewGroup of child
     * @return measured height of the child in px
     */
    public static int measureViewHeight(View child, ViewGroup parent) {
        final ViewGroup.LayoutParams lp = child.getLayoutParams();
        final int childSideMargin;
        if (lp instanceof MarginLayoutParams) {
            final MarginLayoutParams mlp = (MarginLayoutParams) lp;
            childSideMargin = mlp.leftMargin + mlp.rightMargin;
        } else {
            childSideMargin = 0;
        }

        final int parentWSpec = MeasureSpec.makeMeasureSpec(parent.getWidth(), MeasureSpec.EXACTLY);
        final int wSpec = ViewGroup.getChildMeasureSpec(parentWSpec,
                parent.getPaddingLeft() + parent.getPaddingRight() + childSideMargin,
                ViewGroup.LayoutParams.MATCH_PARENT);
        final int hSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        child.measure(wSpec, hSpec);
        return child.getMeasuredHeight();
    }

    /**
     * Encode the string in HTML.
     *
     * @param removeEmptyDoubleQuotes If true, also remove any occurrence of ""
     *            found in the string
     */
    public static Object cleanUpString(String string, boolean removeEmptyDoubleQuotes) {
        return !TextUtils.isEmpty(string) ? TextUtils.htmlEncode(removeEmptyDoubleQuotes ? string
                .replace("\"\"", "") : string) : "";
    }

    /**
     * Get the correct display string for the unread count of a folder.
     */
    public static String getUnreadCountString(Context context, int unreadCount) {
        final String unreadCountString;
        final int maxUnreadCount = getMaxUnreadCount(context);
        if (unreadCount > maxUnreadCount) {
            final String unreadText = getUnreadText(context);
            // Localize "99+" according to the device language
            unreadCountString = String.format(unreadText, maxUnreadCount);
        } else if (unreadCount <= 0) {
            unreadCountString = "";
        } else {
            // Localize unread count according to the device language
            unreadCountString = String.format("%d", unreadCount);
        }
        return unreadCountString;
    }

    /**
     * Get the correct display string for the unseen count of a folder.
     */
    public static String getUnseenCountString(Context context, int unseenCount) {
        final String unseenCountString;
        final int maxUnreadCount = getMaxUnreadCount(context);
        if (unseenCount > maxUnreadCount) {
            final String largeUnseenText = getLargeUnseenText(context);
            // Localize "99+" according to the device language
            unseenCountString = String.format(largeUnseenText, maxUnreadCount);
        } else if (unseenCount <= 0) {
            unseenCountString = "";
        } else {
            // Localize unseen count according to the device language
            unseenCountString = String.format(getUnseenText(context), unseenCount);
        }
        return unseenCountString;
    }

    /**
     * Get text matching the last sync status.
     */
    public static CharSequence getSyncStatusText(Context context, int packedStatus) {
        final String[] errors = context.getResources().getStringArray(R.array.sync_status);
        final int status = packedStatus & 0x0f;
        if (status >= errors.length) {
            return "";
        }
        return errors[status];
    }

    /**
     * Create an intent to show a conversation.
     * @param conversation Conversation to open.
     * @param folderUri
     * @param account
     * @return
     */
    public static Intent createViewConversationIntent(final Context context,
            Conversation conversation, final Uri folderUri, Account account) {
        final Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
                | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
        final Uri versionedUri = appendVersionQueryParameter(context, conversation.uri);
        // We need the URI to be unique, even if it's for the same message, so append the folder URI
        final Uri uniqueUri = versionedUri.buildUpon().appendQueryParameter(
                FOLDER_URI_QUERY_PARAMETER, folderUri.toString()).build();
        intent.setDataAndType(uniqueUri, account.mimeType);
        intent.putExtra(Utils.EXTRA_ACCOUNT, account.serialize());
        intent.putExtra(Utils.EXTRA_FOLDER_URI, folderUri);
        intent.putExtra(Utils.EXTRA_CONVERSATION, conversation);
        return intent;
    }

    /**
     * Create an intent to open a folder.
     *
     * @param folderUri Folder to open.
     * @param account
     * @return
     */
    public static Intent createViewFolderIntent(final Context context, final Uri folderUri,
            Account account) {
        if (folderUri == null || account == null) {
            LogUtils.wtf(LOG_TAG, "Utils.createViewFolderIntent(%s,%s): Bad input", folderUri,
                    account);
            return null;
        }
        final Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
                | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
        intent.setDataAndType(appendVersionQueryParameter(context, folderUri), account.mimeType);
        intent.putExtra(Utils.EXTRA_ACCOUNT, account.serialize());
        intent.putExtra(Utils.EXTRA_FOLDER_URI, folderUri);
        return intent;
    }

    /**
     * Creates an intent to open the default inbox for the given account.
     *
     * @param account
     * @return
     */
    public static Intent createViewInboxIntent(Account account) {
        if (account == null) {
            LogUtils.wtf(LOG_TAG, "Utils.createViewInboxIntent(%s): Bad input", account);
            return null;
        }
        final Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
                | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
        intent.setDataAndType(account.settings.defaultInbox, account.mimeType);
        intent.putExtra(Utils.EXTRA_ACCOUNT, account.serialize());
        return intent;
    }

    /**
     * Helper method to show context-aware help.
     *
     * @param context Context to be used to open the help.
     * @param account Account from which the help URI is extracted
     * @param helpTopic Information about the activity the user was in
     *      when they requested help which specifies the help topic to display
     */
    public static void showHelp(Context context, Account account, String helpTopic) {
        final String urlString = account.helpIntentUri != null ?
                account.helpIntentUri.toString() : null;
        if (TextUtils.isEmpty(urlString)) {
            LogUtils.e(LOG_TAG, "unable to show help for account: %s", account);
            return;
        }
        showHelp(context, account.helpIntentUri, helpTopic);
    }

    /**
     * Helper method to show context-aware help.
     *
     * @param context Context to be used to open the help.
     * @param helpIntentUri URI of the help content to display
     * @param helpTopic Information about the activity the user was in
     *      when they requested help which specifies the help topic to display
     */
    public static void showHelp(Context context, Uri helpIntentUri, String helpTopic) {
        final String urlString = helpIntentUri == null ? null : helpIntentUri.toString();
        if (TextUtils.isEmpty(urlString)) {
            LogUtils.e(LOG_TAG, "unable to show help for help URI: %s", helpIntentUri);
            return;
        }

        // generate the full URL to the requested help section
        final Uri helpUrl = HelpUrl.getHelpUrl(context, helpIntentUri, helpTopic);

        final boolean useBrowser = context.getResources().getBoolean(R.bool.openHelpWithBrowser);
        if (useBrowser) {
            // open a browser with the full help URL
            openUrl(context, helpUrl, null);
        } else {
            // start the help activity with the full help URL
            final Intent intent = new Intent(context, HelpActivity.class);
            intent.putExtra(HelpActivity.PARAM_HELP_URL, helpUrl);
            context.startActivity(intent);
        }
    }

    /**
     * Helper method to open a link in a browser.
     *
     * @param context Context
     * @param uri Uri to open.
     */
    private static void openUrl(Context context, Uri uri, Bundle optionalExtras) {
        if(uri == null || TextUtils.isEmpty(uri.toString())) {
            LogUtils.wtf(LOG_TAG, "invalid url in Utils.openUrl(): %s", uri);
            return;
        }
        final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        // Fill in any of extras that have been requested.
        if (optionalExtras != null) {
            intent.putExtras(optionalExtras);
        }
        intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

        context.startActivity(intent);
    }

    /**
     * Show the top level settings screen for the supplied account.
     */
    public static void showSettings(Context context, Account account) {
        if (account == null) {
            LogUtils.e(LOG_TAG, "Invalid attempt to show setting screen with null account");
            return;
        }
        final Intent settingsIntent = new Intent(Intent.ACTION_EDIT, account.settingsIntentUri);

        settingsIntent.setPackage(context.getPackageName());
        settingsIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

        context.startActivity(settingsIntent);
    }

    /**
     * Show the account level settings screen for the supplied account.
     */
    public static void showAccountSettings(Context context, Account account) {
        if (account == null) {
            LogUtils.e(LOG_TAG, "Invalid attempt to show setting screen with null account");
            return;
        }
        final Intent settingsIntent = new Intent(Intent.ACTION_EDIT,
                appendVersionQueryParameter(context, account.settingsIntentUri));

        settingsIntent.setPackage(context.getPackageName());
        settingsIntent.putExtra(EditSettingsExtras.EXTRA_ACCOUNT, account);
        settingsIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

        context.startActivity(settingsIntent);
    }

    /**
     * Show the feedback screen for the supplied account.
     */
    public static void sendFeedback(Activity activity, Account account, boolean reportingProblem) {
        if (activity != null && account != null) {
            sendFeedback(activity, account.sendFeedbackIntentUri, reportingProblem);
        }
    }

    public static void sendFeedback(Activity activity, Uri feedbackIntentUri,
            boolean reportingProblem) {
        if (activity != null &&  !isEmpty(feedbackIntentUri)) {
            final Bundle optionalExtras = new Bundle(2);
            optionalExtras.putBoolean(
                    UIProvider.SendFeedbackExtras.EXTRA_REPORTING_PROBLEM, reportingProblem);
            final Bitmap screenBitmap = getReducedSizeBitmap(activity);
            if (screenBitmap != null) {
                optionalExtras.putParcelable(
                        UIProvider.SendFeedbackExtras.EXTRA_SCREEN_SHOT, screenBitmap);
            }
            openUrl(activity, feedbackIntentUri, optionalExtras);
        }
    }

    private static Bitmap getReducedSizeBitmap(Activity activity) {
        final Window activityWindow = activity.getWindow();
        final View currentView = activityWindow != null ? activityWindow.getDecorView() : null;
        final View rootView = currentView != null ? currentView.getRootView() : null;
        if (rootView != null) {
            rootView.setDrawingCacheEnabled(true);
            final Bitmap drawingCache = rootView.getDrawingCache();
            // Null check to avoid NPE discovered from monkey crash:
            if (drawingCache != null) {
                try {
                    final Bitmap originalBitmap = drawingCache.copy(Bitmap.Config.RGB_565, false);
                    double originalHeight = originalBitmap.getHeight();
                    double originalWidth = originalBitmap.getWidth();
                    int newHeight = SCALED_SCREENSHOT_MAX_HEIGHT_WIDTH;
                    int newWidth = SCALED_SCREENSHOT_MAX_HEIGHT_WIDTH;
                    double scaleX, scaleY;
                    scaleX = newWidth  / originalWidth;
                    scaleY = newHeight / originalHeight;
                    final double scale = Math.min(scaleX, scaleY);
                    newWidth = (int)Math.round(originalWidth * scale);
                    newHeight = (int)Math.round(originalHeight * scale);
                    return Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, true);
                } catch (OutOfMemoryError e) {
                    LogUtils.e(LOG_TAG, e, "OOME when attempting to scale screenshot");
                }
            }
        }
        return null;
    }

    /**
     * Split out a filename's extension and return it.
     * @param filename a file name
     * @return the file extension (max of 5 chars including period, like ".docx"), or null
     */
    public static String getFileExtension(String filename) {
        String extension = null;
        int index = !TextUtils.isEmpty(filename) ? filename.lastIndexOf('.') : -1;
        // Limit the suffix to dot + four characters
        if (index >= 0 && filename.length() - index <= FILE_EXTENSION_MAX_CHARS + 1) {
            extension = filename.substring(index);
        }
        return extension;
    }

   /**
    * (copied from {@link Intent#normalizeMimeType(String)} for pre-J)
    *
    * Normalize a MIME data type.
    *
    * <p>A normalized MIME type has white-space trimmed,
    * content-type parameters removed, and is lower-case.
    * This aligns the type with Android best practices for
    * intent filtering.
    *
    * <p>For example, "text/plain; charset=utf-8" becomes "text/plain".
    * "text/x-vCard" becomes "text/x-vcard".
    *
    * <p>All MIME types received from outside Android (such as user input,
    * or external sources like Bluetooth, NFC, or the Internet) should
    * be normalized before they are used to create an Intent.
    *
    * @param type MIME data type to normalize
    * @return normalized MIME data type, or null if the input was null
    * @see {@link android.content.Intent#setType}
    * @see {@link android.content.Intent#setTypeAndNormalize}
    */
   public static String normalizeMimeType(String type) {
       if (type == null) {
           return null;
       }

       type = type.trim().toLowerCase(Locale.US);

       final int semicolonIndex = type.indexOf(';');
       if (semicolonIndex != -1) {
           type = type.substring(0, semicolonIndex);
       }
       return type;
   }

   /**
    * (copied from {@link android.net.Uri#normalizeScheme()} for pre-J)
    *
    * Return a normalized representation of this Uri.
    *
    * <p>A normalized Uri has a lowercase scheme component.
    * This aligns the Uri with Android best practices for
    * intent filtering.
    *
    * <p>For example, "HTTP://www.android.com" becomes
    * "http://www.android.com"
    *
    * <p>All URIs received from outside Android (such as user input,
    * or external sources like Bluetooth, NFC, or the Internet) should
    * be normalized before they are used to create an Intent.
    *
    * <p class="note">This method does <em>not</em> validate bad URI's,
    * or 'fix' poorly formatted URI's - so do not use it for input validation.
    * A Uri will always be returned, even if the Uri is badly formatted to
    * begin with and a scheme component cannot be found.
    *
    * @return normalized Uri (never null)
    * @see {@link android.content.Intent#setData}
    */
   public static Uri normalizeUri(Uri uri) {
       String scheme = uri.getScheme();
       if (scheme == null) return uri;  // give up
       String lowerScheme = scheme.toLowerCase(Locale.US);
       if (scheme.equals(lowerScheme)) return uri;  // no change

       return uri.buildUpon().scheme(lowerScheme).build();
   }

   public static Intent setIntentTypeAndNormalize(Intent intent, String type) {
       return intent.setType(normalizeMimeType(type));
   }

   public static Intent setIntentDataAndTypeAndNormalize(Intent intent, Uri data, String type) {
       return intent.setDataAndType(normalizeUri(data), normalizeMimeType(type));
   }

   public static int getTransparentColor(int color) {
       return 0x00ffffff & color;
   }

    public static void setMenuItemVisibility(Menu menu, int itemId, boolean shouldShow) {
        final MenuItem item = menu.findItem(itemId);
        if (item == null) {
            return;
        }
        item.setVisible(shouldShow);
        item.setEnabled(shouldShow);
    }

    /**
     * Parse a string (possibly null or empty) into a URI. If the string is null
     * or empty, null is returned back. Otherwise an empty URI is returned.
     *
     * @param uri
     * @return a valid URI, possibly {@link android.net.Uri#EMPTY}
     */
    public static Uri getValidUri(String uri) {
        if (TextUtils.isEmpty(uri) || uri == JSONObject.NULL)
            return Uri.EMPTY;
        return Uri.parse(uri);
    }

    public static boolean isEmpty(Uri uri) {
        return uri == null || Uri.EMPTY.equals(uri);
    }

    public static String dumpFragment(Fragment f) {
        final StringWriter sw = new StringWriter();
        f.dump("", new FileDescriptor(), new PrintWriter(sw), new String[0]);
        return sw.toString();
    }

    /**
     * Executes an out-of-band command on the cursor.
     * @param cursor
     * @param request Bundle with all keys and values set for the command.
     * @param key The string value against which we will check for success or failure
     * @return true if the operation was a success.
     */
    private static boolean executeConversationCursorCommand(
            Cursor cursor, Bundle request, String key) {
        final Bundle response = cursor.respond(request);
        final String result = response.getString(key,
                UIProvider.ConversationCursorCommand.COMMAND_RESPONSE_FAILED);

        return UIProvider.ConversationCursorCommand.COMMAND_RESPONSE_OK.equals(result);
    }

    /**
     * Commands a cursor representing a set of conversations to indicate that an item is being shown
     * in the UI.
     *
     * @param cursor a conversation cursor
     * @param position position of the item being shown.
     */
    public static boolean notifyCursorUIPositionChange(Cursor cursor, int position) {
        final Bundle request = new Bundle();
        final String key =
                UIProvider.ConversationCursorCommand.COMMAND_NOTIFY_CURSOR_UI_POSITION_CHANGE;
        request.putInt(key, position);
        return executeConversationCursorCommand(cursor, request, key);
    }

    /**
     * Commands a cursor representing a set of conversations to set its visibility state.
     *
     * @param cursor a conversation cursor
     * @param visible true if the conversation list is visible, false otherwise.
     * @param isFirstSeen true if you want to notify the cursor that this conversation list was seen
     *        for the first time: the user launched the app into it, or the user switched from some
     *        other folder into it.
     */
    public static void setConversationCursorVisibility(
            Cursor cursor, boolean visible, boolean isFirstSeen) {
        new MarkConversationCursorVisibleTask(cursor, visible, isFirstSeen).execute();
    }

    /**
     * Async task for  marking conversations "seen" and informing the cursor that the folder was
     * seen for the first time by the UI.
     */
    private static class MarkConversationCursorVisibleTask extends AsyncTask<Void, Void, Void> {
        private final Cursor mCursor;
        private final boolean mVisible;
        private final boolean mIsFirstSeen;

        /**
         * Create a new task with the given cursor, with the given visibility and
         *
         * @param cursor
         * @param isVisible true if the conversation list is visible, false otherwise.
         * @param isFirstSeen true if the folder was shown for the first time: either the user has
         *        just switched to it, or the user started the app in this folder.
         */
        public MarkConversationCursorVisibleTask(
                Cursor cursor, boolean isVisible, boolean isFirstSeen) {
            mCursor = cursor;
            mVisible = isVisible;
            mIsFirstSeen = isFirstSeen;
        }

        @Override
        protected Void doInBackground(Void... params) {
            if (mCursor == null) {
                return null;
            }
            final Bundle request = new Bundle();
            if (mIsFirstSeen) {
                request.putBoolean(
                        UIProvider.ConversationCursorCommand.COMMAND_KEY_ENTERED_FOLDER, true);
            }
            final String key = UIProvider.ConversationCursorCommand.COMMAND_KEY_SET_VISIBILITY;
            request.putBoolean(key, mVisible);
            executeConversationCursorCommand(mCursor, request, key);
            return null;
        }
    }


    /**
     * This utility method returns the conversation ID at the current cursor position.
     * @return the conversation id at the cursor.
     */
    public static long getConversationId(ConversationCursor cursor) {
        return cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN);
    }

    /**
     * @return whether to show two pane or single pane search results.
     */
    public static boolean showTwoPaneSearchResults(Context context) {
        return context.getResources().getBoolean(R.bool.show_two_pane_search_results);
    }

    /**
     * Sets the layer type of a view to hardware if the view is attached and hardware acceleration
     * is enabled. Does nothing otherwise.
     */
    public static void enableHardwareLayer(View v) {
        if (v != null && v.isHardwareAccelerated()) {
            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            v.buildLayer();
        }
    }

    /**
     * Returns the count that should be shown for the specified folder.  This method should be used
     * when the UI wants to display an "unread" count.  For most labels, the returned value will be
     * the unread count, but for some folder types (outbox, drafts, trash) this will return the
     * total count.
     */
    public static int getFolderUnreadDisplayCount(final Folder folder) {
        if (folder != null) {
            if (folder.supportsCapability(UIProvider.FolderCapabilities.UNSEEN_COUNT_ONLY)) {
                return 0;
            } else if (folder.isUnreadCountHidden()) {
                return folder.totalCount;
            } else {
                return folder.unreadCount;
            }
        }
        return 0;
    }

    public static Uri appendVersionQueryParameter(final Context context, final Uri uri) {
        return uri.buildUpon().appendQueryParameter(APP_VERSION_QUERY_PARAMETER,
                getVersionCode(context)).build();
    }

    /**
     * Convenience method for diverting mailto: uris directly to our compose activity. Using this
     * method ensures that the Account object is not accidentally sent to a different process.
     *
     * @param context for sending the intent
     * @param uri mailto: or other uri
     * @param account desired account for potential compose activity
     * @return true if a compose activity was started, false if uri should be sent to a view intent
     */
    public static boolean divertMailtoUri(final Context context, final Uri uri,
            final Account account) {
        final String scheme = normalizeUri(uri).getScheme();
        if (TextUtils.equals(MAILTO_SCHEME, scheme)) {
            ComposeActivity.composeMailto(context, account, uri);
            return true;
        }
        return false;
    }

    /**
     * Gets the specified {@link Folder} object.
     *
     * @param folderUri The {@link Uri} for the folder
     * @param allowHidden <code>true</code> to allow a hidden folder to be returned,
     *        <code>false</code> to return <code>null</code> instead
     * @return the specified {@link Folder} object, or <code>null</code>
     */
    public static Folder getFolder(final Context context, final Uri folderUri,
            final boolean allowHidden) {
        final Uri uri = folderUri
                .buildUpon()
                .appendQueryParameter(UIProvider.ALLOW_HIDDEN_FOLDERS_QUERY_PARAM,
                        Boolean.toString(allowHidden))
                .build();

        final Cursor cursor = context.getContentResolver().query(uri,
                UIProvider.FOLDERS_PROJECTION, null, null, null);

        if (cursor == null) {
            return null;
        }

        try {
            if (cursor.moveToFirst()) {
                return new Folder(cursor);
            } else {
                return null;
            }
        } finally {
            cursor.close();
        }
    }

    /**
     * Begins systrace tracing for a given tag. No-op on unsupported platform versions.
     *
     * @param tag systrace tag to use
     *
     * @see android.os.Trace#beginSection(String)
     */
    public static void traceBeginSection(String tag) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            android.os.Trace.beginSection(tag);
        }
    }

    /**
     * Ends systrace tracing for the most recently begun section. No-op on unsupported platform
     * versions.
     *
     * @see android.os.Trace#endSection()
     */
    public static void traceEndSection() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            android.os.Trace.endSection();
        }
    }

    /**
     * Given a value and a set of upper-bounds to use as buckets, return the smallest upper-bound
     * that is greater than the value.<br>
     * <br>
     * Useful for turning a continuous value into one of a set of discrete ones.
     *
     * @param value a value to bucketize
     * @param upperBounds list of upper-bound buckets to clamp to, sorted from smallest-greatest
     * @return the smallest upper-bound larger than the value, or -1 if the value is larger than
     * all upper-bounds
     */
    public static long getUpperBound(long value, long[] upperBounds) {
        for (long ub : upperBounds) {
            if (value < ub) {
                return ub;
            }
        }
        return -1;
    }

    public static @Nullable Address getAddress(Map<String, Address> cache, String emailStr) {
        Address addr;
        synchronized (cache) {
            addr = cache.get(emailStr);
            if (addr == null) {
                addr = Address.getEmailAddress(emailStr);
                if (addr != null) {
                    cache.put(emailStr, addr);
                }
            }
        }
        return addr;
    }

    /**
     * Applies the given appearance on the given subString, and inserts that as a parameter in the
     * given parentString.
     */
    public static Spanned insertStringWithStyle(Context context,
            String entireString, String subString, int appearance) {
        final int index = entireString.indexOf(subString);
        final SpannableString descriptionText = new SpannableString(entireString);
        descriptionText.setSpan(
                new TextAppearanceSpan(context, appearance),
                index,
                index + subString.length(),
                0);
        return descriptionText;
    }

    /**
     * Email addresses are supposed to be treated as case-insensitive for the host-part and
     * case-sensitive for the local-part, but nobody really wants email addresses to match
     * case-sensitive on the local-part, so just smash everything to lower case.
     * @param email Hello@Example.COM
     * @return hello@example.com
     */
    public static String normalizeEmailAddress(String email) {
        /*
        // The RFC5321 version
        if (TextUtils.isEmpty(email)) {
            return email;
        }
        String[] parts = email.split("@");
        if (parts.length != 2) {
            LogUtils.d(LOG_TAG, "Tried to normalize a malformed email address: ", email);
            return email;
        }

        return parts[0] + "@" + parts[1].toLowerCase(Locale.US);
        */
        if (TextUtils.isEmpty(email)) {
            return email;
        } else {
            // Doing this for other locales might really screw things up, so do US-version only
            return email.toLowerCase(Locale.US);
        }
    }

    /**
     * Returns whether the device currently has network connection. This does not guarantee that
     * the connection is reliable.
     */
    public static boolean isConnected(final Context context) {
        final ConnectivityManager connectivityManager =
                ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
        final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        return (networkInfo != null) && networkInfo.isConnected();
    }
}
