/*
 * 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.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
 * open 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 {

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

    private final CloseGuard mCloseGuard = CloseGuard.get();

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

    private int 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(nativeCreatePage(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;
        nativeAppendPage(mNativeDocument, page.mCanvas.mNativeCanvas);
        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) {
            nativeFinalize(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 int nativeCreateDocument();

    private native void nativeFinalize(int document);

    private native void nativeAppendPage(int document, int page);

    private native void nativeWriteTo(int document, OutputStream out, byte[] chunk);

    private static native int nativeCreatePage(int pageWidth, int pageHeight, int contentLeft,
            int contentTop, int contentRight, int contentBottom);

    private final class PdfCanvas extends Canvas {

        public PdfCanvas(int 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>{@link Canvas#clipPath(android.graphics.Path)
         *     Canvas.clipPath(android.graphics.Path)}</li>
         * <li>All flavors of {@link Canvas#drawText(String, float, float,
         *     android.graphics.Paint) Canvas.drawText(String, float, float,
         *     android.graphics.Paint)}</li>
         * <li>All flavors of {@link Canvas#drawPosText(String, float[],
         *     android.graphics.Paint) Canvas.drawPosText(String, float[],
         *     android.graphics.Paint)}</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>{@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>
         * <li>Perspective transforms</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;
            }
        }
    }
}
