/*
 * Copyright (C) 2012 Google Inc.
 * Licensed to The Android Open Source Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mail.photo;

import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.print.PrintHelper;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.ex.photo.Intents;
import com.android.ex.photo.PhotoViewActivity;
import com.android.ex.photo.fragments.PhotoViewFragment;
import com.android.ex.photo.views.ProgressBarWrapper;
import com.android.mail.R;
import com.android.mail.analytics.Analytics;
import com.android.mail.browse.AttachmentActionHandler;
import com.android.mail.print.PrintUtils;
import com.android.mail.providers.Attachment;
import com.android.mail.providers.Message;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.AttachmentDestination;
import com.android.mail.providers.UIProvider.AttachmentState;
import com.android.mail.utils.AttachmentUtils;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
import com.google.common.collect.Lists;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

/**
 * Derives from {@link PhotoViewActivity} to allow customization
 * to the {@link ActionBar} from the default implementation.
 */
public class MailPhotoViewActivity extends PhotoViewActivity {

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

    private MenuItem mSaveItem;
    private MenuItem mSaveAllItem;
    private MenuItem mShareItem;
    private MenuItem mShareAllItem;
    private MenuItem mPrintItem;
    /**
     * Only for attachments that are currently downloading. Attachments that failed show the
     * retry button.
     */
    private MenuItem mDownloadAgainItem;
    private MenuItem mExtraOption1Item;
    protected AttachmentActionHandler mActionHandler;
    private Menu mMenu;

    private static final String EXTRA_ACCOUNT = MailPhotoViewActivity.class.getName() + "-acct";
    private static final String EXTRA_MESSAGE = MailPhotoViewActivity.class.getName() + "-msg";

    /**
     * Start a new MailPhotoViewActivity to view the given images.
     *
     * @param photoIndex The index of the photo to show first.
     */
    public static void startMailPhotoViewActivity(final Context context, final String account,
            final Message msg, final int photoIndex) {
        final Intents.PhotoViewIntentBuilder builder =
                Intents.newPhotoViewIntentBuilder(context,
                        "com.android.mail.photo.MailPhotoViewActivity");
        builder
                .setPhotosUri(msg.attachmentListUri.toString())
                .setProjection(UIProvider.ATTACHMENT_PROJECTION)
                .setPhotoIndex(photoIndex);

        context.startActivity(wrapIntent(builder.build(), account, msg));
    }

    /**
     * Start a new MailPhotoViewActivity to view the given images.
     *
     * @param initialPhotoUri The uri of the photo to show first.
     */
    public static void startMailPhotoViewActivity(final Context context, final String account,
            final Message msg, final String initialPhotoUri) {
        context.startActivity(
                buildMailPhotoViewActivityIntent(context, account, msg, initialPhotoUri));
    }

    public static Intent buildMailPhotoViewActivityIntent(
            final Context context, final String account, final Message msg,
            final String initialPhotoUri) {
        final Intents.PhotoViewIntentBuilder builder = Intents.newPhotoViewIntentBuilder(
                context, "com.android.mail.photo.MailPhotoViewActivity");

        builder.setPhotosUri(msg.attachmentListUri.toString())
                .setProjection(UIProvider.ATTACHMENT_PROJECTION)
                .setInitialPhotoUri(initialPhotoUri);

        return wrapIntent(builder.build(), account, msg);
    }

    private static Intent wrapIntent(final Intent intent, final String account, final Message msg) {
        intent.putExtra(EXTRA_MESSAGE, msg);
        intent.putExtra(EXTRA_ACCOUNT, account);
        return intent;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_PROGRESS);
        super.onCreate(savedInstanceState);

        mActionHandler = new AttachmentActionHandler(this, null);
        mActionHandler.initialize(getFragmentManager());

        final Intent intent = getIntent();
        final String account = intent.getStringExtra(EXTRA_ACCOUNT);
        final Message msg = intent.getParcelableExtra(EXTRA_MESSAGE);
        mActionHandler.setAccount(account);
        mActionHandler.setMessage(msg);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();

        inflater.inflate(R.menu.photo_view_menu, menu);
        mMenu = menu;

        mSaveItem = mMenu.findItem(R.id.menu_save);
        mSaveAllItem = mMenu.findItem(R.id.menu_save_all);
        mShareItem = mMenu.findItem(R.id.menu_share);
        mShareAllItem = mMenu.findItem(R.id.menu_share_all);
        mPrintItem = mMenu.findItem(R.id.menu_print);
        mDownloadAgainItem = mMenu.findItem(R.id.menu_download_again);
        mExtraOption1Item = mMenu.findItem(R.id.attachment_extra_option1);

        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        updateActionItems();
        return true;
    }

    /**
     * Updates the action items to tweak their visibility in case
     * there is functionality that is not relevant (eg, the Save
     * button should not appear if the photo has already been saved).
     */
    @Override
    protected void updateActionItems() {
        final Attachment attachment = getCurrentAttachment();

        if (attachment != null && mSaveItem != null && mShareItem != null) {
            mSaveItem.setEnabled(!attachment.isDownloading()
                    && attachment.canSave() && !attachment.isSavedToExternal());
            final boolean canShare = attachment.canShare();
            mShareItem.setEnabled(canShare);
            mPrintItem.setEnabled(canShare);
            mDownloadAgainItem.setEnabled(attachment.canSave() && attachment.isDownloading());
            mExtraOption1Item.setEnabled(mActionHandler.shouldShowExtraOption1());
        } else {
            if (mMenu != null) {
                mMenu.setGroupEnabled(R.id.photo_view_menu_group, false);
            }
            return;
        }

        List<Attachment> attachments = getAllAttachments();
        if (attachments != null) {
            boolean enabled = false;
            for (final Attachment a : attachments) {
                // If one attachment can be saved, enable save all
                if (!a.isDownloading() && a.canSave() && !a.isSavedToExternal()) {
                    enabled = true;
                    break;
                }
            }
            mSaveAllItem.setEnabled(enabled);

            // all attachments must be present to be able to share all
            enabled = true;
            for (final Attachment a : attachments) {
                if (!a.canShare()) {
                    enabled = false;
                    break;
                }
            }
            mShareAllItem.setEnabled(enabled);
        }

        // Turn off functionality that only works on JellyBean.
        if (!Utils.isRunningJellybeanOrLater()) {
            mShareItem.setVisible(false);
            mShareAllItem.setVisible(false);
        }

        // Turn off functionality that only works on KitKat.
        if (!Utils.isRunningKitkatOrLater()) {
            mPrintItem.setVisible(false);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        final int itemId = item.getItemId();

        Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, itemId,
                "photo_viewer", 0);

        if (itemId == android.R.id.home) {
            // app icon in action bar clicked; go back to conversation
            finish();
        } else if (itemId == R.id.menu_save) { // save the current photo
            saveAttachment();
        } else if (itemId == R.id.menu_save_all) { // save all of the photos
            saveAllAttachments();
        } else if (itemId == R.id.menu_share) { // share the current photo
            shareAttachment();
        } else if (itemId == R.id.menu_share_all) { // share all of the photos
            shareAllAttachments();
        } else if (itemId == R.id.menu_print) { // print the current photo
            printAttachment();
        } else if (itemId == R.id.menu_download_again) { // redownload the current photo
            redownloadAttachment();
        } else if (itemId == R.id.attachment_extra_option1) {
            mActionHandler.setAttachment(getCurrentAttachment());
            mActionHandler.handleOption1();
        } else {
            return super.onOptionsItemSelected(item);
        }
        return true;
    }

    /**
     * Adjusts the activity title and subtitle to reflect the image name and size.
     */
    @Override
    protected void updateActionBar() {
        super.updateActionBar();

        final Attachment attachment = getCurrentAttachment();
        final ActionBar actionBar = getActionBar();
        final String size = AttachmentUtils.convertToHumanReadableSize(this, attachment.size);

        // update the status
        // There are 3 states
        //      1. Saved, Attachment Size
        //      2. Saving...
        //      3. Default, Attachment Size
        if (attachment.isSavedToExternal()) {
            actionBar.setSubtitle(getResources().getString(R.string.saved, size));
        } else if (attachment.isDownloading() &&
                attachment.destination == AttachmentDestination.EXTERNAL) {
                actionBar.setSubtitle(R.string.saving);
        } else {
            actionBar.setSubtitle(size);
        }
        updateActionItems();
    }

    @Override
    public void onFragmentVisible(PhotoViewFragment fragment) {
        super.onFragmentVisible(fragment);
        final Attachment attachment = getCurrentAttachment();
        if (attachment.state == AttachmentState.PAUSED) {
            mActionHandler.setAttachment(attachment);
            mActionHandler.startDownloadingAttachment(attachment.destination);
        }
    }

    @Override
    public void onCursorChanged(PhotoViewFragment fragment, Cursor cursor) {
        super.onCursorChanged(fragment, cursor);
        updateProgressAndEmptyViews(fragment, new Attachment(cursor));
    }

    /**
     * Updates the empty views of the fragment based upon the current
     * state of the attachment.
     * @param fragment the current fragment
     */
    private void updateProgressAndEmptyViews(
            final PhotoViewFragment fragment, final Attachment attachment) {
        final ProgressBarWrapper progressBar = fragment.getPhotoProgressBar();
        final TextView emptyText = fragment.getEmptyText();
        final ImageView retryButton = fragment.getRetryButton();

        // update the progress
        if (attachment.shouldShowProgress()) {
            progressBar.setMax(attachment.size);
            progressBar.setProgress(attachment.downloadedSize);
            progressBar.setIndeterminate(false);
        } else if (fragment.isProgressBarNeeded()) {
            progressBar.setIndeterminate(true);
        }

        // If the download failed, show the empty text and retry button
        if (attachment.isDownloadFailed()) {
            emptyText.setText(R.string.photo_load_failed);
            emptyText.setVisibility(View.VISIBLE);
            retryButton.setVisibility(View.VISIBLE);
            retryButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    redownloadAttachment();
                    emptyText.setVisibility(View.GONE);
                    retryButton.setVisibility(View.GONE);
                }
            });
            progressBar.setVisibility(View.GONE);
        }
    }

    /**
     * Save the current attachment.
     */
    private void saveAttachment() {
        saveAttachment(getCurrentAttachment());
    }

    /**
     * Redownloads the attachment.
     */
    private void redownloadAttachment() {
        final Attachment attachment = getCurrentAttachment();
        if (attachment != null && attachment.canSave()) {
            // REDOWNLOADING command is only for attachments that are finished or failed.
            // For an attachment that is downloading (or paused in the DownloadManager), we need to
            // cancel it first.
            mActionHandler.setAttachment(attachment);
            mActionHandler.cancelAttachment();
            mActionHandler.startDownloadingAttachment(attachment.destination);
        }
    }

    /**
     * Saves the attachment.
     * @param attachment the attachment to save.
     */
    private void saveAttachment(final Attachment attachment) {
        if (attachment != null && attachment.canSave()) {
            mActionHandler.setAttachment(attachment);
            mActionHandler.startDownloadingAttachment(AttachmentDestination.EXTERNAL);
        }
    }

    /**
     * Save all of the attachments in the cursor.
     */
    private void saveAllAttachments() {
        Cursor cursor = getCursorAtProperPosition();

        if (cursor == null) {
            return;
        }

        int i = -1;
        while (cursor.moveToPosition(++i)) {
            saveAttachment(new Attachment(cursor));
        }
    }

    /**
     * Share the current attachment.
     */
    private void shareAttachment() {
        shareAttachment(getCurrentAttachment());
    }

    /**
     * Shares the attachment
     * @param attachment the attachment to share
     */
    private void shareAttachment(final Attachment attachment) {
        if (attachment != null) {
            mActionHandler.setAttachment(attachment);
            mActionHandler.shareAttachment();
        }
    }

    /**
     * Share all of the attachments in the cursor.
     */
    private void shareAllAttachments() {
        Cursor cursor = getCursorAtProperPosition();

        if (cursor == null) {
            return;
        }

        ArrayList<Parcelable> uris = new ArrayList<Parcelable>();
        int i = -1;
        while (cursor.moveToPosition(++i)) {
            uris.add(Utils.normalizeUri(new Attachment(cursor).contentUri));
        }

        mActionHandler.shareAttachments(uris);
    }

    private void printAttachment() {
        final Attachment attachment = getCurrentAttachment();
        final Context context = this;
        final PrintHelper printHelper = new PrintHelper(context);
        try {
            printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT);
            printHelper.printBitmap(PrintUtils.buildPrintJobName(context, attachment.getName()),
                    attachment.contentUri);
        } catch (FileNotFoundException e) {
            // couldn't print a photo at the particular Uri. Should we notify the user?
            LogUtils.e(LOG_TAG, e, "Can't print photo");
        }
    }

    /**
     * Helper method to get the currently visible attachment.
     */
    protected Attachment getCurrentAttachment() {
        final Cursor cursor = getCursorAtProperPosition();

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

        return new Attachment(cursor);
    }

    private List<Attachment> getAllAttachments() {
        final Cursor cursor = getCursor();

        if (cursor == null || cursor.isClosed() || !cursor.moveToFirst()) {
            return null;
        }

        List<Attachment> list = Lists.newArrayList();
        do {
            list.add(new Attachment(cursor));
        } while (cursor.moveToNext());

        return list;
    }
}
