/*
 * Copyright (C) 2013 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.printspooler;

import android.app.Activity;
import android.app.Dialog;
import android.app.LoaderManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.content.ServiceConnection;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.print.ILayoutResultCallback;
import android.print.IPrintDocumentAdapter;
import android.print.IPrintDocumentAdapterObserver;
import android.print.IWriteResultCallback;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintAttributes.Margins;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Resolution;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.print.PrintJobId;
import android.print.PrintJobInfo;
import android.print.PrintManager;
import android.print.PrinterCapabilitiesInfo;
import android.print.PrinterId;
import android.print.PrinterInfo;
import android.printservice.PrintService;
import android.printservice.PrintServiceInfo;
import android.provider.DocumentsContract;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
import android.text.TextWatcher;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewPropertyAnimator;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;

import com.android.printspooler.MediaSizeUtils.MediaSizeComparator;

import libcore.io.IoUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Activity for configuring a print job.
 */
public class PrintJobConfigActivity extends Activity {

    private static final String LOG_TAG = "PrintJobConfigActivity";

    private static final boolean DEBUG = false;

    public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID";

    private static final int LOADER_ID_PRINTERS_LOADER = 1;

    private static final int ORIENTATION_PORTRAIT = 0;
    private static final int ORIENTATION_LANDSCAPE = 1;

    private static final int DEST_ADAPTER_MAX_ITEM_COUNT = 9;

    private static final int DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF = Integer.MAX_VALUE;
    private static final int DEST_ADAPTER_ITEM_ID_ALL_PRINTERS = Integer.MAX_VALUE - 1;

    private static final int ACTIVITY_REQUEST_CREATE_FILE = 1;
    private static final int ACTIVITY_REQUEST_SELECT_PRINTER = 2;
    private static final int ACTIVITY_POPULATE_ADVANCED_PRINT_OPTIONS = 3;

    private static final int CONTROLLER_STATE_FINISHED = 1;
    private static final int CONTROLLER_STATE_FAILED = 2;
    private static final int CONTROLLER_STATE_CANCELLED = 3;
    private static final int CONTROLLER_STATE_INITIALIZED = 4;
    private static final int CONTROLLER_STATE_STARTED = 5;
    private static final int CONTROLLER_STATE_LAYOUT_STARTED = 6;
    private static final int CONTROLLER_STATE_LAYOUT_COMPLETED = 7;
    private static final int CONTROLLER_STATE_WRITE_STARTED = 8;
    private static final int CONTROLLER_STATE_WRITE_COMPLETED = 9;

    private static final int EDITOR_STATE_INITIALIZED = 1;
    private static final int EDITOR_STATE_CONFIRMED_PRINT = 2;
    private static final int EDITOR_STATE_CANCELLED = 3;

    private static final int MIN_COPIES = 1;
    private static final String MIN_COPIES_STRING = String.valueOf(MIN_COPIES);

    private static final Pattern PATTERN_DIGITS = Pattern.compile("[\\d]+");

    private static final Pattern PATTERN_ESCAPE_SPECIAL_CHARS = Pattern.compile(
            "(?=[]\\[+&|!(){}^\"~*?:\\\\])");

    private static final Pattern PATTERN_PAGE_RANGE = Pattern.compile(
            "[\\s]*[0-9]*[\\s]*[\\-]?[\\s]*[0-9]*[\\s]*?(([,])"
            + "[\\s]*[0-9]*[\\s]*[\\-]?[\\s]*[0-9]*[\\s]*|[\\s]*)+");

    public static final PageRange[] ALL_PAGES_ARRAY = new PageRange[] {PageRange.ALL_PAGES};

    private final PrintAttributes mOldPrintAttributes = new PrintAttributes.Builder().build();
    private final PrintAttributes mCurrPrintAttributes = new PrintAttributes.Builder().build();

    private final DeathRecipient mDeathRecipient = new DeathRecipient() {
        @Override
        public void binderDied() {
            finish();
        }
    };

    private Editor mEditor;
    private Document mDocument;
    private PrintController mController;

    private PrintJobId mPrintJobId;

    private IBinder mIPrintDocumentAdapter;

    private Dialog mGeneratingPrintJobDialog;

    private PrintSpoolerProvider mSpoolerProvider;

    private String mCallingPackageName;

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);

        setTitle(R.string.print_dialog);

        Bundle extras = getIntent().getExtras();

        PrintJobInfo printJob = extras.getParcelable(PrintManager.EXTRA_PRINT_JOB);
        if (printJob == null) {
            throw new IllegalArgumentException("printJob cannot be null");
        }

        mPrintJobId = printJob.getId();
        mIPrintDocumentAdapter = extras.getBinder(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER);
        if (mIPrintDocumentAdapter == null) {
            throw new IllegalArgumentException("PrintDocumentAdapter cannot be null");
        }

        try {
            IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter)
                    .setObserver(new PrintDocumentAdapterObserver(this));
        } catch (RemoteException re) {
            finish();
            return;
        }

        PrintAttributes attributes = printJob.getAttributes();
        if (attributes != null) {
            mCurrPrintAttributes.copyFrom(attributes);
        }

        mCallingPackageName = extras.getString(DocumentsContract.EXTRA_PACKAGE_NAME);

        setContentView(R.layout.print_job_config_activity_container);

        try {
            mIPrintDocumentAdapter.linkToDeath(mDeathRecipient, 0);
        } catch (RemoteException re) {
            finish();
            return;
        }

        mDocument = new Document();
        mEditor = new Editor();

        mSpoolerProvider = new PrintSpoolerProvider(this,
                new Runnable() {
            @Override
            public void run() {
                // We got the spooler so unleash the UI.
                mController = new PrintController(new RemotePrintDocumentAdapter(
                        IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter),
                        mSpoolerProvider.getSpooler().generateFileForPrintJob(mPrintJobId)));
                mController.initialize();

                mEditor.initialize();
                mEditor.postCreate();
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mSpoolerProvider.getSpooler() != null) {
            mEditor.refreshCurrentPrinter();
        }
    }

    @Override
    public void onPause() {
       if (isFinishing()) {
           if (mController != null && mController.hasStarted()) {
               mController.finish();
           }
           if (mEditor != null && mEditor.isPrintConfirmed()
                   && mController != null && mController.isFinished()) {
                   mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
                           PrintJobInfo.STATE_QUEUED, null);
           } else {
               mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
                       PrintJobInfo.STATE_CANCELED, null);
           }
           if (mGeneratingPrintJobDialog != null) {
               mGeneratingPrintJobDialog.dismiss();
               mGeneratingPrintJobDialog = null;
           }
           mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0);
           mSpoolerProvider.destroy();
       }
        super.onPause();
    }

    public boolean onTouchEvent(MotionEvent event) {
        if (mController != null && mEditor != null &&
                !mEditor.isPrintConfirmed() && mEditor.shouldCloseOnTouch(event)) {
            if (!mController.isWorking()) {
                PrintJobConfigActivity.this.finish();
            }
            mEditor.cancel();
            return true;
        }
        return super.onTouchEvent(event);
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            event.startTracking();
        }
        return super.onKeyDown(keyCode, event);
    }

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (mController != null && mEditor != null) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                if (mEditor.isShwoingGeneratingPrintJobUi()) {
                    return true;
                }
                if (event.isTracking() && !event.isCanceled()) {
                    if (!mController.isWorking()) {
                        PrintJobConfigActivity.this.finish();
                    }
                }
                mEditor.cancel();
                return true;
            }
        }
        return super.onKeyUp(keyCode, event);
    }

    private boolean printAttributesChanged() {
        return !mOldPrintAttributes.equals(mCurrPrintAttributes);
    }

    private class PrintController {
        private final AtomicInteger mRequestCounter = new AtomicInteger();

        private final RemotePrintDocumentAdapter mRemotePrintAdapter;

        private final Bundle mMetadata;

        private final ControllerHandler mHandler;

        private final LayoutResultCallback mLayoutResultCallback;

        private final WriteResultCallback mWriteResultCallback;

        private int mControllerState = CONTROLLER_STATE_INITIALIZED;

        private boolean mHasStarted;

        private PageRange[] mRequestedPages;

        public PrintController(RemotePrintDocumentAdapter adapter) {
            mRemotePrintAdapter = adapter;
            mMetadata = new Bundle();
            mHandler = new ControllerHandler(getMainLooper());
            mLayoutResultCallback = new LayoutResultCallback(mHandler);
            mWriteResultCallback = new WriteResultCallback(mHandler);
        }

        public void initialize() {
            mHasStarted = false;
            mControllerState = CONTROLLER_STATE_INITIALIZED;
        }

        public void cancel() {
            if (isWorking()) {
                mRemotePrintAdapter.cancel();
            }
            mControllerState = CONTROLLER_STATE_CANCELLED;
        }

        public boolean isCancelled() {
            return (mControllerState == CONTROLLER_STATE_CANCELLED);
        }

        public boolean isFinished() {
            return (mControllerState == CONTROLLER_STATE_FINISHED);
        }

        public boolean hasStarted() {
            return mHasStarted;
        }

        public boolean hasPerformedLayout() {
            return mControllerState >= CONTROLLER_STATE_LAYOUT_COMPLETED;
        }

        public boolean isPerformingLayout() {
            return mControllerState == CONTROLLER_STATE_LAYOUT_STARTED;
        }

        public boolean isWorking() {
            return mControllerState == CONTROLLER_STATE_LAYOUT_STARTED
                    || mControllerState == CONTROLLER_STATE_WRITE_STARTED;
        }

        public void start() {
            mControllerState = CONTROLLER_STATE_STARTED;
            mHasStarted = true;
            mRemotePrintAdapter.start();
        }

        public void update() {
            if (!mController.hasStarted()) {
                mController.start();
            }

            // If the print attributes are the same and we are performing
            // a layout, then we have to wait for it to completed which will
            // trigger writing of the necessary pages.
            final boolean printAttributesChanged = printAttributesChanged();
            if (!printAttributesChanged && isPerformingLayout()) {
                return;
            }

            // If print is confirmed we always do a layout since the previous
            // ones were for preview and this one is for printing.
            if (!printAttributesChanged && !mEditor.isPrintConfirmed()) {
                if (mDocument.info == null) {
                    // We are waiting for the result of a layout, so do nothing.
                    return;
                }
                // If the attributes didn't change and we have done a layout, then
                // we do not do a layout but may have to ask the app to write some
                // pages. Hence, pretend layout completed and nothing changed, so
                // we handle writing as usual.
                handleOnLayoutFinished(mDocument.info, false, mRequestCounter.get());
            } else {
                mSpoolerProvider.getSpooler().setPrintJobAttributesNoPersistence(
                        mPrintJobId, mCurrPrintAttributes);

                mMetadata.putBoolean(PrintDocumentAdapter.EXTRA_PRINT_PREVIEW,
                        !mEditor.isPrintConfirmed());

                mControllerState = CONTROLLER_STATE_LAYOUT_STARTED;

                mRemotePrintAdapter.layout(mOldPrintAttributes, mCurrPrintAttributes,
                        mLayoutResultCallback, mMetadata, mRequestCounter.incrementAndGet());

                mOldPrintAttributes.copyFrom(mCurrPrintAttributes);
            }
        }

        public void finish() {
            mControllerState = CONTROLLER_STATE_FINISHED;
            mRemotePrintAdapter.finish();
        }

        private void handleOnLayoutFinished(PrintDocumentInfo info,
                boolean layoutChanged, int sequence) {
            if (mRequestCounter.get() != sequence) {
                return;
            }

            if (isCancelled()) {
                mEditor.updateUi();
                if (mEditor.isDone()) {
                    PrintJobConfigActivity.this.finish();
                }
                return;
            }

            final int oldControllerState = mControllerState;

            if (mControllerState == CONTROLLER_STATE_LAYOUT_STARTED) {
                mControllerState = CONTROLLER_STATE_LAYOUT_COMPLETED;
            }

            // For layout purposes we care only whether the type or the page
            // count changed. We still do not have the size since we did not
            // call write. We use "layoutChanged" set by the application to
            // know whether something else changed about the document.
            final boolean infoChanged = !equalsIgnoreSize(info, mDocument.info);
            // If the info changed, we update the document and the print job.
            if (infoChanged) {
                mDocument.info = info;
                // Set the info.
                mSpoolerProvider.getSpooler().setPrintJobPrintDocumentInfoNoPersistence(
                        mPrintJobId, info);
            }

            // If the document info or the layout changed, then
            // drop the pages since we have to fetch them again.
            if (infoChanged || layoutChanged) {
                mDocument.pages = null;
                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(
                        mPrintJobId, null);
            }

            PageRange[] oldRequestedPages = mRequestedPages;

            // No pages means that the user selected an invalid range while we
            // were doing a layout or the layout returned a document info for
            // which the selected range is invalid. In such a case we do not
            // write anything and wait for the user to fix the range which will
            // trigger an update.
            mRequestedPages = mEditor.getRequestedPages();
            if (mRequestedPages == null || mRequestedPages.length == 0) {
                mEditor.updateUi();
                if (mEditor.isDone()) {
                    PrintJobConfigActivity.this.finish();
                }
                return;
            } else {
                // If print is not confirmed we just ask for the first of the
                // selected pages to emulate a behavior that shows preview
                // increasing the chances that apps will implement the APIs
                // correctly.
                if (!mEditor.isPrintConfirmed()) {
                    if (ALL_PAGES_ARRAY.equals(mRequestedPages)) {
                        mRequestedPages = new PageRange[] {new PageRange(0, 0)};
                    } else {
                        final int firstPage = mRequestedPages[0].getStart();
                        mRequestedPages = new PageRange[] {new PageRange(firstPage, firstPage)};
                    }
                }
            }

            // If the info and the layout did not change...
            if (!infoChanged && !layoutChanged
                    // and we have the requested pages ... 
                    && (PageRangeUtils.contains(mDocument.pages, mRequestedPages))
                        // ...or the requested pages are being written...
                        || (oldControllerState == CONTROLLER_STATE_WRITE_STARTED
                            && oldRequestedPages != null
                            && PageRangeUtils.contains(oldRequestedPages, mRequestedPages))) {
                // Nothing interesting changed and we have all requested pages.
                // Then update the print jobs's pages as we will not do a write
                // and we usually update the pages in the write complete callback.
                if (mDocument.pages != null) {
                    // Update the print job's pages given we have them.
                    updatePrintJobPages(mDocument.pages, mRequestedPages);
                }
                mEditor.updateUi();
                if (mEditor.isDone()) {
                    requestCreatePdfFileOrFinish();
                }
                return;
            }

            mEditor.updateUi();

            // Request a write of the pages of interest.
            mControllerState = CONTROLLER_STATE_WRITE_STARTED;
            mRemotePrintAdapter.write(mRequestedPages, mWriteResultCallback,
                    mRequestCounter.incrementAndGet());
        }

        private void handleOnLayoutFailed(final CharSequence error, int sequence) {
            if (mRequestCounter.get() != sequence) {
                return;
            }
            mControllerState = CONTROLLER_STATE_FAILED;
            mEditor.showUi(Editor.UI_ERROR, new Runnable() {
                @Override
                public void run() {
                    if (!TextUtils.isEmpty(error)) {
                        TextView messageView = (TextView) findViewById(R.id.message);
                        messageView.setText(error);
                    }
                }
            });
        }

        private void handleOnWriteFinished(PageRange[] pages, int sequence) {
            if (mRequestCounter.get() != sequence) {
                return;
            }

            if (isCancelled()) {
                if (mEditor.isDone()) {
                    PrintJobConfigActivity.this.finish();
                }
                return;
            }

            mControllerState = CONTROLLER_STATE_WRITE_COMPLETED;

            // Update the document size.
            File file = mSpoolerProvider.getSpooler()
                    .generateFileForPrintJob(mPrintJobId);
            mDocument.info.setDataSize(file.length());

            // Update the print job with the updated info.
            mSpoolerProvider.getSpooler().setPrintJobPrintDocumentInfoNoPersistence(
                    mPrintJobId, mDocument.info);

            // Update which pages we have fetched.
            mDocument.pages = PageRangeUtils.normalize(pages);

            if (DEBUG) {
                Log.i(LOG_TAG, "Requested: " + Arrays.toString(mRequestedPages)
                        + " and got: " + Arrays.toString(mDocument.pages));
            }

            updatePrintJobPages(mDocument.pages, mRequestedPages);

            if (mEditor.isDone()) {
                requestCreatePdfFileOrFinish();
            }
        }

        private void updatePrintJobPages(PageRange[] writtenPages, PageRange[] requestedPages) {
            // Adjust the print job pages based on what was requested and written.
            // The cases are ordered in the most expected to the least expected.
            if (Arrays.equals(writtenPages, requestedPages)) {
                // We got a document with exactly the pages we wanted. Hence,
                // the printer has to print all pages in the data.
                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
                        ALL_PAGES_ARRAY);
            } else if (Arrays.equals(writtenPages, ALL_PAGES_ARRAY)) {
                // We requested specific pages but got all of them. Hence,
                // the printer has to print only the requested pages.
                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
                        requestedPages);
            } else if (PageRangeUtils.contains(writtenPages, requestedPages)) {
                // We requested specific pages and got more but not all pages.
                // Hence, we have to offset appropriately the printed pages to
                // be based off the start of the written ones instead of zero.
                // The written pages are always non-null and not empty.
                final int offset = -writtenPages[0].getStart();
                PageRange[] offsetPages = Arrays.copyOf(requestedPages, requestedPages.length);
                PageRangeUtils.offset(offsetPages, offset);
                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
                        offsetPages);
            } else if (Arrays.equals(requestedPages, ALL_PAGES_ARRAY)
                    && writtenPages.length == 1 && writtenPages[0].getStart() == 0
                    && writtenPages[0].getEnd() == mDocument.info.getPageCount() - 1) {
                // We requested all pages via the special constant and got all
                // of them as an explicit enumeration. Hence, the printer has
                // to print only the requested pages.
                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
                        writtenPages);
            } else {
                // We did not get the pages we requested, then the application
                // misbehaves, so we fail quickly.
                mControllerState = CONTROLLER_STATE_FAILED;
                Log.e(LOG_TAG, "Received invalid pages from the app: requested="
                        + Arrays.toString(requestedPages) + " written="
                        + Arrays.toString(writtenPages));
                mEditor.showUi(Editor.UI_ERROR, null);
            }
        }

        private void requestCreatePdfFileOrFinish() {
            if (mEditor.isPrintingToPdf()) {
                Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
                intent.setType("application/pdf");
                intent.putExtra(Intent.EXTRA_TITLE, mDocument.info.getName());
                intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, mCallingPackageName);
                startActivityForResult(intent, ACTIVITY_REQUEST_CREATE_FILE);
            } else {
                PrintJobConfigActivity.this.finish();
            }
        }

        private void handleOnWriteFailed(final CharSequence error, int sequence) {
            if (mRequestCounter.get() != sequence) {
                return;
            }
            mControllerState = CONTROLLER_STATE_FAILED;
            mEditor.showUi(Editor.UI_ERROR, new Runnable() {
                @Override
                public void run() {
                    if (!TextUtils.isEmpty(error)) {
                        TextView messageView = (TextView) findViewById(R.id.message);
                        messageView.setText(error);
                    }
                }
            });
        }

        private boolean equalsIgnoreSize(PrintDocumentInfo lhs, PrintDocumentInfo rhs) {
            if (lhs == rhs) {
                return true;
            }
            if (lhs == null) {
                if (rhs != null) {
                    return false;
                }
            } else {
                if (rhs == null) {
                    return false;
                }
                if (lhs.getContentType() != rhs.getContentType()
                        || lhs.getPageCount() != rhs.getPageCount()) {
                    return false;
                }
            }
            return true;
        }

        private final class ControllerHandler extends Handler {
            public static final int MSG_ON_LAYOUT_FINISHED = 1;
            public static final int MSG_ON_LAYOUT_FAILED = 2;
            public static final int MSG_ON_WRITE_FINISHED = 3;
            public static final int MSG_ON_WRITE_FAILED = 4;

            public ControllerHandler(Looper looper) {
                super(looper, null, false);
            }

            @Override
            public void handleMessage(Message message) {
                switch (message.what) {
                    case MSG_ON_LAYOUT_FINISHED: {
                        PrintDocumentInfo info = (PrintDocumentInfo) message.obj;
                        final boolean changed = (message.arg1 == 1);
                        final int sequence = message.arg2;
                        handleOnLayoutFinished(info, changed, sequence);
                    } break;

                    case MSG_ON_LAYOUT_FAILED: {
                        CharSequence error = (CharSequence) message.obj;
                        final int sequence = message.arg1;
                        handleOnLayoutFailed(error, sequence);
                    } break;

                    case MSG_ON_WRITE_FINISHED: {
                        PageRange[] pages = (PageRange[]) message.obj;
                        final int sequence = message.arg1;
                        handleOnWriteFinished(pages, sequence);
                    } break;

                    case MSG_ON_WRITE_FAILED: {
                        CharSequence error = (CharSequence) message.obj;
                        final int sequence = message.arg1;
                        handleOnWriteFailed(error, sequence);
                    } break;
                }
            }
        }
    }

    private static final class LayoutResultCallback extends ILayoutResultCallback.Stub {
        private final WeakReference<PrintController.ControllerHandler> mWeakHandler;

        public LayoutResultCallback(PrintController.ControllerHandler handler) {
            mWeakHandler = new WeakReference<PrintController.ControllerHandler>(handler);
        }

        @Override
        public void onLayoutFinished(PrintDocumentInfo info, boolean changed, int sequence) {
            Handler handler = mWeakHandler.get();
            if (handler != null) {
                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_LAYOUT_FINISHED,
                        changed ? 1 : 0, sequence, info).sendToTarget();
            }
        }

        @Override
        public void onLayoutFailed(CharSequence error, int sequence) {
            Handler handler = mWeakHandler.get();
            if (handler != null) {
                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_LAYOUT_FAILED,
                        sequence, 0, error).sendToTarget();
            }
        }
    }

    private static final class WriteResultCallback extends IWriteResultCallback.Stub {
        private final WeakReference<PrintController.ControllerHandler> mWeakHandler;

        public WriteResultCallback(PrintController.ControllerHandler handler) {
            mWeakHandler = new WeakReference<PrintController.ControllerHandler>(handler);
        }

        @Override
        public void onWriteFinished(PageRange[] pages, int sequence) {
            Handler handler = mWeakHandler.get();
            if (handler != null) {
                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_WRITE_FINISHED,
                        sequence, 0, pages).sendToTarget();
            }
        }

        @Override
        public void onWriteFailed(CharSequence error, int sequence) {
            Handler handler = mWeakHandler.get();
            if (handler != null) {
                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_WRITE_FAILED,
                    sequence, 0, error).sendToTarget();
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case ACTIVITY_REQUEST_CREATE_FILE: {
                if (data != null) {
                    Uri uri = data.getData();
                    writePrintJobDataAndFinish(uri);
                } else {
                    mEditor.showUi(Editor.UI_EDITING_PRINT_JOB,
                            new Runnable() {
                        @Override
                        public void run() {
                            mEditor.initialize();
                            mEditor.bindUi();
                            mEditor.reselectCurrentPrinter();
                            mEditor.updateUi();
                        }
                    });
                }
            } break;

            case ACTIVITY_REQUEST_SELECT_PRINTER: {
                if (resultCode == RESULT_OK) {
                    PrinterId printerId = (PrinterId) data.getParcelableExtra(
                            INTENT_EXTRA_PRINTER_ID);
                    if (printerId != null) {
                        mEditor.ensurePrinterSelected(printerId);
                        break;
                    }
                }
                mEditor.ensureCurrentPrinterSelected();
            } break;

            case ACTIVITY_POPULATE_ADVANCED_PRINT_OPTIONS: {
                if (resultCode == RESULT_OK) {
                    PrintJobInfo printJobInfo = (PrintJobInfo) data.getParcelableExtra(
                            PrintService.EXTRA_PRINT_JOB_INFO);
                    if (printJobInfo != null) {
                        mEditor.updateFromAdvancedOptions(printJobInfo);
                        break;
                    }
                }
                mEditor.cancel();
                PrintJobConfigActivity.this.finish();
            } break;
        }
    }

    private void writePrintJobDataAndFinish(final Uri uri) {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                InputStream in = null;
                OutputStream out = null;
                try {
                    PrintJobInfo printJob = mSpoolerProvider.getSpooler()
                            .getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY);
                    if (printJob == null) {
                        return null;
                    }
                    File file = mSpoolerProvider.getSpooler()
                            .generateFileForPrintJob(mPrintJobId);
                    in = new FileInputStream(file);
                    out = getContentResolver().openOutputStream(uri);
                    final byte[] buffer = new byte[8192];
                    while (true) {
                        final int readByteCount = in.read(buffer);
                        if (readByteCount < 0) {
                            break;
                        }
                        out.write(buffer, 0, readByteCount);
                    }
                } catch (FileNotFoundException fnfe) {
                    Log.e(LOG_TAG, "Error writing print job data!", fnfe);
                } catch (IOException ioe) {
                    Log.e(LOG_TAG, "Error writing print job data!", ioe);
                } finally {
                    IoUtils.closeQuietly(in);
                    IoUtils.closeQuietly(out);
                }
                return null;
            }

            @Override
            public void onPostExecute(Void result) {
                mEditor.cancel();
                PrintJobConfigActivity.this.finish();
            }
        }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
    }

    private final class Editor {
        private static final int UI_NONE = 0;
        private static final int UI_EDITING_PRINT_JOB = 1;
        private static final int UI_GENERATING_PRINT_JOB = 2;
        private static final int UI_ERROR = 3;

        private EditText mCopiesEditText;

        private TextView mRangeOptionsTitle;
        private TextView mPageRangeTitle;
        private EditText mPageRangeEditText;

        private Spinner mDestinationSpinner;
        private DestinationAdapter mDestinationSpinnerAdapter;

        private Spinner mMediaSizeSpinner;
        private ArrayAdapter<SpinnerItem<MediaSize>> mMediaSizeSpinnerAdapter;

        private Spinner mColorModeSpinner;
        private ArrayAdapter<SpinnerItem<Integer>> mColorModeSpinnerAdapter;

        private Spinner mOrientationSpinner;
        private  ArrayAdapter<SpinnerItem<Integer>> mOrientationSpinnerAdapter;

        private Spinner mRangeOptionsSpinner;
        private ArrayAdapter<SpinnerItem<Integer>> mRangeOptionsSpinnerAdapter;

        private SimpleStringSplitter mStringCommaSplitter =
                new SimpleStringSplitter(',');

        private View mContentContainer;

        private View mAdvancedPrintOptionsContainer;

        private Button mAdvancedOptionsButton;

        private Button mPrintButton;

        private PrinterId mNextPrinterId;

        private PrinterInfo mCurrentPrinter;

        private MediaSizeComparator mMediaSizeComparator;

        private final OnFocusChangeListener mFocusListener = new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean hasFocus) {
                EditText editText = (EditText) view;
                if (!TextUtils.isEmpty(editText.getText())) {
                    editText.setSelection(editText.getText().length());
                }
            }
        };

        private final OnItemSelectedListener mOnItemSelectedListener =
                new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> spinner, View view, int position, long id) {
                if (spinner == mDestinationSpinner) {
                    if (mIgnoreNextDestinationChange) {
                        mIgnoreNextDestinationChange = false;
                        return;
                    }

                    if (position == AdapterView.INVALID_POSITION) {
                        updateUi();
                        return;
                    }

                    if (id == DEST_ADAPTER_ITEM_ID_ALL_PRINTERS) {
                        startSelectPrinterActivity();
                        return;
                    }

                    mCapabilitiesTimeout.remove();

                    mCurrentPrinter = (PrinterInfo) mDestinationSpinnerAdapter
                            .getItem(position);

                    mSpoolerProvider.getSpooler().setPrintJobPrinterNoPersistence(
                            mPrintJobId, mCurrentPrinter);

                    if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
                        mCapabilitiesTimeout.post();
                        updateUi();
                        return;
                    }

                    PrinterCapabilitiesInfo capabilities = mCurrentPrinter.getCapabilities();
                    if (capabilities == null) {
                        mCapabilitiesTimeout.post();
                        updateUi();
                        refreshCurrentPrinter();
                    } else {
                        updatePrintAttributes(capabilities);
                        updateUi();
                        mController.update();
                        refreshCurrentPrinter();
                    }
                } else if (spinner == mMediaSizeSpinner) {
                    if (mIgnoreNextMediaSizeChange) {
                        mIgnoreNextMediaSizeChange = false;
                        return;
                    }
                    if (mOldMediaSizeSelectionIndex
                            == mMediaSizeSpinner.getSelectedItemPosition()) {
                        mOldMediaSizeSelectionIndex = AdapterView.INVALID_POSITION;
                        return;
                    }
                    SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(position);
                    if (mOrientationSpinner.getSelectedItemPosition() == 0) {
                        mCurrPrintAttributes.setMediaSize(mediaItem.value.asPortrait());
                    } else {
                        mCurrPrintAttributes.setMediaSize(mediaItem.value.asLandscape());
                    }
                    if (!hasErrors()) {
                        mController.update();
                    }
                } else if (spinner == mColorModeSpinner) {
                    if (mIgnoreNextColorChange) {
                        mIgnoreNextColorChange = false;
                        return;
                    }
                    if (mOldColorModeSelectionIndex
                            == mColorModeSpinner.getSelectedItemPosition()) {
                        mOldColorModeSelectionIndex = AdapterView.INVALID_POSITION;
                        return;
                    }
                    SpinnerItem<Integer> colorModeItem =
                            mColorModeSpinnerAdapter.getItem(position);
                    mCurrPrintAttributes.setColorMode(colorModeItem.value);
                    if (!hasErrors()) {
                        mController.update();
                    }
                } else if (spinner == mOrientationSpinner) {
                    if (mIgnoreNextOrientationChange) {
                        mIgnoreNextOrientationChange = false;
                        return;
                    }
                    SpinnerItem<Integer> orientationItem =
                            mOrientationSpinnerAdapter.getItem(position);
                    setCurrentPrintAttributesOrientation(orientationItem.value);
                    if (!hasErrors()) {
                        mController.update();
                    }
                } else if (spinner == mRangeOptionsSpinner) {
                    if (mIgnoreNextRangeOptionChange) {
                        mIgnoreNextRangeOptionChange = false;
                        return;
                    }
                    updateUi();
                    if (!hasErrors()) {
                        mController.update();
                    }
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                /* do nothing*/
            }
        };

        private void setCurrentPrintAttributesOrientation(int orientation) {
            MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
            if (orientation == ORIENTATION_PORTRAIT) {
                if (!mediaSize.isPortrait()) {
                    // Rotate the media size.
                    mCurrPrintAttributes.setMediaSize(mediaSize.asPortrait());

                    // Rotate the resolution.
                    Resolution oldResolution = mCurrPrintAttributes.getResolution();
                    Resolution newResolution = new Resolution(
                            oldResolution.getId(),
                            oldResolution.getLabel(),
                            oldResolution.getVerticalDpi(),
                            oldResolution.getHorizontalDpi());
                    mCurrPrintAttributes.setResolution(newResolution);

                    // Rotate the physical margins.
                    Margins oldMinMargins = mCurrPrintAttributes.getMinMargins();
                    Margins newMinMargins = new Margins(
                            oldMinMargins.getBottomMils(),
                            oldMinMargins.getLeftMils(),
                            oldMinMargins.getTopMils(),
                            oldMinMargins.getRightMils());
                    mCurrPrintAttributes.setMinMargins(newMinMargins);
                }
            } else {
                if (mediaSize.isPortrait()) {
                    // Rotate the media size.
                    mCurrPrintAttributes.setMediaSize(mediaSize.asLandscape());

                    // Rotate the resolution.
                    Resolution oldResolution = mCurrPrintAttributes.getResolution();
                    Resolution newResolution = new Resolution(
                            oldResolution.getId(),
                            oldResolution.getLabel(),
                            oldResolution.getVerticalDpi(),
                            oldResolution.getHorizontalDpi());
                    mCurrPrintAttributes.setResolution(newResolution);

                    // Rotate the physical margins.
                    Margins oldMinMargins = mCurrPrintAttributes.getMinMargins();
                    Margins newMargins = new Margins(
                            oldMinMargins.getTopMils(),
                            oldMinMargins.getRightMils(),
                            oldMinMargins.getBottomMils(),
                            oldMinMargins.getLeftMils());
                    mCurrPrintAttributes.setMinMargins(newMargins);
                }
            }
        }

        private void updatePrintAttributes(PrinterCapabilitiesInfo capabilities) {
            PrintAttributes defaults = capabilities.getDefaults();

            // Sort the media sizes based on the current locale.
            List<MediaSize> sortedMediaSizes = new ArrayList<MediaSize>(
                    capabilities.getMediaSizes());
            Collections.sort(sortedMediaSizes, mMediaSizeComparator);

            // Media size.
            MediaSize currMediaSize = mCurrPrintAttributes.getMediaSize();
            if (currMediaSize == null) {
                mCurrPrintAttributes.setMediaSize(defaults.getMediaSize());
            } else {
                MediaSize currMediaSizePortrait = currMediaSize.asPortrait();
                final int mediaSizeCount = sortedMediaSizes.size();
                for (int i = 0; i < mediaSizeCount; i++) {
                    MediaSize mediaSize = sortedMediaSizes.get(i);
                    if (currMediaSizePortrait.equals(mediaSize.asPortrait())) {
                        mCurrPrintAttributes.setMediaSize(currMediaSize);
                        break;
                    }
                }
            }

            // Color mode.
            final int colorMode = mCurrPrintAttributes.getColorMode();
            if ((capabilities.getColorModes() & colorMode) == 0) {
                mCurrPrintAttributes.setColorMode(colorMode);
            }

            // Resolution
            Resolution resolution = mCurrPrintAttributes.getResolution();
            if (resolution == null || !capabilities.getResolutions().contains(resolution)) {
                mCurrPrintAttributes.setResolution(defaults.getResolution());
            }

            // Margins.
            Margins margins = mCurrPrintAttributes.getMinMargins();
            if (margins == null) {
                mCurrPrintAttributes.setMinMargins(defaults.getMinMargins());
            } else {
                Margins minMargins = capabilities.getMinMargins();
                if (margins.getLeftMils() < minMargins.getLeftMils()
                        || margins.getTopMils() < minMargins.getTopMils()
                        || margins.getRightMils() > minMargins.getRightMils()
                        || margins.getBottomMils() > minMargins.getBottomMils()) {
                    mCurrPrintAttributes.setMinMargins(defaults.getMinMargins());
                }
            }
        }

        private final TextWatcher mCopiesTextWatcher = new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                /* do nothing */
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                /* do nothing */
            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (mIgnoreNextCopiesChange) {
                    mIgnoreNextCopiesChange = false;
                    return;
                }

                final boolean hadErrors = hasErrors();

                if (editable.length() == 0) {
                    mCopiesEditText.setError("");
                    updateUi();
                    return;
                }

                int copies = 0;
                try {
                    copies = Integer.parseInt(editable.toString());
                } catch (NumberFormatException nfe) {
                    /* ignore */
                }

                if (copies < MIN_COPIES) {
                    mCopiesEditText.setError("");
                    updateUi();
                    return;
                }

                mCopiesEditText.setError(null);
                mSpoolerProvider.getSpooler().setPrintJobCopiesNoPersistence(
                        mPrintJobId, copies);
                updateUi();

                if (hadErrors && !hasErrors() && printAttributesChanged()) {
                    mController.update();
                }
            }
        };

        private final TextWatcher mRangeTextWatcher = new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                /* do nothing */
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                /* do nothing */
            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (mIgnoreNextRangeChange) {
                    mIgnoreNextRangeChange = false;
                    return;
                }

                final boolean hadErrors = hasErrors();

                String text = editable.toString();

                if (TextUtils.isEmpty(text)) {
                    mPageRangeEditText.setError("");
                    updateUi();
                    return;
                }

                String escapedText = PATTERN_ESCAPE_SPECIAL_CHARS.matcher(text).replaceAll("////");
                if (!PATTERN_PAGE_RANGE.matcher(escapedText).matches()) {
                    mPageRangeEditText.setError("");
                    updateUi();
                    return;
                }

                // The range
                Matcher matcher = PATTERN_DIGITS.matcher(text);
                while (matcher.find()) {
                    String numericString = text.substring(matcher.start(), matcher.end()).trim();
                    if (TextUtils.isEmpty(numericString)) {
                        continue;
                    }
                    final int pageIndex = Integer.parseInt(numericString);
                    if (pageIndex < 1 || pageIndex > mDocument.info.getPageCount()) {
                        mPageRangeEditText.setError("");
                        updateUi();
                        return;
                    }
                }

                // We intentionally do not catch the case of the from page being
                // greater than the to page. When computing the requested pages
                // we just swap them if necessary.

                // Keep the print job up to date with the selected pages if we
                // know how many pages are there in the document.
                PageRange[] requestedPages = getRequestedPages();
                if (requestedPages != null && requestedPages.length > 0
                        && requestedPages[requestedPages.length - 1].getEnd()
                                < mDocument.info.getPageCount()) {
                    mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(
                            mPrintJobId, requestedPages);
                }

                mPageRangeEditText.setError(null);
                mPrintButton.setEnabled(true);
                updateUi();

                if (hadErrors && !hasErrors() && printAttributesChanged()) {
                    updateUi();
                }
            }
        };

        private final WaitForPrinterCapabilitiesTimeout mCapabilitiesTimeout =
                new WaitForPrinterCapabilitiesTimeout();

        private int mEditorState;

        private boolean mIgnoreNextDestinationChange;
        private int mOldMediaSizeSelectionIndex;
        private int mOldColorModeSelectionIndex;
        private boolean mIgnoreNextOrientationChange;
        private boolean mIgnoreNextRangeOptionChange;
        private boolean mIgnoreNextCopiesChange;
        private boolean mIgnoreNextRangeChange;
        private boolean mIgnoreNextMediaSizeChange;
        private boolean mIgnoreNextColorChange;

        private int mCurrentUi = UI_NONE;

        private boolean mFavoritePrinterSelected;

        public Editor() {
            showUi(UI_EDITING_PRINT_JOB, null);
        }

        public void postCreate() {
            // Destination.
            mMediaSizeComparator = new MediaSizeComparator(PrintJobConfigActivity.this);
            mDestinationSpinnerAdapter = new DestinationAdapter();
            mDestinationSpinnerAdapter.registerDataSetObserver(new DataSetObserver() {
                @Override
                public void onChanged() {
                    // Initially, we have only safe to PDF as a printer but after some
                    // printers are loaded we want to select the user's favorite one
                    // which is the first.
                    if (!mFavoritePrinterSelected && mDestinationSpinnerAdapter.getCount() > 1) {
                        mFavoritePrinterSelected = true;
                        mDestinationSpinner.setSelection(0);
                        // Workaround again the weird spinner behavior to notify for selection
                        // change on the next layout pass as the current printer is used below.
                        mCurrentPrinter = (PrinterInfo) mDestinationSpinnerAdapter.getItem(0);
                    }

                    // If there is a next printer to select and we succeed selecting
                    // it - done. Let the selection handling code make everything right.
                    if (mNextPrinterId != null && selectPrinter(mNextPrinterId)) {
                        mNextPrinterId = null;
                        return;
                    }

                    // If the current printer properties changed, we update the UI.
                    if (mCurrentPrinter != null) {
                        final int printerCount = mDestinationSpinnerAdapter.getCount();
                        for (int i = 0; i < printerCount; i++) {
                            Object item = mDestinationSpinnerAdapter.getItem(i);
                            // Some items are not printers
                            if (item instanceof PrinterInfo) {
                                PrinterInfo printer = (PrinterInfo) item;
                                if (!printer.getId().equals(mCurrentPrinter.getId())) {
                                    continue;
                                }

                                // If nothing changed - done.
                                if (mCurrentPrinter.equals(printer)) {
                                    return;
                                }

                                // If the current printer became available and has no
                                // capabilities, we refresh it.
                                if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE
                                        && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
                                        && printer.getCapabilities() == null) {
                                    if (!mCapabilitiesTimeout.isPosted()) {
                                        mCapabilitiesTimeout.post();
                                    }
                                    mCurrentPrinter.copyFrom(printer);
                                    refreshCurrentPrinter();
                                    return;
                                }

                                // If the current printer became unavailable or its
                                // capabilities go away, we update the UI and add a
                                // timeout to declare the printer as unavailable.
                                if ((mCurrentPrinter.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
                                        && printer.getStatus() == PrinterInfo.STATUS_UNAVAILABLE)
                                    || (mCurrentPrinter.getCapabilities() != null
                                        && printer.getCapabilities() == null)) {
                                    if (!mCapabilitiesTimeout.isPosted()) {
                                        mCapabilitiesTimeout.post();
                                    }
                                    mCurrentPrinter.copyFrom(printer);
                                    updateUi();
                                    return;
                                }

                                // We just refreshed the current printer.
                                if (printer.getCapabilities() != null
                                        && mCapabilitiesTimeout.isPosted()) {
                                    mCapabilitiesTimeout.remove();
                                    updatePrintAttributes(printer.getCapabilities());
                                    updateUi();
                                    mController.update();
                                }

                                // Update the UI if capabilities changed.
                                boolean capabilitiesChanged = false;

                                if (mCurrentPrinter.getCapabilities() == null) {
                                    if (printer.getCapabilities() != null) {
                                        updatePrintAttributes(printer.getCapabilities());
                                        capabilitiesChanged = true;
                                    }
                                } else if (!mCurrentPrinter.getCapabilities().equals(
                                        printer.getCapabilities())) {
                                    capabilitiesChanged = true;
                                }

                                // Update the UI if the status changed.
                                final boolean statusChanged = mCurrentPrinter.getStatus()
                                        != printer.getStatus();

                                // Update the printer with the latest info.
                                if (!mCurrentPrinter.equals(printer)) {
                                    mCurrentPrinter.copyFrom(printer);
                                }

                                if (capabilitiesChanged || statusChanged) {
                                    // If something changed during update...
                                    if (updateUi() || !mController.hasPerformedLayout()) {
                                        // Update the document.
                                        mController.update();
                                    }
                                }

                                break;
                            }
                        }
                    }
                }

                @Override
                public void onInvalidated() {
                    /* do nothing - we always have one fake PDF printer */
                }
            });

            // Media size.
            mMediaSizeSpinnerAdapter = new ArrayAdapter<SpinnerItem<MediaSize>>(
                    PrintJobConfigActivity.this,
                    R.layout.spinner_dropdown_item, R.id.title);

            // Color mode.
            mColorModeSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
                    PrintJobConfigActivity.this,
                    R.layout.spinner_dropdown_item, R.id.title);

            // Orientation
            mOrientationSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
                    PrintJobConfigActivity.this,
                    R.layout.spinner_dropdown_item, R.id.title);
            String[] orientationLabels = getResources().getStringArray(
                  R.array.orientation_labels);
            mOrientationSpinnerAdapter.add(new SpinnerItem<Integer>(
                    ORIENTATION_PORTRAIT, orientationLabels[0]));
            mOrientationSpinnerAdapter.add(new SpinnerItem<Integer>(
                    ORIENTATION_LANDSCAPE, orientationLabels[1]));

            // Range options
            mRangeOptionsSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
                    PrintJobConfigActivity.this,
                    R.layout.spinner_dropdown_item, R.id.title);
            final int[] rangeOptionsValues = getResources().getIntArray(
                    R.array.page_options_values);
            String[] rangeOptionsLabels = getResources().getStringArray(
                    R.array.page_options_labels);
            final int rangeOptionsCount = rangeOptionsLabels.length;
            for (int i = 0; i < rangeOptionsCount; i++) {
                mRangeOptionsSpinnerAdapter.add(new SpinnerItem<Integer>(
                        rangeOptionsValues[i], rangeOptionsLabels[i]));
            }

            showUi(UI_EDITING_PRINT_JOB, null);
            bindUi();
            updateUi();
        }

        public void reselectCurrentPrinter() {
            if (mCurrentPrinter != null) {
                // TODO: While the data did not change and we set the adapter
                // to a newly inflated spinner, the latter does not show the
                // current item unless we poke the adapter. This requires more
                // investigation. Maybe an optimization in AdapterView does not
                // call into the adapter if the view is not visible which is the
                // case when we set the adapter.
                mDestinationSpinnerAdapter.notifyDataSetChanged();
                final int position = mDestinationSpinnerAdapter.getPrinterIndex(
                        mCurrentPrinter.getId());
                mDestinationSpinner.setSelection(position);
            }
        }

        public void refreshCurrentPrinter() {
            PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
            if (printer != null) {
                FusedPrintersProvider printersLoader = (FusedPrintersProvider)
                        (Loader<?>) getLoaderManager().getLoader(
                                LOADER_ID_PRINTERS_LOADER);
                if (printersLoader != null) {
                    printersLoader.setTrackedPrinter(printer.getId());
                }
            }
        }

        public void addCurrentPrinterToHistory() {
            PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
            PrinterId fakePdfPritnerId = mDestinationSpinnerAdapter.mFakePdfPrinter.getId();
            if (printer != null && !printer.getId().equals(fakePdfPritnerId)) {
                FusedPrintersProvider printersLoader = (FusedPrintersProvider)
                        (Loader<?>) getLoaderManager().getLoader(
                                LOADER_ID_PRINTERS_LOADER);
                if (printersLoader != null) {
                    printersLoader.addHistoricalPrinter(printer);
                }
            }
        }

        public void updateFromAdvancedOptions(PrintJobInfo printJobInfo) {
            boolean updateContent = false;

            // Copies.
            mCopiesEditText.setText(String.valueOf(printJobInfo.getCopies()));

            // Media size and orientation
            PrintAttributes attributes = printJobInfo.getAttributes();
            if (!mCurrPrintAttributes.getMediaSize().equals(attributes.getMediaSize())) {
                final int mediaSizeCount = mMediaSizeSpinnerAdapter.getCount();
                for (int i = 0; i < mediaSizeCount; i++) {
                    MediaSize mediaSize = mMediaSizeSpinnerAdapter.getItem(i).value;
                    if (mediaSize.asPortrait().equals(attributes.getMediaSize().asPortrait())) {
                        updateContent = true;
                        mCurrPrintAttributes.setMediaSize(attributes.getMediaSize());
                        mMediaSizeSpinner.setSelection(i);
                        mIgnoreNextMediaSizeChange = true;
                        if (attributes.getMediaSize().isPortrait()) {
                            mOrientationSpinner.setSelection(0);
                            mIgnoreNextOrientationChange = true;
                        } else {
                            mOrientationSpinner.setSelection(1);
                            mIgnoreNextOrientationChange = true;
                        }
                        break;
                    }
                }
            }

            // Color mode.
            final int colorMode = attributes.getColorMode();
            if (mCurrPrintAttributes.getColorMode() != colorMode) {
                if (colorMode == PrintAttributes.COLOR_MODE_MONOCHROME) {
                    updateContent = true;
                    mColorModeSpinner.setSelection(0);
                    mIgnoreNextColorChange = true;
                    mCurrPrintAttributes.setColorMode(attributes.getColorMode());
                } else if (colorMode == PrintAttributes.COLOR_MODE_COLOR) {
                    updateContent = true;
                    mColorModeSpinner.setSelection(1);
                    mIgnoreNextColorChange = true;
                    mCurrPrintAttributes.setColorMode(attributes.getColorMode());
                }
            }

            // Range.
            PageRange[] pageRanges = printJobInfo.getPages();
            if (pageRanges != null && pageRanges.length > 0) {
                pageRanges = PageRangeUtils.normalize(pageRanges);
                final int pageRangeCount = pageRanges.length;
                if (pageRangeCount == 1 && pageRanges[0] == PageRange.ALL_PAGES) {
                    mRangeOptionsSpinner.setSelection(0);
                } else {
                    final int pageCount = mDocument.info.getPageCount();
                    if (pageRanges[0].getStart() >= 0
                            && pageRanges[pageRanges.length - 1].getEnd() < pageCount) {
                        mRangeOptionsSpinner.setSelection(1);
                        StringBuilder builder = new StringBuilder();
                        for (int i = 0; i < pageRangeCount; i++) {
                            if (builder.length() > 0) {
                                builder.append(',');
                            }
                            PageRange pageRange = pageRanges[i];
                            final int shownStartPage = pageRange.getStart() + 1;
                            final int shownEndPage = pageRange.getEnd() + 1;
                            builder.append(shownStartPage);
                            if (shownStartPage != shownEndPage) {
                                builder.append('-');
                                builder.append(shownEndPage);
                            }
                        }
                        mPageRangeEditText.setText(builder.toString());
                    }
                }
            }

            // Update the advanced options.
            mSpoolerProvider.getSpooler().setPrintJobAdvancedOptionsNoPersistence(
                    mPrintJobId, printJobInfo.getAdvancedOptions());

            // Update the content if needed.
            if (updateContent) {
                mController.update();
            }
        }

        public void ensurePrinterSelected(PrinterId printerId) {
            // If the printer is not present maybe the loader is not
            // updated yet. In this case make a note and as soon as
            // the printer appears will will select it.
            if (!selectPrinter(printerId)) {
                mNextPrinterId = printerId;
            }
        }

        public boolean selectPrinter(PrinterId printerId) {
            mDestinationSpinnerAdapter.ensurePrinterInVisibleAdapterPosition(printerId);
            final int position = mDestinationSpinnerAdapter.getPrinterIndex(printerId);
            if (position != AdapterView.INVALID_POSITION
                    && position != mDestinationSpinner.getSelectedItemPosition()) {
                Object item = mDestinationSpinnerAdapter.getItem(position);
                mCurrentPrinter = (PrinterInfo) item;
                mDestinationSpinner.setSelection(position);
                return true;
            }
            return false;
        }

        public void ensureCurrentPrinterSelected() {
            if (mCurrentPrinter != null) {
                selectPrinter(mCurrentPrinter.getId());
            }
        }

        public boolean isPrintingToPdf() {
            return mDestinationSpinner.getSelectedItem()
                    == mDestinationSpinnerAdapter.mFakePdfPrinter;
        }

        public boolean shouldCloseOnTouch(MotionEvent event) {
            if (event.getAction() != MotionEvent.ACTION_DOWN) {
                return false;
            }

            final int[] locationInWindow = new int[2];
            mContentContainer.getLocationInWindow(locationInWindow);

            final int windowTouchSlop = ViewConfiguration.get(PrintJobConfigActivity.this)
                    .getScaledWindowTouchSlop();
            final int eventX = (int) event.getX();
            final int eventY = (int) event.getY();
            final int lenientWindowLeft = locationInWindow[0] - windowTouchSlop;
            final int lenientWindowRight = lenientWindowLeft + mContentContainer.getWidth()
                    + windowTouchSlop;
            final int lenientWindowTop = locationInWindow[1] - windowTouchSlop;
            final int lenientWindowBottom = lenientWindowTop + mContentContainer.getHeight()
                    + windowTouchSlop;

            if (eventX < lenientWindowLeft || eventX > lenientWindowRight
                    || eventY < lenientWindowTop || eventY > lenientWindowBottom) {
                return true;
            }
            return false;
        }

        public boolean isShwoingGeneratingPrintJobUi() {
            return (mCurrentUi == UI_GENERATING_PRINT_JOB);
        }

        public void showUi(int ui, final Runnable postSwitchCallback) {
            if (ui == UI_NONE) {
                throw new IllegalStateException("cannot remove the ui");
            }

            if (mCurrentUi == ui) {
                return;
            }

            final int oldUi = mCurrentUi;
            mCurrentUi = ui;

            switch (oldUi) {
                case UI_NONE: {
                    switch (ui) {
                        case UI_EDITING_PRINT_JOB: {
                            doUiSwitch(R.layout.print_job_config_activity_content_editing);
                            registerPrintButtonClickListener();
                            if (postSwitchCallback != null) {
                                postSwitchCallback.run();
                            }
                        } break;

                        case UI_GENERATING_PRINT_JOB: {
                            doUiSwitch(R.layout.print_job_config_activity_content_generating);
                            registerCancelButtonClickListener();
                            if (postSwitchCallback != null) {
                                postSwitchCallback.run();
                            }
                        } break;
                    }
                } break;

                case UI_EDITING_PRINT_JOB: {
                    switch (ui) {
                        case UI_GENERATING_PRINT_JOB: {
                            animateUiSwitch(R.layout.print_job_config_activity_content_generating,
                                    new Runnable() {
                                @Override
                                public void run() {
                                    registerCancelButtonClickListener();
                                    if (postSwitchCallback != null) {
                                        postSwitchCallback.run();
                                    }
                                }
                            },
                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                                    ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
                        } break;

                        case UI_ERROR: {
                            animateUiSwitch(R.layout.print_job_config_activity_content_error,
                                    new Runnable() {
                                @Override
                                public void run() {
                                    registerOkButtonClickListener();
                                    if (postSwitchCallback != null) {
                                        postSwitchCallback.run();
                                    }
                                }
                            },
                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                                    ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
                        } break;
                    }
                } break;

                case UI_GENERATING_PRINT_JOB: {
                    switch (ui) {
                        case UI_EDITING_PRINT_JOB: {
                            animateUiSwitch(R.layout.print_job_config_activity_content_editing,
                                    new Runnable() {
                                @Override
                                public void run() {
                                    registerPrintButtonClickListener();
                                    if (postSwitchCallback != null) {
                                        postSwitchCallback.run();
                                    }
                                }
                            },
                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                    ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
                        } break;

                        case UI_ERROR: {
                            animateUiSwitch(R.layout.print_job_config_activity_content_error,
                                    new Runnable() {
                                @Override
                                public void run() {
                                    registerOkButtonClickListener();
                                    if (postSwitchCallback != null) {
                                        postSwitchCallback.run();
                                    }
                                }
                            },
                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                                    ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
                        } break;
                    }
                } break;

                case UI_ERROR: {
                    switch (ui) {
                        case UI_EDITING_PRINT_JOB: {
                            animateUiSwitch(R.layout.print_job_config_activity_content_editing,
                                    new Runnable() {
                                @Override
                                public void run() {
                                    registerPrintButtonClickListener();
                                    if (postSwitchCallback != null) {
                                        postSwitchCallback.run();
                                    }
                                }
                            },
                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                    ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
                        } break;
                    }
                } break;
            }
        }

        private void registerAdvancedPrintOptionsButtonClickListener() {
            Button advancedOptionsButton = (Button) findViewById(R.id.advanced_settings_button);
            advancedOptionsButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    ComponentName serviceName = mCurrentPrinter.getId().getServiceName();
                    String activityName = getAdvancedOptionsActivityName(serviceName);
                    if (TextUtils.isEmpty(activityName)) {
                        return;
                    }
                    Intent intent = new Intent(Intent.ACTION_MAIN);
                    intent.setComponent(new ComponentName(serviceName.getPackageName(),
                            activityName));

                    List<ResolveInfo> resolvedActivities = getPackageManager()
                            .queryIntentActivities(intent, 0);
                    if (resolvedActivities.isEmpty()) {
                        return;
                    }
                    // The activity is a component name, therefore it is one or none.
                    if (resolvedActivities.get(0).activityInfo.exported) {
                        PrintJobInfo printJobInfo = mSpoolerProvider.getSpooler().getPrintJobInfo(
                                mPrintJobId, PrintManager.APP_ID_ANY);
                        intent.putExtra(PrintService.EXTRA_PRINT_JOB_INFO, printJobInfo);
                        // TODO: Make this an API for the next release.
                        intent.putExtra("android.intent.extra.print.EXTRA_PRINTER_INFO",
                                mCurrentPrinter);
                        try {
                            startActivityForResult(intent,
                                    ACTIVITY_POPULATE_ADVANCED_PRINT_OPTIONS);
                        } catch (ActivityNotFoundException anfe) {
                            Log.e(LOG_TAG, "Error starting activity for intent: " + intent, anfe);
                        }
                    }
                }
            });
        }

        private void registerPrintButtonClickListener() {
            Button printButton = (Button) findViewById(R.id.print_button);
            printButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
                    if (printer != null) {
                        mEditor.confirmPrint();
                        mController.update();
                        if (!printer.equals(mDestinationSpinnerAdapter.mFakePdfPrinter)) {
                            mEditor.refreshCurrentPrinter();
                        }
                    } else {
                        mEditor.cancel();
                        PrintJobConfigActivity.this.finish();
                    }
                }
            });
        }

        private void registerCancelButtonClickListener() {
            Button cancelButton = (Button) findViewById(R.id.cancel_button);
            cancelButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!mController.isWorking()) {
                        PrintJobConfigActivity.this.finish();
                    }
                    mEditor.cancel();
                }
            });
        }

        private void registerOkButtonClickListener() {
            Button okButton = (Button) findViewById(R.id.ok_button);
            okButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    mEditor.showUi(Editor.UI_EDITING_PRINT_JOB, new Runnable() {
                        @Override
                        public void run() {
                            // Start over with a clean slate.
                            mOldPrintAttributes.clear();
                            mController.initialize();
                            mEditor.initialize();
                            mEditor.bindUi();
                            mEditor.reselectCurrentPrinter();
                            if (!mController.hasPerformedLayout()) {
                                mController.update();
                            }
                        }
                    });
                }
            });
        }

        private void doUiSwitch(int showLayoutId) {
            ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
            contentContainer.removeAllViews();
            getLayoutInflater().inflate(showLayoutId, contentContainer, true);
        }

        private void animateUiSwitch(int showLayoutId, final Runnable beforeShowNewUiAction,
                final LayoutParams containerParams) {
            // Find everything we will shuffle around.
            final ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
            final View hidingView = contentContainer.getChildAt(0);
            final View showingView = getLayoutInflater().inflate(showLayoutId,
                    null, false);

            // First animation - fade out the old content.
            AutoCancellingAnimator.animate(hidingView).alpha(0.0f)
                    .withLayer().withEndAction(new Runnable() {
                @Override
                public void run() {
                    hidingView.setVisibility(View.INVISIBLE);

                    // Prepare the new content with correct size and alpha.
                    showingView.setMinimumWidth(contentContainer.getWidth());
                    showingView.setAlpha(0.0f);

                    // Compute how to much shrink /stretch the content.
                    final int widthSpec = MeasureSpec.makeMeasureSpec(
                            contentContainer.getWidth(), MeasureSpec.UNSPECIFIED);
                    final int heightSpec = MeasureSpec.makeMeasureSpec(
                            contentContainer.getHeight(), MeasureSpec.UNSPECIFIED);
                    showingView.measure(widthSpec, heightSpec);
                    final float scaleY = (float) showingView.getMeasuredHeight()
                            / (float) contentContainer.getHeight();

                    // Second animation - resize the container.
                    AutoCancellingAnimator.animate(contentContainer).scaleY(scaleY)
                            .withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            // Swap the old and the new content.
                            contentContainer.removeAllViews();
                            contentContainer.setScaleY(1.0f);
                            contentContainer.addView(showingView);

                            contentContainer.setLayoutParams(containerParams);

                            beforeShowNewUiAction.run();

                            // Third animation - show the new content.
                            AutoCancellingAnimator.animate(showingView).alpha(1.0f);
                        }
                    });
                }
            });
        }

        public void initialize() {
            mEditorState = EDITOR_STATE_INITIALIZED;
        }

        public boolean isCancelled() {
            return mEditorState == EDITOR_STATE_CANCELLED;
        }

        public void cancel() {
            mEditorState = EDITOR_STATE_CANCELLED;
            mController.cancel();
            updateUi();
        }

        public boolean isDone() {
            return isPrintConfirmed() || isCancelled();
        }

        public boolean isPrintConfirmed() {
            return mEditorState == EDITOR_STATE_CONFIRMED_PRINT;
        }

        public void confirmPrint() {
            addCurrentPrinterToHistory();
            mEditorState = EDITOR_STATE_CONFIRMED_PRINT;
            showUi(UI_GENERATING_PRINT_JOB, null);
        }

        public PageRange[] getRequestedPages() {
            if (hasErrors()) {
                return null;
            }
            if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
                List<PageRange> pageRanges = new ArrayList<PageRange>();
                mStringCommaSplitter.setString(mPageRangeEditText.getText().toString());

                while (mStringCommaSplitter.hasNext()) {
                    String range = mStringCommaSplitter.next().trim();
                    if (TextUtils.isEmpty(range)) {
                        continue;
                    }
                    final int dashIndex = range.indexOf('-');
                    final int fromIndex;
                    final int toIndex;

                    if (dashIndex > 0) {
                        fromIndex = Integer.parseInt(range.substring(0, dashIndex).trim()) - 1;
                        // It is possible that the dash is at the end since the input
                        // verification can has to allow the user to keep entering if
                        // this would lead to a valid input. So we handle this.
                        toIndex = (dashIndex < range.length() - 1)
                                ? Integer.parseInt(range.substring(dashIndex + 1,
                                        range.length()).trim()) - 1 : fromIndex;
                    } else {
                        fromIndex = toIndex = Integer.parseInt(range) - 1;
                    }

                    PageRange pageRange = new PageRange(Math.min(fromIndex, toIndex),
                            Math.max(fromIndex, toIndex));
                    pageRanges.add(pageRange);
                }

                PageRange[] pageRangesArray = new PageRange[pageRanges.size()];
                pageRanges.toArray(pageRangesArray);

                return PageRangeUtils.normalize(pageRangesArray);
            }

            return ALL_PAGES_ARRAY;
        }

        private void bindUi() {
            if (mCurrentUi != UI_EDITING_PRINT_JOB) {
                return;
            }

            // Content container
            mContentContainer = findViewById(R.id.content_container);

            // Copies
            mCopiesEditText = (EditText) findViewById(R.id.copies_edittext);
            mCopiesEditText.setOnFocusChangeListener(mFocusListener);
            mCopiesEditText.setText(MIN_COPIES_STRING);
            mCopiesEditText.setSelection(mCopiesEditText.getText().length());
            mCopiesEditText.addTextChangedListener(mCopiesTextWatcher);
            if (!TextUtils.equals(mCopiesEditText.getText(), MIN_COPIES_STRING)) {
                mIgnoreNextCopiesChange = true;
            }
            mSpoolerProvider.getSpooler().setPrintJobCopiesNoPersistence(
                    mPrintJobId, MIN_COPIES);

            // Destination.
            mDestinationSpinner = (Spinner) findViewById(R.id.destination_spinner);
            mDestinationSpinner.setDropDownWidth(ViewGroup.LayoutParams.MATCH_PARENT);
            mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter);
            mDestinationSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
            if (mDestinationSpinnerAdapter.getCount() > 0) {
                mIgnoreNextDestinationChange = true;
            }

            // Media size.
            mMediaSizeSpinner = (Spinner) findViewById(R.id.paper_size_spinner);
            mMediaSizeSpinner.setAdapter(mMediaSizeSpinnerAdapter);
            mMediaSizeSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
            if (mMediaSizeSpinnerAdapter.getCount() > 0) {
                mOldMediaSizeSelectionIndex = 0;
            }

            // Color mode.
            mColorModeSpinner = (Spinner) findViewById(R.id.color_spinner);
            mColorModeSpinner.setAdapter(mColorModeSpinnerAdapter);
            mColorModeSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
            if (mColorModeSpinnerAdapter.getCount() > 0) {
                mOldColorModeSelectionIndex = 0;
            }

            // Orientation
            mOrientationSpinner = (Spinner) findViewById(R.id.orientation_spinner);
            mOrientationSpinner.setAdapter(mOrientationSpinnerAdapter);
            mOrientationSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
            if (mOrientationSpinnerAdapter.getCount() > 0) {
                mIgnoreNextOrientationChange = true;
            }

            // Range options
            mRangeOptionsTitle = (TextView) findViewById(R.id.range_options_title);
            mRangeOptionsSpinner = (Spinner) findViewById(R.id.range_options_spinner);
            mRangeOptionsSpinner.setAdapter(mRangeOptionsSpinnerAdapter);
            mRangeOptionsSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
            if (mRangeOptionsSpinnerAdapter.getCount() > 0) {
                mIgnoreNextRangeOptionChange = true;
            }

            // Page range
            mPageRangeTitle = (TextView) findViewById(R.id.page_range_title);
            mPageRangeEditText = (EditText) findViewById(R.id.page_range_edittext);
            mPageRangeEditText.setOnFocusChangeListener(mFocusListener);
            mPageRangeEditText.addTextChangedListener(mRangeTextWatcher);

            // Advanced options button.
            mAdvancedPrintOptionsContainer = findViewById(R.id.advanced_settings_container);
            mAdvancedOptionsButton = (Button) findViewById(R.id.advanced_settings_button);
            registerAdvancedPrintOptionsButtonClickListener();

            // Print button
            mPrintButton = (Button) findViewById(R.id.print_button);
            registerPrintButtonClickListener();
        }

        public boolean updateUi() {
            if (mCurrentUi != UI_EDITING_PRINT_JOB) {
                return false;
            }
            if (isPrintConfirmed() || isCancelled()) {
                mDestinationSpinner.setEnabled(false);
                mCopiesEditText.setEnabled(false);
                mMediaSizeSpinner.setEnabled(false);
                mColorModeSpinner.setEnabled(false);
                mOrientationSpinner.setEnabled(false);
                mRangeOptionsSpinner.setEnabled(false);
                mPageRangeEditText.setEnabled(false);
                mPrintButton.setEnabled(false);
                mAdvancedOptionsButton.setEnabled(false);
                return false;
            }

            // If a printer with capabilities is selected, then we enabled all options.
            boolean allOptionsEnabled = false;
            final int selectedIndex = mDestinationSpinner.getSelectedItemPosition();
            if (selectedIndex >= 0) {
                Object item = mDestinationSpinnerAdapter.getItem(selectedIndex);
                if (item instanceof PrinterInfo) {
                    PrinterInfo printer = (PrinterInfo) item;
                    if (printer.getCapabilities() != null
                            && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE) {
                        allOptionsEnabled = true;
                    }
                }
            }

            if (!allOptionsEnabled) {
                mCopiesEditText.setEnabled(false);
                mMediaSizeSpinner.setEnabled(false);
                mColorModeSpinner.setEnabled(false);
                mOrientationSpinner.setEnabled(false);
                mRangeOptionsSpinner.setEnabled(false);
                mPageRangeEditText.setEnabled(false);
                mPrintButton.setEnabled(false);
                mAdvancedOptionsButton.setEnabled(false);
                return false;
            } else {
                boolean someAttributeSelectionChanged = false;

                PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
                PrinterCapabilitiesInfo capabilities = printer.getCapabilities();
                PrintAttributes defaultAttributes = printer.getCapabilities().getDefaults();

                // Media size.
                // Sort the media sizes based on the current locale.
                List<MediaSize> mediaSizes = new ArrayList<MediaSize>(capabilities.getMediaSizes());
                Collections.sort(mediaSizes, mMediaSizeComparator);

                // If the media sizes changed, we update the adapter and the spinner.
                boolean mediaSizesChanged = false;
                final int mediaSizeCount = mediaSizes.size();
                if (mediaSizeCount != mMediaSizeSpinnerAdapter.getCount()) {
                    mediaSizesChanged = true;
                } else {
                    for (int i = 0; i < mediaSizeCount; i++) {
                        if (!mediaSizes.get(i).equals(mMediaSizeSpinnerAdapter.getItem(i).value)) {
                            mediaSizesChanged = true;
                            break;
                        }
                    }
                }
                if (mediaSizesChanged) {
                    // Remember the old media size to try selecting it again.
                    int oldMediaSizeNewIndex = AdapterView.INVALID_POSITION;
                    MediaSize oldMediaSize = mCurrPrintAttributes.getMediaSize();

                    // Rebuild the adapter data.
                    mMediaSizeSpinnerAdapter.clear();
                    for (int i = 0; i < mediaSizeCount; i++) {
                        MediaSize mediaSize = mediaSizes.get(i);
                        if (mediaSize.asPortrait().equals(oldMediaSize.asPortrait())) {
                            // Update the index of the old selection.
                            oldMediaSizeNewIndex = i;
                        }
                        mMediaSizeSpinnerAdapter.add(new SpinnerItem<MediaSize>(
                                mediaSize, mediaSize.getLabel(getPackageManager())));
                    }

                    mMediaSizeSpinner.setEnabled(true);

                    if (oldMediaSizeNewIndex != AdapterView.INVALID_POSITION) {
                        // Select the old media size - nothing really changed.
                        setMediaSizeSpinnerSelectionNoCallback(oldMediaSizeNewIndex);
                    } else {
                        // Select the first or the default and mark if selection changed.
                        final int mediaSizeIndex = Math.max(mediaSizes.indexOf(
                                defaultAttributes.getMediaSize()), 0);
                        setMediaSizeSpinnerSelectionNoCallback(mediaSizeIndex);
                        if (oldMediaSize.isPortrait()) {
                            mCurrPrintAttributes.setMediaSize(mMediaSizeSpinnerAdapter
                                    .getItem(mediaSizeIndex).value.asPortrait());
                        } else {
                            mCurrPrintAttributes.setMediaSize(mMediaSizeSpinnerAdapter
                                    .getItem(mediaSizeIndex).value.asLandscape());
                        }
                        someAttributeSelectionChanged = true;
                    }
                }
                mMediaSizeSpinner.setEnabled(true);

                // Color mode.
                final int colorModes = capabilities.getColorModes();

                // If the color modes changed, we update the adapter and the spinner.
                boolean colorModesChanged = false;
                if (Integer.bitCount(colorModes) != mColorModeSpinnerAdapter.getCount()) {
                    colorModesChanged = true;
                } else {
                    int remainingColorModes = colorModes;
                    int adapterIndex = 0;
                    while (remainingColorModes != 0) {
                        final int colorBitOffset = Integer.numberOfTrailingZeros(
                                remainingColorModes);
                        final int colorMode = 1 << colorBitOffset;
                        remainingColorModes &= ~colorMode;
                        if (colorMode != mColorModeSpinnerAdapter.getItem(adapterIndex).value) {
                            colorModesChanged = true;
                            break;
                        }
                        adapterIndex++;
                    }
                }
                if (colorModesChanged) {
                    // Remember the old color mode to try selecting it again.
                    int oldColorModeNewIndex = AdapterView.INVALID_POSITION;
                    final int oldColorMode = mCurrPrintAttributes.getColorMode();

                    // Rebuild the adapter data.
                    mColorModeSpinnerAdapter.clear();
                    String[] colorModeLabels = getResources().getStringArray(
                            R.array.color_mode_labels);
                    int remainingColorModes = colorModes;
                    while (remainingColorModes != 0) {
                        final int colorBitOffset = Integer.numberOfTrailingZeros(
                                remainingColorModes);
                        final int colorMode = 1 << colorBitOffset;
                        if (colorMode == oldColorMode) {
                            // Update the index of the old selection.
                            oldColorModeNewIndex = colorBitOffset;
                        }
                        remainingColorModes &= ~colorMode;
                        mColorModeSpinnerAdapter.add(new SpinnerItem<Integer>(colorMode,
                                colorModeLabels[colorBitOffset]));
                    }
                    mColorModeSpinner.setEnabled(true);
                    if (oldColorModeNewIndex != AdapterView.INVALID_POSITION) {
                        // Select the old color mode - nothing really changed.
                        setColorModeSpinnerSelectionNoCallback(oldColorModeNewIndex);
                    } else {
                        final int selectedColorMode = colorModes & defaultAttributes.getColorMode();
                        final int itemCount = mColorModeSpinnerAdapter.getCount();
                        for (int i = 0; i < itemCount; i++) {
                            SpinnerItem<Integer> item = mColorModeSpinnerAdapter.getItem(i);
                            if (selectedColorMode == item.value) {
                                setColorModeSpinnerSelectionNoCallback(i);
                                mCurrPrintAttributes.setColorMode(selectedColorMode);
                                someAttributeSelectionChanged = true;
                            }
                        }
                    }
                }
                mColorModeSpinner.setEnabled(true);

                // Orientation
                MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
                if (mediaSize.isPortrait()
                        && mOrientationSpinner.getSelectedItemPosition() != 0) {
                    mIgnoreNextOrientationChange = true;
                    mOrientationSpinner.setSelection(0);
                } else if (!mediaSize.isPortrait()
                        && mOrientationSpinner.getSelectedItemPosition() != 1) {
                    mIgnoreNextOrientationChange = true;
                    mOrientationSpinner.setSelection(1);
                }
                mOrientationSpinner.setEnabled(true);

                // Range options
                PrintDocumentInfo info = mDocument.info;
                if (info != null && info.getPageCount() > 0) {
                    if (info.getPageCount() == 1) {
                        mRangeOptionsSpinner.setEnabled(false);
                    } else {
                        mRangeOptionsSpinner.setEnabled(true);
                        if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
                            if (!mPageRangeEditText.isEnabled()) {
                                mPageRangeEditText.setEnabled(true);
                                mPageRangeEditText.setVisibility(View.VISIBLE);
                                mPageRangeTitle.setVisibility(View.VISIBLE);
                                mPageRangeEditText.requestFocus();
                                InputMethodManager imm = (InputMethodManager)
                                        getSystemService(INPUT_METHOD_SERVICE);
                                imm.showSoftInput(mPageRangeEditText, 0);
                            }
                        } else {
                            mPageRangeEditText.setEnabled(false);
                            mPageRangeEditText.setVisibility(View.INVISIBLE);
                            mPageRangeTitle.setVisibility(View.INVISIBLE);
                        }
                    }
                    final int pageCount = mDocument.info.getPageCount();
                    String title = (pageCount != PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
                            ? getString(R.string.label_pages, String.valueOf(pageCount))
                            : getString(R.string.page_count_unknown);
                    mRangeOptionsTitle.setText(title);
                } else {
                    if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
                        mIgnoreNextRangeOptionChange = true;
                        mRangeOptionsSpinner.setSelection(0);
                    }
                    mRangeOptionsSpinner.setEnabled(false);
                    mRangeOptionsTitle.setText(getString(R.string.page_count_unknown));
                    mPageRangeEditText.setEnabled(false);
                    mPageRangeEditText.setVisibility(View.INVISIBLE);
                    mPageRangeTitle.setVisibility(View.INVISIBLE);
                }

                // Advanced print options
                ComponentName serviceName = mCurrentPrinter.getId().getServiceName();
                if (!TextUtils.isEmpty(getAdvancedOptionsActivityName(serviceName))) {
                    mAdvancedPrintOptionsContainer.setVisibility(View.VISIBLE);
                    mAdvancedOptionsButton.setEnabled(true);
                } else {
                    mAdvancedPrintOptionsContainer.setVisibility(View.GONE);
                    mAdvancedOptionsButton.setEnabled(false);
                }

                // Print
                if (mDestinationSpinner.getSelectedItemId()
                        != DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF) {
                    String newText = getString(R.string.print_button);
                    if (!TextUtils.equals(newText, mPrintButton.getText())) {
                        mPrintButton.setText(R.string.print_button);
                    }
                } else {
                    String newText = getString(R.string.save_button);
                    if (!TextUtils.equals(newText, mPrintButton.getText())) {
                        mPrintButton.setText(R.string.save_button);
                    }
                }
                if ((mRangeOptionsSpinner.getSelectedItemPosition() == 1
                            && (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
                        || (mRangeOptionsSpinner.getSelectedItemPosition() == 0
                            && (!mController.hasPerformedLayout() || hasErrors()))) {
                    mPrintButton.setEnabled(false);
                } else {
                    mPrintButton.setEnabled(true);
                }

                // Copies
                if (mDestinationSpinner.getSelectedItemId()
                        != DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF) {
                    mCopiesEditText.setEnabled(true);
                } else {
                    mCopiesEditText.setEnabled(false);
                }
                if (mCopiesEditText.getError() == null
                        && TextUtils.isEmpty(mCopiesEditText.getText())) {
                    mIgnoreNextCopiesChange = true;
                    mCopiesEditText.setText(String.valueOf(MIN_COPIES));
                    mCopiesEditText.requestFocus();
                }

                return someAttributeSelectionChanged;
            }
        }

        private String getAdvancedOptionsActivityName(ComponentName serviceName) {
            PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
            List<PrintServiceInfo> printServices = printManager.getEnabledPrintServices();
            final int printServiceCount = printServices.size();
            for (int i = 0; i < printServiceCount; i ++) {
                PrintServiceInfo printServiceInfo = printServices.get(i);
                ServiceInfo serviceInfo = printServiceInfo.getResolveInfo().serviceInfo;
                if (serviceInfo.name.equals(serviceName.getClassName())
                        && serviceInfo.packageName.equals(serviceName.getPackageName())) {
                    return printServiceInfo.getAdvancedOptionsActivityName();
                }
            }
            return null;
        }

        private void setMediaSizeSpinnerSelectionNoCallback(int position) {
            if (mMediaSizeSpinner.getSelectedItemPosition() != position) {
                mOldMediaSizeSelectionIndex = position;
                mMediaSizeSpinner.setSelection(position);
            }
        }

        private void setColorModeSpinnerSelectionNoCallback(int position) {
            if (mColorModeSpinner.getSelectedItemPosition() != position) {
                mOldColorModeSelectionIndex = position;
                mColorModeSpinner.setSelection(position);
            }
        }

        private void startSelectPrinterActivity() {
            Intent intent = new Intent(PrintJobConfigActivity.this,
                    SelectPrinterActivity.class);
            startActivityForResult(intent, ACTIVITY_REQUEST_SELECT_PRINTER);
        }

        private boolean hasErrors() {
            if (mCopiesEditText.getError() != null) {
                return true;
            }
            return mPageRangeEditText.getVisibility() == View.VISIBLE
                    && mPageRangeEditText.getError() != null;
        }

        private final class SpinnerItem<T> {
            final T value;
            CharSequence label;

            public SpinnerItem(T value, CharSequence label) {
                this.value = value;
                this.label = label;
            }

            public String toString() {
                return label.toString();
            }
        }

        private final class WaitForPrinterCapabilitiesTimeout implements Runnable {
            private static final long GET_CAPABILITIES_TIMEOUT_MILLIS = 10000; // 10sec

            private boolean mIsPosted;

            public void post() {
                if (!mIsPosted) {
                    mDestinationSpinner.postDelayed(this,
                            GET_CAPABILITIES_TIMEOUT_MILLIS);
                    mIsPosted = true;
                }
            }

            public void remove() {
                if (mIsPosted) {
                    mIsPosted = false;
                    mDestinationSpinner.removeCallbacks(this);
                }
            }

            public boolean isPosted() {
                return mIsPosted;
            }

            @Override
            public void run() {
                mIsPosted = false;
                if (mDestinationSpinner.getSelectedItemPosition() >= 0) {
                    View itemView = mDestinationSpinner.getSelectedView();
                    TextView titleView = (TextView) itemView.findViewById(R.id.subtitle);
                    try {
                        PackageInfo packageInfo = getPackageManager().getPackageInfo(
                                mCurrentPrinter.getId().getServiceName().getPackageName(), 0);
                        CharSequence service = packageInfo.applicationInfo.loadLabel(
                                getPackageManager());
                        String subtitle = getString(R.string.printer_unavailable, service.toString());
                        titleView.setText(subtitle);
                    } catch (NameNotFoundException nnfe) {
                        /* ignore */
                    }
                }
            }
        }

        private final class DestinationAdapter extends BaseAdapter
                implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>{
            private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();

            private PrinterInfo mFakePdfPrinter;

            public DestinationAdapter() {
                getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this);
            }

            public int getPrinterIndex(PrinterId printerId) {
                for (int i = 0; i < getCount(); i++) {
                    PrinterInfo printer = (PrinterInfo) getItem(i);
                    if (printer != null && printer.getId().equals(printerId)) {
                        return i;
                    }
                }
                return AdapterView.INVALID_POSITION;
            }

            public void ensurePrinterInVisibleAdapterPosition(PrinterId printerId) {
                final int printerCount = mPrinters.size();
                for (int i = 0; i < printerCount; i++) {
                    PrinterInfo printer = (PrinterInfo) mPrinters.get(i);
                    if (printer.getId().equals(printerId)) {
                        // If already in the list - do nothing.
                        if (i < getCount() - 2) {
                            return;
                        }
                        // Else replace the last one (two items are not printers).
                        final int lastPrinterIndex = getCount() - 3;
                        mPrinters.set(i, mPrinters.get(lastPrinterIndex));
                        mPrinters.set(lastPrinterIndex, printer);
                        notifyDataSetChanged();
                        return;
                    }
                }
            }

            @Override
            public int getCount() {
                if (mFakePdfPrinter == null) {
                    return 0;
                }
                return Math.min(mPrinters.size() + 2, DEST_ADAPTER_MAX_ITEM_COUNT);
            }

            @Override
            public boolean isEnabled(int position) {
                Object item = getItem(position);
                if (item instanceof PrinterInfo) {
                    PrinterInfo printer = (PrinterInfo) item;
                    return printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
                }
                return true;
            }

            @Override
            public Object getItem(int position) {
                if (mPrinters.isEmpty()) {
                    if (position == 0 && mFakePdfPrinter != null) {
                        return mFakePdfPrinter;
                    }
                } else {
                    if (position < 1) {
                        return mPrinters.get(position);
                    }
                    if (position == 1 && mFakePdfPrinter != null) {
                        return mFakePdfPrinter;
                    }
                    if (position < getCount() - 1) {
                        return mPrinters.get(position - 1);
                    }
                }
                return null;
            }

            @Override
            public long getItemId(int position) {
                if (mPrinters.isEmpty()) {
                    if (mFakePdfPrinter != null) {
                        if (position == 0) {
                            return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
                        } else if (position == 1) {
                            return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
                        }
                    }
                } else {
                    if (position == 1 && mFakePdfPrinter != null) {
                        return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
                    }
                    if (position == getCount() - 1) {
                        return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
                    }
                }
                return position;
            }

            @Override
            public View getDropDownView(int position, View convertView,
                    ViewGroup parent) {
                View view = getView(position, convertView, parent);
                view.setEnabled(isEnabled(position));
                return view;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if (convertView == null) {
                    convertView = getLayoutInflater().inflate(
                            R.layout.printer_dropdown_item, parent, false);
                }

                CharSequence title = null;
                CharSequence subtitle = null;
                Drawable icon = null;

                if (mPrinters.isEmpty()) {
                    if (position == 0 && mFakePdfPrinter != null) {
                        PrinterInfo printer = (PrinterInfo) getItem(position);
                        title = printer.getName();
                    } else if (position == 1) {
                        title = getString(R.string.all_printers);
                    }
                } else {
                    if (position == 1 && mFakePdfPrinter != null) {
                        PrinterInfo printer = (PrinterInfo) getItem(position);
                        title = printer.getName();
                    } else if (position == getCount() - 1) {
                        title = getString(R.string.all_printers);
                    } else {
                        PrinterInfo printer = (PrinterInfo) getItem(position);
                        title = printer.getName();
                        try {
                            PackageInfo packageInfo = getPackageManager().getPackageInfo(
                                    printer.getId().getServiceName().getPackageName(), 0);
                            subtitle = packageInfo.applicationInfo.loadLabel(getPackageManager());
                            icon = packageInfo.applicationInfo.loadIcon(getPackageManager());
                        } catch (NameNotFoundException nnfe) {
                            /* ignore */
                        }
                    }
                }

                TextView titleView = (TextView) convertView.findViewById(R.id.title);
                titleView.setText(title);

                TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
                if (!TextUtils.isEmpty(subtitle)) {
                    subtitleView.setText(subtitle);
                    subtitleView.setVisibility(View.VISIBLE);
                } else {
                    subtitleView.setText(null);
                    subtitleView.setVisibility(View.GONE);
                }

                ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
                if (icon != null) {
                    iconView.setImageDrawable(icon);
                    iconView.setVisibility(View.VISIBLE);
                } else {
                    iconView.setVisibility(View.INVISIBLE);
                }

                return convertView;
            }

            @Override
            public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
                if (id == LOADER_ID_PRINTERS_LOADER) {
                    return new FusedPrintersProvider(PrintJobConfigActivity.this);
                }
                return null;
            }

            @Override
            public void onLoadFinished(Loader<List<PrinterInfo>> loader,
                    List<PrinterInfo> printers) {
                // If this is the first load, create the fake PDF printer.
                // We do this to avoid flicker where the PDF printer is the
                // only one and as soon as the loader loads the favorites
                // it gets switched. Not a great user experience.
                if (mFakePdfPrinter == null) {
                    mCurrentPrinter = mFakePdfPrinter = createFakePdfPrinter();
                    updatePrintAttributes(mCurrentPrinter.getCapabilities());
                    updateUi();
                }

                // We rearrange the printers if the user selects a printer
                // not shown in the initial short list. Therefore, we have
                // to keep the printer order.

                // No old printers - do not bother keeping their position.
                if (mPrinters.isEmpty()) {
                    mPrinters.addAll(printers);
                    mEditor.ensureCurrentPrinterSelected();
                    notifyDataSetChanged();
                    return;
                }

                // Add the new printers to a map.
                ArrayMap<PrinterId, PrinterInfo> newPrintersMap =
                        new ArrayMap<PrinterId, PrinterInfo>();
                final int printerCount = printers.size();
                for (int i = 0; i < printerCount; i++) {
                    PrinterInfo printer = printers.get(i);
                    newPrintersMap.put(printer.getId(), printer);
                }

                List<PrinterInfo> newPrinters = new ArrayList<PrinterInfo>();

                // Update printers we already have.
                final int oldPrinterCount = mPrinters.size();
                for (int i = 0; i < oldPrinterCount; i++) {
                    PrinterId oldPrinterId = mPrinters.get(i).getId();
                    PrinterInfo updatedPrinter = newPrintersMap.remove(oldPrinterId);
                    if (updatedPrinter != null) {
                        newPrinters.add(updatedPrinter);
                    }
                }

                // Add the rest of the new printers, i.e. what is left.
                newPrinters.addAll(newPrintersMap.values());

                mPrinters.clear();
                mPrinters.addAll(newPrinters);

                mEditor.ensureCurrentPrinterSelected();
                notifyDataSetChanged();
            }

            @Override
            public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
                mPrinters.clear();
                notifyDataSetInvalidated();
            }


            private PrinterInfo createFakePdfPrinter() {
                MediaSize defaultMediaSize = MediaSizeUtils.getDefault(PrintJobConfigActivity.this);

                PrinterId printerId = new PrinterId(getComponentName(), "PDF printer");

                PrinterCapabilitiesInfo.Builder builder =
                        new PrinterCapabilitiesInfo.Builder(printerId);

                String[] mediaSizeIds = getResources().getStringArray(
                        R.array.pdf_printer_media_sizes);
                final int mediaSizeIdCount = mediaSizeIds.length;
                for (int i = 0; i < mediaSizeIdCount; i++) {
                    String id = mediaSizeIds[i];
                    MediaSize mediaSize = MediaSize.getStandardMediaSizeById(id);
                    builder.addMediaSize(mediaSize, mediaSize.equals(defaultMediaSize));
                }

                builder.addResolution(new Resolution("PDF resolution", "PDF resolution",
                            300, 300), true);
                builder.setColorModes(PrintAttributes.COLOR_MODE_COLOR
                        | PrintAttributes.COLOR_MODE_MONOCHROME,
                        PrintAttributes.COLOR_MODE_COLOR);

                return new PrinterInfo.Builder(printerId, getString(R.string.save_as_pdf),
                        PrinterInfo.STATUS_IDLE)
                    .setCapabilities(builder.build())
                    .build();
            }
        }
    }

    /**
     * An instance of this class class is intended to be the first focusable
     * in a layout to which the system automatically gives focus. It performs
     * some voodoo to avoid the first tap on it to start an edit mode, rather
     * to bring up the IME, i.e. to get the behavior as if the view was not
     * focused.
     */
    public static final class CustomEditText extends EditText {
        private boolean mClickedBeforeFocus;
        private CharSequence mError;

        public CustomEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @Override
        public boolean performClick() {
            super.performClick();
            if (isFocused() && !mClickedBeforeFocus) {
                clearFocus();
                requestFocus();
            }
            mClickedBeforeFocus = true;
            return true;
        }

        @Override
        public CharSequence getError() {
            return mError;
        }

        @Override
        public void setError(CharSequence error, Drawable icon) {
            setCompoundDrawables(null, null, icon, null);
            mError = error;
        }

        protected void onFocusChanged(boolean gainFocus, int direction,
                Rect previouslyFocusedRect) {
            if (!gainFocus) {
                mClickedBeforeFocus = false;
            }
            super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
        }
    }

    private static final class Document {
        public PrintDocumentInfo info;
        public PageRange[] pages;
    }

    private static final class PageRangeUtils {

        private static final Comparator<PageRange> sComparator = new Comparator<PageRange>() {
            @Override
            public int compare(PageRange lhs, PageRange rhs) {
                return lhs.getStart() - rhs.getStart();
            }
        };

        private PageRangeUtils() {
            throw new UnsupportedOperationException();
        }

        public static boolean contains(PageRange[] ourRanges, PageRange[] otherRanges) {
            if (ourRanges == null || otherRanges == null) {
                return false;
            }

            if (ourRanges.length == 1
                    && PageRange.ALL_PAGES.equals(ourRanges[0])) {
                return true;
            }

            ourRanges = normalize(ourRanges);
            otherRanges = normalize(otherRanges);

            // Note that the code below relies on the ranges being normalized
            // which is they contain monotonically increasing non-intersecting
            // subranges whose start is less that or equal to the end.
            int otherRangeIdx = 0;
            final int ourRangeCount = ourRanges.length;
            final int otherRangeCount = otherRanges.length;
            for (int ourRangeIdx = 0; ourRangeIdx < ourRangeCount; ourRangeIdx++) {
                PageRange ourRange = ourRanges[ourRangeIdx];
                for (; otherRangeIdx < otherRangeCount; otherRangeIdx++) {
                    PageRange otherRange = otherRanges[otherRangeIdx];
                    if (otherRange.getStart() > ourRange.getEnd()) {
                        break;
                    }
                    if (otherRange.getStart() < ourRange.getStart()
                            || otherRange.getEnd() > ourRange.getEnd()) {
                        return false;
                    }
                }
            }
            if (otherRangeIdx < otherRangeCount) {
                return false;
            }
            return true;
        }

        public static PageRange[] normalize(PageRange[] pageRanges) {
            if (pageRanges == null) {
                return null;
            }
            final int oldRangeCount = pageRanges.length;
            if (oldRangeCount <= 1) {
                return pageRanges;
            }
            Arrays.sort(pageRanges, sComparator);
            int newRangeCount = 1;
            for (int i = 0; i < oldRangeCount - 1; i++) {
                newRangeCount++;
                PageRange currentRange = pageRanges[i];
                PageRange nextRange = pageRanges[i + 1];
                if (currentRange.getEnd() + 1 >= nextRange.getStart()) {
                    newRangeCount--;
                    pageRanges[i] = null;
                    pageRanges[i + 1] = new PageRange(currentRange.getStart(),
                            Math.max(currentRange.getEnd(), nextRange.getEnd()));
                }
            }
            if (newRangeCount == oldRangeCount) {
                return pageRanges;
            }
            return Arrays.copyOfRange(pageRanges, oldRangeCount - newRangeCount,
                    oldRangeCount);
        }

        public static void offset(PageRange[] pageRanges, int offset) {
            if (offset == 0) {
                return;
            }
            final int pageRangeCount = pageRanges.length;
            for (int i = 0; i < pageRangeCount; i++) {
                final int start = pageRanges[i].getStart() + offset;
                final int end = pageRanges[i].getEnd() + offset;
                pageRanges[i] = new PageRange(start, end);
            }
        }
    }

    private static final class AutoCancellingAnimator
            implements OnAttachStateChangeListener, Runnable {

        private ViewPropertyAnimator mAnimator;

        private boolean mCancelled;
        private Runnable mEndCallback;

        public static AutoCancellingAnimator animate(View view) {
            ViewPropertyAnimator animator = view.animate();
            AutoCancellingAnimator cancellingWrapper =
                    new AutoCancellingAnimator(animator);
            view.addOnAttachStateChangeListener(cancellingWrapper);
            return cancellingWrapper;
        }

        private AutoCancellingAnimator(ViewPropertyAnimator animator) {
            mAnimator = animator;
        }

        public AutoCancellingAnimator alpha(float alpha) {
            mAnimator = mAnimator.alpha(alpha);
            return this;
        }

        public void cancel() {
            mAnimator.cancel();
        }

        public AutoCancellingAnimator withLayer() {
            mAnimator = mAnimator.withLayer();
            return this;
        }

        public AutoCancellingAnimator withEndAction(Runnable callback) {
            mEndCallback = callback;
            mAnimator = mAnimator.withEndAction(this);
            return this;
        }

        public AutoCancellingAnimator scaleY(float scale) {
            mAnimator = mAnimator.scaleY(scale);
            return this;
        }

        @Override
        public void onViewAttachedToWindow(View v) {
            /* do nothing */
        }

        @Override
        public void onViewDetachedFromWindow(View v) {
            cancel();
        }

        @Override
        public void run() {
            if (!mCancelled) {
                mEndCallback.run();
            }
        }
    }

    private static final class PrintSpoolerProvider implements ServiceConnection {
        private final Context mContext;
        private final Runnable mCallback;

        private PrintSpoolerService mSpooler;

        public PrintSpoolerProvider(Context context, Runnable callback) {
            mContext = context;
            mCallback = callback;
            Intent intent = new Intent(mContext, PrintSpoolerService.class);
            mContext.bindService(intent, this, 0);
        }

        public PrintSpoolerService getSpooler() {
            return mSpooler;
        }

        public void destroy() {
            if (mSpooler != null) {
                mContext.unbindService(this);
            }
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mSpooler = ((PrintSpoolerService.PrintSpooler) service).getService();
            if (mSpooler != null) {
                mCallback.run();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            /* do noting - we are in the same process */
        }
    }

    private static final class PrintDocumentAdapterObserver
            extends IPrintDocumentAdapterObserver.Stub {
        private final WeakReference<PrintJobConfigActivity> mWeakActvity;

        public PrintDocumentAdapterObserver(PrintJobConfigActivity activity) {
            mWeakActvity = new WeakReference<PrintJobConfigActivity>(activity);
        }

        @Override
        public void onDestroy() {
            final PrintJobConfigActivity activity = mWeakActvity.get();
            if (activity != null) {
                activity.mController.mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (activity.mController != null) {
                            activity.mController.cancel();
                        }
                        if (activity.mEditor != null) {
                            activity.mEditor.cancel();
                        }
                        activity.finish();
                    }
                });
            }
        }
    }
}
