/**
 * 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);
    }

    /**
     * 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();
    }
}
