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

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;

import dalvik.system.CloseGuard;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * This class enables generating a PDF document from native Android content. You
 * create a new document and then for every page you want to add you start a page,
 * write content to the page, and finish the page. After you are done with all
 * pages, you write the document to an output stream and close the document.
 * After a document is closed you should not use it anymore. Note that pages are
 * created one by one, i.e. you can have only a single page to which you are
 * writing at any given time. This class is not thread safe.
 * </p>
 * <p>
 * A typical use of the APIs looks like this:
 * </p>
 * <pre>
 * // create a new document
 * PdfDocument document = new PdfDocument();
 *
 * // crate a page description
 * PageInfo pageInfo = new PageInfo.Builder(new Rect(0, 0, 100, 100), 1).create();
 *
 * // start a page
 * Page page = document.startPage(pageInfo);
 *
 * // draw something on the page
 * View content = getContentView();
 * content.draw(page.getCanvas());
 *
 * // finish the page
 * document.finishPage(page);
 * . . .
 * // add more pages
 * . . .
 * // write the document content
 * document.writeTo(getOutputStream());
 *
 * // close the document
 * document.close();
 * </pre>
 */
public class PdfDocument {

    // TODO: We need a constructor that will take an OutputStream to
    // support online data serialization as opposed to the current
    // on demand one. The current approach is fine until Skia starts
    // to support online PDF generation at which point we need to
    // handle this.

    private final byte[] mChunk = new byte[4096];

    private final CloseGuard mCloseGuard = CloseGuard.get();

    private final List<PageInfo> mPages = new ArrayList<PageInfo>();

    private long mNativeDocument;

    private Page mCurrentPage;

    /**
     * Creates a new instance.
     */
    public PdfDocument() {
        mNativeDocument = nativeCreateDocument();
        mCloseGuard.open("close");
    }

    /**
     * Starts a page using the provided {@link PageInfo}. After the page
     * is created you can draw arbitrary content on the page's canvas which
     * you can get by calling {@link Page#getCanvas()}. After you are done
     * drawing the content you should finish the page by calling
     * {@link #finishPage(Page)}. After the page is finished you should
     * no longer access the page or its canvas.
     * <p>
     * <strong>Note:</strong> Do not call this method after {@link #close()}.
     * Also do not call this method if the last page returned by this method
     * is not finished by calling {@link #finishPage(Page)}.
     * </p>
     *
     * @param pageInfo The page info. Cannot be null.
     * @return A blank page.
     *
     * @see #finishPage(Page)
     */
    public Page startPage(PageInfo pageInfo) {
        throwIfClosed();
        throwIfCurrentPageNotFinished();
        if (pageInfo == null) {
            throw new IllegalArgumentException("page cannot be null");
        }
        Canvas canvas = new PdfCanvas(nativeStartPage(mNativeDocument, pageInfo.mPageWidth,
                pageInfo.mPageHeight, pageInfo.mContentRect.left, pageInfo.mContentRect.top,
                pageInfo.mContentRect.right, pageInfo.mContentRect.bottom));
        mCurrentPage = new Page(canvas, pageInfo);
        return mCurrentPage;
    }

    /**
     * Finishes a started page. You should always finish the last started page.
     * <p>
     * <strong>Note:</strong> Do not call this method after {@link #close()}.
     * You should not finish the same page more than once.
     * </p>
     *
     * @param page The page. Cannot be null.
     *
     * @see #startPage(PageInfo)
     */
    public void finishPage(Page page) {
        throwIfClosed();
        if (page == null) {
            throw new IllegalArgumentException("page cannot be null");
        }
        if (page != mCurrentPage) {
            throw new IllegalStateException("invalid page");
        }
        if (page.isFinished()) {
            throw new IllegalStateException("page already finished");
        }
        mPages.add(page.getInfo());
        mCurrentPage = null;
        nativeFinishPage(mNativeDocument);
        page.finish();
    }

    /**
     * Writes the document to an output stream. You can call this method
     * multiple times.
     * <p>
     * <strong>Note:</strong> Do not call this method after {@link #close()}.
     * Also do not call this method if a page returned by {@link #startPage(
     * PageInfo)} is not finished by calling {@link #finishPage(Page)}.
     * </p>
     *
     * @param out The output stream. Cannot be null.
     *
     * @throws IOException If an error occurs while writing.
     */
    public void writeTo(OutputStream out) throws IOException {
        throwIfClosed();
        throwIfCurrentPageNotFinished();
        if (out == null) {
            throw new IllegalArgumentException("out cannot be null!");
        }
        nativeWriteTo(mNativeDocument, out, mChunk);
    }

    /**
     * Gets the pages of the document.
     *
     * @return The pages or an empty list.
     */
    public List<PageInfo> getPages() {
        return Collections.unmodifiableList(mPages);
    }

    /**
     * Closes this document. This method should be called after you
     * are done working with the document. After this call the document
     * is considered closed and none of its methods should be called.
     * <p>
     * <strong>Note:</strong> Do not call this method if the page
     * returned by {@link #startPage(PageInfo)} is not finished by
     * calling {@link #finishPage(Page)}.
     * </p>
     */
    public void close() {
        throwIfCurrentPageNotFinished();
        dispose();
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            mCloseGuard.warnIfOpen();
            dispose();
        } finally {
            super.finalize();
        }
    }

    private void dispose() {
        if (mNativeDocument != 0) {
            nativeClose(mNativeDocument);
            mCloseGuard.close();
            mNativeDocument = 0;
        }
    }

    /**
     * Throws an exception if the document is already closed.
     */
    private void throwIfClosed() {
        if (mNativeDocument == 0) {
            throw new IllegalStateException("document is closed!");
        }
    }

    /**
     * Throws an exception if the last started page is not finished.
     */
    private void throwIfCurrentPageNotFinished() {
        if (mCurrentPage != null) {
            throw new IllegalStateException("Current page not finished!");
        }
    }

    private native long nativeCreateDocument();

    private native void nativeClose(long nativeDocument);

    private native void nativeFinishPage(long nativeDocument);

    private native void nativeWriteTo(long nativeDocument, OutputStream out, byte[] chunk);

    private static native long nativeStartPage(long nativeDocument, int pageWidth, int pageHeight,
            int contentLeft, int contentTop, int contentRight, int contentBottom);

    private final class PdfCanvas extends Canvas {

        public PdfCanvas(long nativeCanvas) {
            super(nativeCanvas);
        }

        @Override
        public void setBitmap(Bitmap bitmap) {
            throw new UnsupportedOperationException();
        }
    }

    /**
     * This class represents meta-data that describes a PDF {@link Page}.
     */
    public static final class PageInfo {
        private int mPageWidth;
        private int mPageHeight;
        private Rect mContentRect;
        private int mPageNumber;

        /**
         * Creates a new instance.
         */
        private PageInfo() {
            /* do nothing */
        }

        /**
         * Gets the page width in PostScript points (1/72th of an inch).
         *
         * @return The page width.
         */
        public int getPageWidth() {
            return mPageWidth;
        }

        /**
         * Gets the page height in PostScript points (1/72th of an inch).
         *
         * @return The page height.
         */
        public int getPageHeight() {
            return mPageHeight;
        }

        /**
         * Get the content rectangle in PostScript points (1/72th of an inch).
         * This is the area that contains the page content and is relative to
         * the page top left.
         *
         * @return The content rectangle.
         */
        public Rect getContentRect() {
            return mContentRect;
        }

        /**
         * Gets the page number.
         *
         * @return The page number.
         */
        public int getPageNumber() {
            return mPageNumber;
        }

        /**
         * Builder for creating a {@link PageInfo}.
         */
        public static final class Builder {
            private final PageInfo mPageInfo = new PageInfo();

            /**
             * Creates a new builder with the mandatory page info attributes.
             *
             * @param pageWidth The page width in PostScript (1/72th of an inch).
             * @param pageHeight The page height in PostScript (1/72th of an inch).
             * @param pageNumber The page number.
             */
            public Builder(int pageWidth, int pageHeight, int pageNumber) {
                if (pageWidth <= 0) {
                    throw new IllegalArgumentException("page width must be positive");
                }
                if (pageHeight <= 0) {
                    throw new IllegalArgumentException("page width must be positive");
                }
                if (pageNumber < 0) {
                    throw new IllegalArgumentException("pageNumber must be non negative");
                }
                mPageInfo.mPageWidth = pageWidth;
                mPageInfo.mPageHeight = pageHeight;
                mPageInfo.mPageNumber = pageNumber;
            }

            /**
             * Sets the content rectangle in PostScript point (1/72th of an inch).
             * This is the area that contains the page content and is relative to
             * the page top left.
             *
             * @param contentRect The content rectangle. Must fit in the page.
             */
            public Builder setContentRect(Rect contentRect) {
                if (contentRect != null && (contentRect.left < 0
                        || contentRect.top < 0
                        || contentRect.right > mPageInfo.mPageWidth
                        || contentRect.bottom > mPageInfo.mPageHeight)) {
                    throw new IllegalArgumentException("contentRect does not fit the page");
                }
                mPageInfo.mContentRect = contentRect;
                return this;
            }

            /**
             * Creates a new {@link PageInfo}.
             *
             * @return The new instance.
             */
            public PageInfo create() {
                if (mPageInfo.mContentRect == null) {
                    mPageInfo.mContentRect = new Rect(0, 0,
                            mPageInfo.mPageWidth, mPageInfo.mPageHeight);
                }
                return mPageInfo;
            }
        }
    }

    /**
     * This class represents a PDF document page. It has associated
     * a canvas on which you can draw content and is acquired by a
     * call to {@link #getCanvas()}. It also has associated a
     * {@link PageInfo} instance that describes its attributes. Also
     * a page has 
     */
    public static final class Page {
        private final PageInfo mPageInfo;
        private Canvas mCanvas;

        /**
         * Creates a new instance.
         *
         * @param canvas The canvas of the page.
         * @param pageInfo The info with meta-data.
         */
        private Page(Canvas canvas, PageInfo pageInfo) {
            mCanvas = canvas;
            mPageInfo = pageInfo;
        }

        /**
         * Gets the {@link Canvas} of the page.
         *
         * <p>
         * <strong>Note: </strong> There are some draw operations that are not yet
         * supported by the canvas returned by this method. More specifically:
         * <ul>
         * <li>Inverse path clipping performed via {@link Canvas#clipPath(android.graphics.Path,
         *     android.graphics.Region.Op) Canvas.clipPath(android.graphics.Path,
         *     android.graphics.Region.Op)} for {@link
         *     android.graphics.Region.Op#REVERSE_DIFFERENCE
         *     Region.Op#REVERSE_DIFFERENCE} operations.</li>
         * <li>{@link Canvas#drawVertices(android.graphics.Canvas.VertexMode, int,
         *     float[], int, float[], int, int[], int, short[], int, int,
         *     android.graphics.Paint) Canvas.drawVertices(
         *     android.graphics.Canvas.VertexMode, int, float[], int, float[],
         *     int, int[], int, short[], int, int, android.graphics.Paint)}</li>
         * <li>Color filters set via {@link Paint#setColorFilter(
         *     android.graphics.ColorFilter)}</li>
         * <li>Mask filters set via {@link Paint#setMaskFilter(
         *     android.graphics.MaskFilter)}</li>
         * <li>Some XFER modes such as
         *     {@link android.graphics.PorterDuff.Mode#SRC_ATOP PorterDuff.Mode SRC},
         *     {@link android.graphics.PorterDuff.Mode#DST_ATOP PorterDuff.DST_ATOP},
         *     {@link android.graphics.PorterDuff.Mode#XOR PorterDuff.XOR},
         *     {@link android.graphics.PorterDuff.Mode#ADD PorterDuff.ADD}</li>
         * </ul>
         *
         * @return The canvas if the page is not finished, null otherwise.
         *
         * @see PdfDocument#finishPage(Page)
         */
        public Canvas getCanvas() {
            return mCanvas;
        }

        /**
         * Gets the {@link PageInfo} with meta-data for the page.
         *
         * @return The page info.
         *
         * @see PdfDocument#finishPage(Page)
         */
        public PageInfo getInfo() {
            return mPageInfo;
        }

        boolean isFinished() {
            return mCanvas == null;
        }

        private void finish() {
            if (mCanvas != null) {
                mCanvas.release();
                mCanvas = null;
            }
        }
    }
}
