#include "PictureRenderer.h"
#include "SamplePipeControllers.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkGPipe.h"
#include "SkPicture.h"
#include "SkTDArray.h"
#include "SkTypes.h"
#include "picture_utils.h"

namespace sk_tools {

enum {
    kDefaultTileWidth = 256,
    kDefaultTileHeight = 256
};

void PictureRenderer::init(SkPicture* pict) {
    SkASSERT(fPicture == NULL);
    SkASSERT(fCanvas.get() == NULL);
    if (fPicture != NULL || fCanvas.get() != NULL) {
        return;
    }

    SkASSERT(pict != NULL);
    if (pict == NULL) {
        return;
    }

    fPicture = pict;
    SkBitmap bitmap;
    sk_tools::setup_bitmap(&bitmap, fPicture->width(), fPicture->height());
    fCanvas.reset(SkNEW_ARGS(SkCanvas, (bitmap)));
}

void PictureRenderer::end() {
    fPicture = NULL;
    fCanvas.reset(NULL);
}

void PipePictureRenderer::render() {
    SkASSERT(fCanvas.get() != NULL);
    SkASSERT(fPicture != NULL);
    if (fCanvas.get() == NULL || fPicture == NULL) {
        return;
    }

    PipeController pipeController(fCanvas.get());
    SkGPipeWriter writer;
    SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
    pipeCanvas->drawPicture(*fPicture);
    writer.endRecording();
}

void SimplePictureRenderer::render() {
    SkASSERT(fCanvas.get() != NULL);
    SkASSERT(fPicture != NULL);
    if (fCanvas.get() == NULL || fPicture == NULL) {
        return;
    }

    fCanvas->drawPicture(*fPicture);
}

TiledPictureRenderer::TiledPictureRenderer()
    : fTileWidth(kDefaultTileWidth)
    , fTileHeight(kDefaultTileHeight) {}

void TiledPictureRenderer::init(SkPicture* pict) {
    SkASSERT(pict != NULL);
    SkASSERT(fTiles.count() == 0);
    if (pict == NULL || fTiles.count() != 0) {
        return;
    }

    this->INHERITED::init(pict);

    if (fTileWidthPercentage > 0) {
        fTileWidth = sk_float_ceil2int(fTileWidthPercentage * fPicture->width() / 100);
    }
    if (fTileHeightPercentage > 0) {
        fTileHeight = sk_float_ceil2int(fTileHeightPercentage * fPicture->height() / 100);
    }

    this->setupTiles();
}

void TiledPictureRenderer::render() {
    SkASSERT(fCanvas.get() != NULL);
    SkASSERT(fPicture != NULL);
    if (fCanvas.get() == NULL || fPicture == NULL) {
        return;
    }

    this->drawTiles();
    this->copyTilesToCanvas();
}

void TiledPictureRenderer::end() {
    this->deleteTiles();
    this->INHERITED::end();
}

TiledPictureRenderer::~TiledPictureRenderer() {
    this->deleteTiles();
}

void TiledPictureRenderer::clipTile(const TileInfo& tile) {
    SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
                                 SkIntToScalar(fPicture->height()));
    tile.fCanvas->clipRect(clip);
}

void TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start) {
    TileInfo* tile = fTiles.push();

    tile->fBitmap = SkNEW(SkBitmap);
    sk_tools::setup_bitmap(tile->fBitmap, fTileWidth, fTileHeight);

    tile->fCanvas = SkNEW_ARGS(SkCanvas, (*(tile->fBitmap)));
    tile->fCanvas->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start));
    this->clipTile(*tile);
}

void TiledPictureRenderer::setupTiles() {
    for (int tile_y_start = 0; tile_y_start < fPicture->height();
         tile_y_start += fTileHeight) {
        for (int tile_x_start = 0; tile_x_start < fPicture->width();
             tile_x_start += fTileWidth) {
            this->addTile(tile_x_start, tile_y_start);
        }
    }
}

void TiledPictureRenderer::deleteTiles() {
    for (int i = 0; i < fTiles.count(); ++i) {
        SkDELETE(fTiles[i].fCanvas);
        SkDELETE(fTiles[i].fBitmap);
    }

    fTiles.reset();
}

void TiledPictureRenderer::drawTiles() {
    for (int i = 0; i < fTiles.count(); ++i) {
        fTiles[i].fCanvas->drawPicture(*(fPicture));
    }
}

void TiledPictureRenderer::copyTilesToCanvas() {
    int tile_index = 0;
    for (int tile_y_start = 0; tile_y_start < fPicture->height();
         tile_y_start += fTileHeight) {
        for (int tile_x_start = 0; tile_x_start < fPicture->width();
             tile_x_start += fTileWidth) {
            SkASSERT(tile_index < fTiles.count());
            SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false);
            fCanvas->drawBitmap(source,
                                SkIntToScalar(tile_x_start),
                                SkIntToScalar(tile_y_start));
            ++tile_index;
        }
    }
}

}
