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

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

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

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

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

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

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

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

    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);

        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];
        }
    };
}
