/**
 * 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.providers;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import com.android.emailcommon.internet.MimeUtility;
import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.mail.Part;
import com.android.mail.browse.MessageAttachmentBar;
import com.android.mail.providers.UIProvider.AttachmentColumns;
import com.android.mail.providers.UIProvider.AttachmentDestination;
import com.android.mail.providers.UIProvider.AttachmentRendition;
import com.android.mail.providers.UIProvider.AttachmentState;
import com.android.mail.providers.UIProvider.AttachmentType;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.MimeType;
import com.android.mail.utils.Utils;
import com.google.common.collect.Lists;

import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;

public class Attachment implements Parcelable {
    public static final int MAX_ATTACHMENT_PREVIEWS = 2;
    public static final String LOG_TAG = LogTag.getLogTag();
    /**
     * Workaround for b/8070022 so that appending a null partId to the end of a
     * uri wouldn't remove the trailing backslash
     */
    public static final String EMPTY_PART_ID = "empty";

    // Indicates that this is a dummy placeholder attachment.
    public static final int FLAG_DUMMY_ATTACHMENT = 1<<10;

    /**
     * Part id of the attachment.
     */
    public String partId;

    /**
     * Attachment file name. See {@link AttachmentColumns#NAME} Use {@link #setName(String)}.
     */
    private String name;

    /**
     * Attachment size in bytes. See {@link AttachmentColumns#SIZE}.
     */
    public int size;

    /**
     * The provider-generated URI for this Attachment. Must be globally unique.
     * For local attachments generated by the Compose UI prior to send/save,
     * this field will be null.
     *
     * @see AttachmentColumns#URI
     */
    public Uri uri;

    /**
     * MIME type of the file. Use {@link #getContentType()} and {@link #setContentType(String)}.
     *
     * @see AttachmentColumns#CONTENT_TYPE
     */
    private String contentType;
    private String inferredContentType;

    /**
     * Use {@link #setState(int)}
     *
     * @see AttachmentColumns#STATE
     */
    public int state;

    /**
     * @see AttachmentColumns#DESTINATION
     */
    public int destination;

    /**
     * @see AttachmentColumns#DOWNLOADED_SIZE
     */
    public int downloadedSize;

    /**
     * Shareable, openable uri for this attachment
     * <p>
     * content:// Gmail.getAttachmentDefaultUri() if origin is SERVER_ATTACHMENT
     * <p>
     * content:// uri pointing to the content to be uploaded if origin is
     * LOCAL_FILE
     * <p>
     * file:// uri pointing to an EXTERNAL apk file. The package manager only
     * handles file:// uris not content:// uris. We do the same workaround in
     * {@link MessageAttachmentBar#onClick(android.view.View)} and
     * UiProvider#getUiAttachmentsCursorForUIAttachments().
     *
     * @see AttachmentColumns#CONTENT_URI
     */
    public Uri contentUri;

    /**
     * Might be null.
     *
     * @see AttachmentColumns#THUMBNAIL_URI
     */
    public Uri thumbnailUri;

    /**
     * Might be null.
     *
     * @see AttachmentColumns#PREVIEW_INTENT_URI
     */
    public Uri previewIntentUri;

    /**
     * The visibility type of this attachment.
     *
     * @see AttachmentColumns#TYPE
     */
    public int type;

    public int flags;

    /**
     * Might be null. JSON string.
     *
     * @see AttachmentColumns#PROVIDER_DATA
     */
    public String providerData;

    /**
     * Streamable mime type of the attachment in case it's a virtual file.
     *
     * Might be null. If null, then the default type (contentType) is assumed
     * to be streamable.
     */
    public String virtualMimeType;

    private transient Uri mIdentifierUri;

    /**
     * True if this attachment can be downloaded again.
     */
    private boolean supportsDownloadAgain;


    public Attachment() {
    }

    public Attachment(Parcel in) {
        name = in.readString();
        size = in.readInt();
        uri = in.readParcelable(null);
        contentType = in.readString();
        state = in.readInt();
        destination = in.readInt();
        downloadedSize = in.readInt();
        contentUri = in.readParcelable(null);
        thumbnailUri = in.readParcelable(null);
        previewIntentUri = in.readParcelable(null);
        providerData = in.readString();
        supportsDownloadAgain = in.readInt() == 1;
        type = in.readInt();
        flags = in.readInt();
        virtualMimeType = in.readString();
    }

    public Attachment(Cursor cursor) {
        if (cursor == null) {
            return;
        }

        name = cursor.getString(cursor.getColumnIndex(AttachmentColumns.NAME));
        size = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.SIZE));
        uri = Uri.parse(cursor.getString(cursor.getColumnIndex(AttachmentColumns.URI)));
        contentType = cursor.getString(cursor.getColumnIndex(AttachmentColumns.CONTENT_TYPE));
        state = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.STATE));
        destination = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.DESTINATION));
        downloadedSize = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.DOWNLOADED_SIZE));
        contentUri = parseOptionalUri(
                cursor.getString(cursor.getColumnIndex(AttachmentColumns.CONTENT_URI)));
        thumbnailUri = parseOptionalUri(
                cursor.getString(cursor.getColumnIndex(AttachmentColumns.THUMBNAIL_URI)));
        previewIntentUri = parseOptionalUri(
                cursor.getString(cursor.getColumnIndex(AttachmentColumns.PREVIEW_INTENT_URI)));
        providerData = cursor.getString(cursor.getColumnIndex(AttachmentColumns.PROVIDER_DATA));
        supportsDownloadAgain = cursor.getInt(
                cursor.getColumnIndex(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN)) == 1;
        type = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.TYPE));
        flags = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.FLAGS));
        virtualMimeType = cursor.getString(cursor.getColumnIndex(AttachmentColumns.VIRTUAL_MIME_TYPE));
    }

    public Attachment(JSONObject srcJson) {
        name = srcJson.optString(AttachmentColumns.NAME, null);
        size = srcJson.optInt(AttachmentColumns.SIZE);
        uri = parseOptionalUri(srcJson, AttachmentColumns.URI);
        contentType = srcJson.optString(AttachmentColumns.CONTENT_TYPE, null);
        state = srcJson.optInt(AttachmentColumns.STATE);
        destination = srcJson.optInt(AttachmentColumns.DESTINATION);
        downloadedSize = srcJson.optInt(AttachmentColumns.DOWNLOADED_SIZE);
        contentUri = parseOptionalUri(srcJson, AttachmentColumns.CONTENT_URI);
        thumbnailUri = parseOptionalUri(srcJson, AttachmentColumns.THUMBNAIL_URI);
        previewIntentUri = parseOptionalUri(srcJson, AttachmentColumns.PREVIEW_INTENT_URI);
        providerData = srcJson.optString(AttachmentColumns.PROVIDER_DATA);
        supportsDownloadAgain = srcJson.optBoolean(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN, true);
        type = srcJson.optInt(AttachmentColumns.TYPE);
        flags = srcJson.optInt(AttachmentColumns.FLAGS);
        virtualMimeType = srcJson.optString(AttachmentColumns.VIRTUAL_MIME_TYPE, null);
    }

    /**
     * Constructor for use when creating attachments in eml files.
     */
    public Attachment(Context context, Part part, Uri emlFileUri, String messageId, String cid,
                      boolean inline) {
        try {
            // Transfer fields from mime format to provider format
            final String contentTypeHeader = MimeUtility.unfoldAndDecode(part.getContentType());
            name = MimeUtility.getHeaderParameter(contentTypeHeader, "name");
            if (name == null) {
                final String contentDisposition =
                        MimeUtility.unfoldAndDecode(part.getDisposition());
                name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
            }

            // Prevent passing in a file path as part of the name.
            if (name != null) {
                name = name.replace('/', '_');
            }

            contentType = MimeType.inferMimeType(name, part.getMimeType());
            uri = EmlAttachmentProvider.getAttachmentUri(emlFileUri, messageId, cid);
            contentUri = uri;
            thumbnailUri = uri;
            previewIntentUri = null;
            state = AttachmentState.SAVED;
            providerData = null;
            supportsDownloadAgain = false;
            destination = AttachmentDestination.CACHE;
            type = inline ? AttachmentType.INLINE_CURRENT_MESSAGE : AttachmentType.STANDARD;
            partId = cid;
            flags = 0;
            virtualMimeType = null;

            // insert attachment into content provider so that we can open the file
            final ContentResolver resolver = context.getContentResolver();
            resolver.insert(uri, toContentValues());

            // save the file in the cache
            try {
                final InputStream in = part.getBody().getInputStream();
                final OutputStream out = resolver.openOutputStream(uri, "rwt");
                size = IOUtils.copy(in, out);
                downloadedSize = size;
                in.close();
                out.close();
            } catch (FileNotFoundException e) {
                LogUtils.e(LOG_TAG, e, "Error in writing attachment to cache");
            } catch (IOException e) {
                LogUtils.e(LOG_TAG, e, "Error in writing attachment to cache");
            }
            // perform a second insert to put the updated size and downloaded size values in
            resolver.insert(uri, toContentValues());
        } catch (MessagingException e) {
            LogUtils.e(LOG_TAG, e, "Error parsing eml attachment");
        }
    }

    /**
     * Create an attachment from a {@link ContentValues} object.
     * The keys should be {@link AttachmentColumns}.
     */
    public Attachment(ContentValues values) {
        name = values.getAsString(AttachmentColumns.NAME);
        size = values.getAsInteger(AttachmentColumns.SIZE);
        uri = parseOptionalUri(values.getAsString(AttachmentColumns.URI));
        contentType = values.getAsString(AttachmentColumns.CONTENT_TYPE);
        state = values.getAsInteger(AttachmentColumns.STATE);
        destination = values.getAsInteger(AttachmentColumns.DESTINATION);
        downloadedSize = values.getAsInteger(AttachmentColumns.DOWNLOADED_SIZE);
        contentUri = parseOptionalUri(values.getAsString(AttachmentColumns.CONTENT_URI));
        thumbnailUri = parseOptionalUri(values.getAsString(AttachmentColumns.THUMBNAIL_URI));
        previewIntentUri =
                parseOptionalUri(values.getAsString(AttachmentColumns.PREVIEW_INTENT_URI));
        providerData = values.getAsString(AttachmentColumns.PROVIDER_DATA);
        supportsDownloadAgain = values.getAsBoolean(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN);
        type = values.getAsInteger(AttachmentColumns.TYPE);
        flags = values.getAsInteger(AttachmentColumns.FLAGS);
        partId = values.getAsString(AttachmentColumns.CONTENT_ID);
        virtualMimeType = values.getAsString(AttachmentColumns.VIRTUAL_MIME_TYPE);
    }

    /**
     * Returns the various attachment fields in a {@link ContentValues} object.
     * The keys for each field should be {@link AttachmentColumns}.
     */
    public ContentValues toContentValues() {
        final ContentValues values = new ContentValues(12);

        values.put(AttachmentColumns.NAME, name);
        values.put(AttachmentColumns.SIZE, size);
        values.put(AttachmentColumns.URI, uri.toString());
        values.put(AttachmentColumns.CONTENT_TYPE, contentType);
        values.put(AttachmentColumns.STATE, state);
        values.put(AttachmentColumns.DESTINATION, destination);
        values.put(AttachmentColumns.DOWNLOADED_SIZE, downloadedSize);
        values.put(AttachmentColumns.CONTENT_URI, contentUri.toString());
        values.put(AttachmentColumns.THUMBNAIL_URI, thumbnailUri.toString());
        values.put(AttachmentColumns.PREVIEW_INTENT_URI,
                previewIntentUri == null ? null : previewIntentUri.toString());
        values.put(AttachmentColumns.PROVIDER_DATA, providerData);
        values.put(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN, supportsDownloadAgain);
        values.put(AttachmentColumns.TYPE, type);
        values.put(AttachmentColumns.FLAGS, flags);
        values.put(AttachmentColumns.CONTENT_ID, partId);
        values.put(AttachmentColumns.VIRTUAL_MIME_TYPE, virtualMimeType);

        return values;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(size);
        dest.writeParcelable(uri, flags);
        dest.writeString(contentType);
        dest.writeInt(state);
        dest.writeInt(destination);
        dest.writeInt(downloadedSize);
        dest.writeParcelable(contentUri, flags);
        dest.writeParcelable(thumbnailUri, flags);
        dest.writeParcelable(previewIntentUri, flags);
        dest.writeString(providerData);
        dest.writeInt(supportsDownloadAgain ? 1 : 0);
        dest.writeInt(type);
        dest.writeInt(flags);
        dest.writeString(virtualMimeType);
    }

    public JSONObject toJSON() throws JSONException {
        final JSONObject result = new JSONObject();

        result.put(AttachmentColumns.NAME, name);
        result.put(AttachmentColumns.SIZE, size);
        result.put(AttachmentColumns.URI, stringify(uri));
        result.put(AttachmentColumns.CONTENT_TYPE, contentType);
        result.put(AttachmentColumns.STATE, state);
        result.put(AttachmentColumns.DESTINATION, destination);
        result.put(AttachmentColumns.DOWNLOADED_SIZE, downloadedSize);
        result.put(AttachmentColumns.CONTENT_URI, stringify(contentUri));
        result.put(AttachmentColumns.THUMBNAIL_URI, stringify(thumbnailUri));
        result.put(AttachmentColumns.PREVIEW_INTENT_URI, stringify(previewIntentUri));
        result.put(AttachmentColumns.PROVIDER_DATA, providerData);
        result.put(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN, supportsDownloadAgain);
        result.put(AttachmentColumns.TYPE, type);
        result.put(AttachmentColumns.FLAGS, flags);
        result.put(AttachmentColumns.VIRTUAL_MIME_TYPE, virtualMimeType);

        return result;
    }

    @Override
    public String toString() {
        try {
            final JSONObject jsonObject = toJSON();
            // Add some additional fields that are helpful when debugging issues
            jsonObject.put("partId", partId);
            if (providerData != null) {
                try {
                    // pretty print the provider data
                    jsonObject.put(AttachmentColumns.PROVIDER_DATA, new JSONObject(providerData));
                } catch (JSONException e) {
                    LogUtils.e(LOG_TAG, e, "JSONException when adding provider data");
                }
            }
            return jsonObject.toString(4);
        } catch (JSONException e) {
            LogUtils.e(LOG_TAG, e, "JSONException in toString");
            return super.toString();
        }
    }

    private static String stringify(Object object) {
        return object != null ? object.toString() : null;
    }

    protected static Uri parseOptionalUri(String uriString) {
        return uriString == null ? null : Uri.parse(uriString);
    }

    protected static Uri parseOptionalUri(JSONObject srcJson, String key) {
        final String uriStr = srcJson.optString(key, null);
        return uriStr == null ? null : Uri.parse(uriStr);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public boolean isPresentLocally() {
        return state == AttachmentState.SAVED;
    }

    public boolean canSave() {
        return !isSavedToExternal() && !isInstallable();
    }

    public boolean canShare() {
        return isPresentLocally() && contentUri != null;
    }

    public boolean isDownloading() {
        return state == AttachmentState.DOWNLOADING || state == AttachmentState.PAUSED;
    }

    public boolean isSavedToExternal() {
        return state == AttachmentState.SAVED && destination == AttachmentDestination.EXTERNAL;
    }

    public boolean isInstallable() {
        return MimeType.isInstallable(getContentType());
    }

    public boolean shouldShowProgress() {
        return (state == AttachmentState.DOWNLOADING || state == AttachmentState.PAUSED)
                && size > 0 && downloadedSize > 0 && downloadedSize <= size;
    }

    public boolean isDownloadFailed() {
        return state == AttachmentState.FAILED;
    }

    public boolean isDownloadFinishedOrFailed() {
        return state == AttachmentState.FAILED || state == AttachmentState.SAVED;
    }

    public boolean supportsDownloadAgain() {
        return supportsDownloadAgain;
    }

    public boolean canPreview() {
        return previewIntentUri != null;
    }

    /**
     * Returns a stable identifier URI for this attachment. TODO: make the uri
     * field stable, and put provider-specific opaque bits and bobs elsewhere
     */
    public Uri getIdentifierUri() {
        if (Utils.isEmpty(mIdentifierUri)) {
            mIdentifierUri = Utils.isEmpty(uri) ?
                    (Utils.isEmpty(contentUri) ? Uri.EMPTY : contentUri)
                    : uri.buildUpon().clearQuery().build();
        }
        return mIdentifierUri;
    }

    public String getContentType() {
        if (TextUtils.isEmpty(inferredContentType)) {
            inferredContentType = MimeType.inferMimeType(name, contentType);
        }
        return inferredContentType;
    }

    public Uri getUriForRendition(int rendition) {
        final Uri uri;
        switch (rendition) {
            case AttachmentRendition.BEST:
                uri = contentUri;
                break;
            case AttachmentRendition.SIMPLE:
                uri = thumbnailUri;
                break;
            default:
                throw new IllegalArgumentException("invalid rendition: " + rendition);
        }
        return uri;
    }

    public void setContentType(String contentType) {
        if (!TextUtils.equals(this.contentType, contentType)) {
            this.inferredContentType = null;
            this.contentType = contentType;
        }
    }

    public String getName() {
        return name;
    }

    public boolean setName(String name) {
        if (!TextUtils.equals(this.name, name)) {
            this.inferredContentType = null;
            this.name = name;
            return true;
        }
        return false;
    }

    /**
     * Sets the attachment state. Side effect: sets downloadedSize
     */
    public void setState(int state) {
        this.state = state;
        if (state == AttachmentState.FAILED || state == AttachmentState.NOT_SAVED) {
            this.downloadedSize = 0;
        }
    }

    /**
     * @return {@code true} if the attachment is an inline attachment
     * that appears in the body of the message content (including possibly
     * quoted text).
     */
    public boolean isInlineAttachment() {
        return type != UIProvider.AttachmentType.STANDARD;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final Attachment that = (Attachment) o;

        if (destination != that.destination) {
            return false;
        }
        if (downloadedSize != that.downloadedSize) {
            return false;
        }
        if (size != that.size) {
            return false;
        }
        if (state != that.state) {
            return false;
        }
        if (supportsDownloadAgain != that.supportsDownloadAgain) {
            return false;
        }
        if (type != that.type) {
            return false;
        }
        if (contentType != null ? !contentType.equals(that.contentType)
                : that.contentType != null) {
            return false;
        }
        if (contentUri != null ? !contentUri.equals(that.contentUri) : that.contentUri != null) {
            return false;
        }
        if (name != null ? !name.equals(that.name) : that.name != null) {
            return false;
        }
        if (partId != null ? !partId.equals(that.partId) : that.partId != null) {
            return false;
        }
        if (previewIntentUri != null ? !previewIntentUri.equals(that.previewIntentUri)
                : that.previewIntentUri != null) {
            return false;
        }
        if (providerData != null ? !providerData.equals(that.providerData)
                : that.providerData != null) {
            return false;
        }
        if (thumbnailUri != null ? !thumbnailUri.equals(that.thumbnailUri)
                : that.thumbnailUri != null) {
            return false;
        }
        if (uri != null ? !uri.equals(that.uri) : that.uri != null) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        int result = partId != null ? partId.hashCode() : 0;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + size;
        result = 31 * result + (uri != null ? uri.hashCode() : 0);
        result = 31 * result + (contentType != null ? contentType.hashCode() : 0);
        result = 31 * result + state;
        result = 31 * result + destination;
        result = 31 * result + downloadedSize;
        result = 31 * result + (contentUri != null ? contentUri.hashCode() : 0);
        result = 31 * result + (thumbnailUri != null ? thumbnailUri.hashCode() : 0);
        result = 31 * result + (previewIntentUri != null ? previewIntentUri.hashCode() : 0);
        result = 31 * result + type;
        result = 31 * result + (providerData != null ? providerData.hashCode() : 0);
        result = 31 * result + (supportsDownloadAgain ? 1 : 0);
        return result;
    }

    public static String toJSONArray(Collection<? extends Attachment> attachments) {
        if (attachments == null) {
            return null;
        }
        final JSONArray result = new JSONArray();
        try {
            for (Attachment attachment : attachments) {
                result.put(attachment.toJSON());
            }
        } catch (JSONException e) {
            throw new IllegalArgumentException(e);
        }
        return result.toString();
    }

    public static List<Attachment> fromJSONArray(String jsonArrayStr) {
        final List<Attachment> results = Lists.newArrayList();
        if (jsonArrayStr != null) {
            try {
                final JSONArray arr = new JSONArray(jsonArrayStr);

                for (int i = 0; i < arr.length(); i++) {
                    results.add(new Attachment(arr.getJSONObject(i)));
                }

            } catch (JSONException e) {
                throw new IllegalArgumentException(e);
            }
        }
        return results;
    }

    private static final String SERVER_ATTACHMENT = "SERVER_ATTACHMENT";
    private static final String LOCAL_FILE = "LOCAL_FILE";

    public String toJoinedString() {
        return TextUtils.join(UIProvider.ATTACHMENT_INFO_DELIMITER, Lists.newArrayList(
                partId == null ? "" : partId,
                name == null ? ""
                        : name.replaceAll("[" + UIProvider.ATTACHMENT_INFO_DELIMITER
                                + UIProvider.ATTACHMENT_INFO_SEPARATOR + "]", ""),
                getContentType(),
                String.valueOf(size),
                getContentType(),
                contentUri != null ? SERVER_ATTACHMENT : LOCAL_FILE,
                contentUri != null ? contentUri.toString() : "",
                "" /* cachedFileUri */,
                String.valueOf(type)));
    }

    /**
     * For use with {@link UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_STATES}.
     *
     * @param previewStates The packed int describing the states of multiple attachments.
     * @param attachmentIndex The index of the attachment to update.
     * @param rendition The rendition of that attachment to update.
     * @param downloaded Whether that specific rendition is downloaded.
     * @return A packed int describing the updated downloaded states of the multiple attachments.
     */
    public static int updatePreviewStates(int previewStates, int attachmentIndex, int rendition,
            boolean downloaded) {
        // find the bit that describes that specific attachment index and rendition
        int shift = attachmentIndex * 2 + rendition;
        int mask = 1 << shift;
        // update the packed int at that bit
        if (downloaded) {
            // turns that bit into a 1
            return previewStates | mask;
        } else {
            // turns that bit into a 0
            return previewStates & ~mask;
        }
    }

    /**
     * For use with {@link UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_STATES}.
     *
     * @param previewStates The packed int describing the states of multiple attachments.
     * @param attachmentIndex The index of the attachment.
     * @param rendition The rendition of the attachment.
     * @return The downloaded state of that particular rendition of that particular attachment.
     */
    public static boolean getPreviewState(int previewStates, int attachmentIndex, int rendition) {
        // find the bit that describes that specific attachment index
        int shift = attachmentIndex * 2;
        int mask = 1 << shift;

        if (rendition == AttachmentRendition.SIMPLE) {
            // implicit shift of 0 finds the SIMPLE rendition bit
            return (previewStates & mask) != 0;
        } else if (rendition == AttachmentRendition.BEST) {
            // shift of 1 finds the BEST rendition bit
            return (previewStates & (mask << 1)) != 0;
        } else {
            return false;
        }
    }

    public static final Creator<Attachment> CREATOR = new Creator<Attachment>() {
            @Override
        public Attachment createFromParcel(Parcel source) {
            return new Attachment(source);
        }

            @Override
        public Attachment[] newArray(int size) {
            return new Attachment[size];
        }
    };
}
