/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkDocument_DEFINED
#define SkDocument_DEFINED

#include "SkBitmap.h"
#include "SkPicture.h"
#include "SkRect.h"
#include "SkRefCnt.h"

class SkCanvas;
class SkWStream;

/** SK_ScalarDefaultDPI is 72 DPI.
*/
#define SK_ScalarDefaultRasterDPI           72.0f

/**
 *  High-level API for creating a document-based canvas. To use..
 *
 *  1. Create a document, specifying a stream to store the output.
 *  2. For each "page" of content:
 *      a. canvas = doc->beginPage(...)
 *      b. draw_my_content(canvas);
 *      c. doc->endPage();
 *  3. Close the document with doc->close().
 */
class SkDocument : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(SkDocument)

    /**
     *  Create a PDF-backed document, writing the results into a file.
     *  If there is an error trying to create the doc, returns NULL.
     *  encoder sets the DCTEncoder for images, to encode a bitmap
     *    as JPEG (DCT).
     *  rasterDpi - the DPI at which features without native PDF support
     *              will be rasterized (e.g. draw image with perspective,
     *              draw text with perspective, ...)
     *              A larger DPI would create a PDF that reflects the original
     *              intent with better fidelity, but it can make for larger
     *              PDF files too, which would use more memory while rendering,
     *              and it would be slower to be processed or sent online or
     *              to printer.
     */
    static SkDocument* CreatePDF(
            const char filename[],
            SkPicture::EncodeBitmap encoder = NULL,
            SkScalar rasterDpi = SK_ScalarDefaultRasterDPI);

    /**
     *  Create a PDF-backed document, writing the results into a stream.
     *  If there is an error trying to create the doc, returns NULL.
     *
     *  The document may write to the stream at anytime during its lifetime,
     *  until either close() is called or the document is deleted. Once close()
     *  has been called, and all of the data has been written to the stream,
     *  if there is a Done proc provided, it will be called with the stream.
     *  The proc can delete the stream, or whatever it needs to do.
     *  encoder sets the DCTEncoder for images, to encode a bitmap
     *    as JPEG (DCT).
     *  Done - clean up method intended to allow deletion of the stream.
     *         Its aborted parameter is true if the cleanup is due to an abort
     *         call. It is false otherwise.
     *  rasterDpi - the DPI at which features without native PDF support
     *              will be rasterized (e.g. draw image with perspective,
     *              draw text with perspective, ...)
     *              A larger DPI would create a PDF that reflects the original
     *              intent with better fidelity, but it can make for larger
     *              PDF files too, which would use more memory while rendering,
     *              and it would be slower to be processed or sent online or
     *              to printer.     */
    static SkDocument* CreatePDF(
            SkWStream*, void (*Done)(SkWStream*,bool aborted) = NULL,
            SkPicture::EncodeBitmap encoder = NULL,
            SkScalar rasterDpi = SK_ScalarDefaultRasterDPI);

    /**
     *  Begin a new page for the document, returning the canvas that will draw
     *  into the page. The document owns this canvas, and it will go out of
     *  scope when endPage() or close() is called, or the document is deleted.
     */
    SkCanvas* beginPage(SkScalar width, SkScalar height,
                        const SkRect* content = NULL);

    /**
     *  Call endPage() when the content for the current page has been drawn
     *  (into the canvas returned by beginPage()). After this call the canvas
     *  returned by beginPage() will be out-of-scope.
     */
    void endPage();

    /**
     *  Call close() when all pages have been drawn. This will close the file
     *  or stream holding the document's contents. After close() the document
     *  can no longer add new pages. Deleting the document will automatically
     *  call close() if need be.
     *  Returns true on success or false on failure.
     */
    bool close();

    /**
     *  Call abort() to stop producing the document immediately.
     *  The stream output must be ignored, and should not be trusted.
     */
    void abort();

protected:
    SkDocument(SkWStream*, void (*)(SkWStream*, bool aborted));
    // note: subclasses must call close() in their destructor, as the base class
    // cannot do this for them.
    virtual ~SkDocument();

    virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height,
                                  const SkRect& content) = 0;
    virtual void onEndPage() = 0;
    virtual bool onClose(SkWStream*) = 0;
    virtual void onAbort() = 0;

    enum State {
        kBetweenPages_State,
        kInPage_State,
        kClosed_State
    };
    State getState() const { return fState; }

private:
    SkWStream* fStream;
    void       (*fDoneProc)(SkWStream*, bool aborted);
    State      fState;

    typedef SkRefCnt INHERITED;
};

#endif
