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

import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;

/**
 * Base class that provides the content of a document to be printed.
 *
 * <h3>Lifecycle</h3>
 * <p>
 * <ul>
 * <li>
 * Initially, you will receive a call to {@link #onStart()}. This callback
 * can be used to allocate resources.
 * </li>
 * <li>
 * Next, you will get one or more calls to {@link #onLayout(PrintAttributes,
 * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} to
 * inform you that the print attributes (page size, density, etc) changed
 * giving you an opportunity to layout the content to match the new constraints.
 * </li>
 * <li>
 * After every call to {@link #onLayout(PrintAttributes, PrintAttributes,
 * CancellationSignal, LayoutResultCallback, Bundle)}, you <strong>may</strong> get
 * a call to {@link #onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal,
 * WriteResultCallback)} asking you to write a PDF file with the content for
 * specific pages.
 * </li>
 * <li>
 * Finally, you will receive a call to {@link #onFinish()}. You can use this
 * callback to release resources allocated in {@link #onStart()}.
 * </li>
 * </ul>
 * <p>
 * The {@link #onStart()} callback is always the first call you will receive and
 * is useful for doing one time setup or resource allocation before printing. You
 * will not receive a subsequent call here.
 * </p>
 * <p>
 * The {@link #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
 * LayoutResultCallback, Bundle)} callback requires that you layout the content
 * based on the current {@link PrintAttributes}. The execution of this method is
 * not considered completed until you invoke one of the methods on the passed in
 * callback instance. Hence, you will not receive a subsequent call to any other
 * method of this class until the execution of this method is complete by invoking
 * one of the callback methods.
 * </p>
 * <p>
 * The {@link #onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal,
 * WriteResultCallback)} requires that you render and write the content of some
 * pages to the provided destination. The execution of this method is not
 * considered complete until you invoke one of the methods on the passed in
 * callback instance. Hence, you will not receive a subsequent call to any other
 * method of this class until the execution of this method is complete by invoking
 * one of the callback methods. You will never receive a sequence of one or more
 * calls to this method without a previous call to {@link #onLayout(PrintAttributes,
 * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)}.
 * </p>
 * <p>
 * The {@link #onFinish()} callback is always the last call you will receive and
 * is useful for doing one time cleanup or resource deallocation after printing.
 * You will not receive a subsequent call here.
 * </p>
 * </p>
 * <h3>Implementation</h3>
 * <p>
 * The APIs defined in this class are designed to enable doing part or all
 * of the work on an arbitrary thread. For example, if the printed content
 * does not depend on the UI state, i.e. on what is shown on the screen, then
 * you can offload the entire work on a dedicated thread, thus making your
 * application interactive while the print work is being performed. Note that
 * while your activity is covered by the system print UI and a user cannot
 * interact with it, doing the printing work on the main application thread
 * may affect the performance of your other application components as they
 * are also executed on that thread.
 * </p>
 * <p>
 * You can also do work on different threads, for example if you print UI
 * content, you can handle {@link #onStart()} and {@link #onLayout(PrintAttributes,
 * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} on
 * the UI thread (assuming onStart initializes resources needed for layout).
 * This will ensure that the UI does not change while you are laying out the
 * printed content. Then you can handle {@link #onWrite(PageRange[], ParcelFileDescriptor,
 * CancellationSignal, WriteResultCallback)} and {@link #onFinish()} on another
 * thread. This will ensure that the main thread is busy for a minimal amount of
 * time. Also this assumes that you will generate the printed content in
 * {@link #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
 * LayoutResultCallback, Bundle)} which is not mandatory. If you use multiple
 * threads, you are responsible for proper synchronization.
 * </p>
 */
public abstract class PrintDocumentAdapter {

    /**
     * Extra: mapped to a boolean value that is <code>true</code> if
     * the current layout is for a print preview, <code>false</code> otherwise.
     * This extra is provided in the {@link Bundle} argument of the {@link
     * #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
     * LayoutResultCallback, Bundle)} callback.
     *
     * @see #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
     * LayoutResultCallback, Bundle)
     */
    public static final String EXTRA_PRINT_PREVIEW = "EXTRA_PRINT_PREVIEW";

    /**
     * Called when printing starts. You can use this callback to allocate
     * resources. This method is invoked on the main thread.
     */
    public void onStart() {
        /* do nothing - stub */
    }

    /**
     * Called when the print attributes (page size, density, etc) changed
     * giving you a chance to layout the content such that it matches the
     * new constraints. This method is invoked on the main thread.
     * <p>
     * After you are done laying out, you <strong>must</strong> invoke: {@link
     * LayoutResultCallback#onLayoutFinished(PrintDocumentInfo, boolean)} with
     * the last argument <code>true</code> or <code>false</code> depending on
     * whether the layout changed the content or not, respectively; or {@link
     * LayoutResultCallback#onLayoutFailed(CharSequence)}, if an error occurred;
     * or {@link LayoutResultCallback#onLayoutCancelled()} if layout was
     * cancelled in a response to a cancellation request via the passed in
     * {@link CancellationSignal}. Note that you <strong>must</strong> call one of
     * the methods of the given callback for this method to be considered complete
     * which is you will not receive any calls to this adapter until the current
     * layout operation is complete by invoking a method on the callback instance.
     * The callback methods can be invoked from an arbitrary thread.
     * </p>
     * <p>
     * One of the arguments passed to this method is a {@link CancellationSignal}
     * which is used to propagate requests from the system to your application for
     * canceling the current layout operation. For example, a cancellation may be
     * requested if the user changes a print option that may affect layout while
     * you are performing a layout operation. In such a case the system will make
     * an attempt to cancel the current layout as another one will have to be performed.
     * Typically, you should register a cancellation callback in the cancellation
     * signal. The cancellation callback <strong>will not</strong> be made on the
     * main thread and can be registered as follows:
     * </p>
     * <pre>
     * cancellationSignal.setOnCancelListener(new OnCancelListener() {
     *     &#064;Override
     *     public void onCancel() {
     *         // Cancel layout
     *     }
     * });
     * </pre>
     * <p>
     * <strong>Note:</strong> If the content is large and a layout will be
     * performed, it is a good practice to schedule the work on a dedicated
     * thread and register an observer in the provided {@link
     * CancellationSignal} upon invocation of which you should stop the
     * layout.
     * </p>
     *
     * @param oldAttributes The old print attributes.
     * @param newAttributes The new print attributes.
     * @param cancellationSignal Signal for observing cancel layout requests.
     * @param callback Callback to inform the system for the layout result.
     * @param extras Additional information about how to layout the content.
     *
     * @see LayoutResultCallback
     * @see CancellationSignal
     * @see #EXTRA_PRINT_PREVIEW
     */
    public abstract void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
            CancellationSignal cancellationSignal, LayoutResultCallback callback,
            Bundle extras);

    /**
     * Called when specific pages of the content should be written in the
     * form of a PDF file to the given file descriptor. This method is invoked
     * on the main thread.
     *<p>
     * After you are done writing, you should close the file descriptor and
     * invoke {@link WriteResultCallback#onWriteFinished(PageRange[])}, if writing
     * completed successfully; or {@link WriteResultCallback#onWriteFailed(
     * CharSequence)}, if an error occurred; or {@link WriteResultCallback#onWriteCancelled()},
     * if writing was cancelled in a response to a cancellation request via the passed
     * in {@link CancellationSignal}. Note that you <strong>must</strong> call one of
     * the methods of the given callback for this method to be considered complete which
     * is you will not receive any calls to this adapter until the current write
     * operation is complete by invoking a method on the callback instance. The callback
     * methods can be invoked from an arbitrary thread.
     * </p>
     * <p>
     * One of the arguments passed to this method is a {@link CancellationSignal}
     * which is used to propagate requests from the system to your application for
     * canceling the current write operation. For example, a cancellation may be
     * requested if the user changes a print option that may affect layout while
     * you are performing a write operation. In such a case the system will make
     * an attempt to cancel the current write as a layout will have to be performed
     * which then may be followed by a write. Typically, you should register a
     * cancellation callback in the cancellation signal. The cancellation callback
     * <strong>will not</strong> be made on the main thread and can be registered
     * as follows:
     * </p>
     * <pre>
     * cancellationSignal.setOnCancelListener(new OnCancelListener() {
     *     &#064;Override
     *     public void onCancel() {
     *         // Cancel write
     *     }
     * });
     * </pre>
     * <p>
     * <strong>Note:</strong> If the printed content is large, it is a good
     * practice to schedule writing it on a dedicated thread and register an
     * observer in the provided {@link CancellationSignal} upon invocation of
     * which you should stop writing.
     * </p>
     *
     * @param pages The pages whose content to print - non-overlapping in ascending order.
     * @param destination The destination file descriptor to which to write.
     * @param cancellationSignal Signal for observing cancel writing requests.
     * @param callback Callback to inform the system for the write result.
     *
     * @see WriteResultCallback
     * @see CancellationSignal
     */
    public abstract void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
            CancellationSignal cancellationSignal, WriteResultCallback callback);

    /**
     * Called when printing finishes. You can use this callback to release
     * resources acquired in {@link #onStart()}. This method is invoked on
     * the main thread.
     */
    public void onFinish() {
        /* do nothing - stub */
    }

    /**
     * Base class for implementing a callback for the result of {@link
     * PrintDocumentAdapter#onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal,
     * WriteResultCallback)}.
     */
    public static abstract class WriteResultCallback {

        /**
         * @hide
         */
        @UnsupportedAppUsage
        public WriteResultCallback() {
            /* do nothing - hide constructor */
        }

        /**
         * Notifies that all the data was written.
         *
         * @param pages The pages that were written. Cannot be <code>null</code>
         *        or empty. <br />
         *        Returning {@link PageRange#ALL_PAGES} indicates that all pages that were
         *        requested as the {@code pages} parameter in {@link #onWrite} were written.
         */
        public void onWriteFinished(PageRange[] pages) {
            /* do nothing - stub */
        }

        /**
         * Notifies that an error occurred while writing the data.
         *
         * @param error The <strong>localized</strong> error message.
         * shown to the user. May be <code>null</code> if error is unknown.
         */
        public void onWriteFailed(CharSequence error) {
            /* do nothing - stub */
        }

        /**
         * Notifies that write was cancelled as a result of a cancellation request.
         */
        public void onWriteCancelled() {
            /* do nothing - stub */
        }
    }

    /**
     * Base class for implementing a callback for the result of {@link
     * PrintDocumentAdapter#onLayout(PrintAttributes, PrintAttributes,
     * CancellationSignal, LayoutResultCallback, Bundle)}.
     */
    public static abstract class LayoutResultCallback {

        /**
         * @hide
         */
        @UnsupportedAppUsage
        public LayoutResultCallback() {
            /* do nothing - hide constructor */
        }

        /**
         * Notifies that the layout finished and whether the content changed.
         *
         * @param info An info object describing the document. Cannot be <code>null</code>.
         * @param changed Whether the layout changed.
         *
         * @see PrintDocumentInfo
         */
        public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
            /* do nothing - stub */
        }

        /**
         * Notifies that an error occurred while laying out the document.
         *
         * @param error The <strong>localized</strong> error message.
         * shown to the user. May be <code>null</code> if error is unknown.
         */
        public void onLayoutFailed(CharSequence error) {
            /* do nothing - stub */
        }

        /**
         * Notifies that layout was cancelled as a result of a cancellation request.
         */
        public void onLayoutCancelled() {
            /* do nothing - stub */
        }
    }
}
