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

#include "SkParticleDrawable.h"

#include "SkAutoMalloc.h"
#include "SkCanvas.h"
#include "SkImage.h"
#include "SkPaint.h"
#include "SkParticleData.h"
#include "SkRect.h"
#include "SkSurface.h"
#include "SkString.h"
#include "SkRSXform.h"

static sk_sp<SkImage> make_circle_image(int radius) {
    auto surface = SkSurface::MakeRasterN32Premul(radius * 2, radius * 2);
    surface->getCanvas()->clear(SK_ColorTRANSPARENT);
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorWHITE);
    surface->getCanvas()->drawCircle(radius, radius, radius, paint);
    return surface->makeImageSnapshot();
}

struct DrawAtlasArrays {
    DrawAtlasArrays(const SkParticleState particles[], int count, SkPoint center)
            : fXforms(count)
            , fRects(count)
            , fColors(count) {
        for (int i = 0; i < count; ++i) {
            fXforms[i] = particles[i].fPose.asRSXform(center);
            fColors[i] = particles[i].fColor.toSkColor();
        }
    }

    SkAutoTMalloc<SkRSXform> fXforms;
    SkAutoTMalloc<SkRect>    fRects;
    SkAutoTMalloc<SkColor>   fColors;
};

class SkCircleDrawable : public SkParticleDrawable {
public:
    SkCircleDrawable(int radius = 1)
            : fRadius(radius) {
        this->rebuild();
    }

    REFLECTED(SkCircleDrawable, SkParticleDrawable)

    void draw(SkCanvas* canvas, const SkParticleState particles[], int count,
              const SkPaint* paint) override {
        SkPoint center = { SkIntToScalar(fRadius), SkIntToScalar(fRadius) };
        DrawAtlasArrays arrays(particles, count, center);
        for (int i = 0; i < count; ++i) {
            arrays.fRects[i].set(0.0f, 0.0f, fImage->width(), fImage->height());
        }
        canvas->drawAtlas(fImage, arrays.fXforms.get(), arrays.fRects.get(), arrays.fColors.get(),
                          count, SkBlendMode::kModulate, nullptr, paint);
    }

    void visitFields(SkFieldVisitor* v) override {
        v->visit("Radius", fRadius);
        this->rebuild();
    }

private:
    int fRadius;

    void rebuild() {
        fRadius = SkTMax(fRadius, 1);
        if (!fImage || fImage->width() != 2 * fRadius) {
            fImage = make_circle_image(fRadius);
        }
    }

    // Cached
    sk_sp<SkImage> fImage;
};

class SkImageDrawable : public SkParticleDrawable {
public:
    SkImageDrawable(const SkString& path = SkString(), int cols = 1, int rows = 1)
            : fPath(path)
            , fCols(cols)
            , fRows(rows) {
        this->rebuild();
    }

    REFLECTED(SkImageDrawable, SkParticleDrawable)

    void draw(SkCanvas* canvas, const SkParticleState particles[], int count,
              const SkPaint* paint) override {
        SkRect baseRect = getBaseRect();
        SkPoint center = { baseRect.width() * 0.5f, baseRect.height() * 0.5f };
        DrawAtlasArrays arrays(particles, count, center);

        int frameCount = fCols * fRows;
        for (int i = 0; i < count; ++i) {
            int frame = static_cast<int>(particles[i].fFrame * frameCount + 0.5f);
            frame = SkTPin(frame, 0, frameCount - 1);
            int row = frame / fCols;
            int col = frame % fCols;
            arrays.fRects[i] = baseRect.makeOffset(col * baseRect.width(), row * baseRect.height());
        }
        canvas->drawAtlas(fImage, arrays.fXforms.get(), arrays.fRects.get(), arrays.fColors.get(),
                          count, SkBlendMode::kModulate, nullptr, paint);
    }

    void visitFields(SkFieldVisitor* v) override {
        SkString oldPath = fPath;

        v->visit("Path", fPath);
        v->visit("Columns", fCols);
        v->visit("Rows", fRows);

        fCols = SkTMax(fCols, 1);
        fRows = SkTMax(fRows, 1);
        if (oldPath != fPath) {
            this->rebuild();
        }
    }

private:
    SkString fPath;
    int      fCols;
    int      fRows;

    SkRect getBaseRect() const {
        return SkRect::MakeWH(static_cast<float>(fImage->width()) / fCols,
                              static_cast<float>(fImage->height() / fRows));
    }

    void rebuild() {
        fImage = SkImage::MakeFromEncoded(SkData::MakeFromFileName(fPath.c_str()));
        if (!fImage) {
            if (!fPath.isEmpty()) {
                SkDebugf("Could not load image \"%s\"\n", fPath.c_str());
            }
            fImage = make_circle_image(1);
        }
    }

    // Cached
    sk_sp<SkImage> fImage;
};

void SkParticleDrawable::RegisterDrawableTypes() {
    REGISTER_REFLECTED(SkParticleDrawable);
    REGISTER_REFLECTED(SkCircleDrawable);
    REGISTER_REFLECTED(SkImageDrawable);
}

sk_sp<SkParticleDrawable> SkParticleDrawable::MakeCircle(int radius) {
    return sk_sp<SkParticleDrawable>(new SkCircleDrawable(radius));
}

sk_sp<SkParticleDrawable> SkParticleDrawable::MakeImage(const SkString& path, int cols, int rows) {
    return sk_sp<SkParticleDrawable>(new SkImageDrawable(path, cols, rows));
}
