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

#include "SkTypes.h"

#if SK_SUPPORT_GPU

#include "GrContextPriv.h"
#include "GrPathUtils.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
#include "GrResourceProvider.h"
#include "SampleCode.h"
#include "SkCanvas.h"
#include "SkGeometry.h"
#include "SkMakeUnique.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkView.h"
#include "ccpr/GrCCPRCoverageProcessor.h"
#include "gl/GrGLGpu.cpp"
#include "ops/GrDrawOp.h"

using PrimitiveInstance = GrCCPRCoverageProcessor::PrimitiveInstance;
using Mode = GrCCPRCoverageProcessor::Mode;

static int num_points(Mode mode)  {
    return mode >= GrCCPRCoverageProcessor::Mode::kSerpentineInsets ? 4 : 3;
}

static int is_curve(Mode mode)  {
    return mode >= GrCCPRCoverageProcessor::Mode::kQuadraticHulls;
}

/**
 * This sample visualizes the AA bloat geometry generated by the ccpr geometry shaders. It
 * increases the AA bloat by 50x and outputs color instead of coverage (coverage=+1 -> green,
 * coverage=0 -> black, coverage=-1 -> red). Use the keys 1-7 to cycle through the different
 * geometry processors.
 */
class CCPRGeometryView : public SampleView {
public:
    CCPRGeometryView() { this->updateGpuData(); }
    void onDrawContent(SkCanvas*) override;

    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override;
    bool onClick(SampleView::Click*) override;
    bool onQuery(SkEvent* evt) override;

private:
    class Click;
    class Op;

    void updateAndInval() {
        this->updateGpuData();
        this->inval(nullptr);
    }

    void updateGpuData();

    Mode fMode = Mode::kTriangleHulls;

    SkPoint fPoints[4] = {
        {100.05f, 100.05f},
        {100.05f, 300.95f},
        {400.75f, 300.95f},
        {400.75f, 100.05f}
    };

    SkSTArray<16, SkPoint>            fGpuPoints;
    SkSTArray<3, PrimitiveInstance>   fGpuInstances;

    typedef SampleView INHERITED;
};

class CCPRGeometryView::Op : public GrDrawOp {
    DEFINE_OP_CLASS_ID

public:
    Op(CCPRGeometryView* view)
            : INHERITED(ClassID())
            , fView(view) {
        this->setBounds(SkRect::MakeLargest(), GrOp::HasAABloat::kNo, GrOp::IsZeroArea::kNo);
    }

    const char* name() const override { return "[Testing/Sample code] CCPRGeometryView::Op"; }

private:
    FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
    RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*) override {
        return RequiresDstTexture::kNo;
    }
    bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override { return false; }
    void onPrepare(GrOpFlushState*) override {}
    void onExecute(GrOpFlushState*) override;

    CCPRGeometryView* fView;

    typedef GrDrawOp INHERITED;
};

void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
    SkAutoCanvasRestore acr(canvas, true);
    canvas->setMatrix(SkMatrix::I());

    SkPath outline;
    outline.moveTo(fPoints[0]);
    if (4 == num_points(fMode)) {
        outline.cubicTo(fPoints[1], fPoints[2], fPoints[3]);
    } else if (is_curve(fMode)) {
        outline.quadTo(fPoints[1], fPoints[3]);
    } else {
        outline.lineTo(fPoints[1]);
        outline.lineTo(fPoints[3]);
    }
    outline.close();

    SkPaint outlinePaint;
    outlinePaint.setColor(0x30000000);
    outlinePaint.setStyle(SkPaint::kStroke_Style);
    outlinePaint.setStrokeWidth(0);
    outlinePaint.setAntiAlias(true);

    canvas->drawPath(outline, outlinePaint);

    const char* caption = "Use GPU backend to visualize geometry.";

    if (GrRenderTargetContext* rtc =
        canvas->internal_private_accessTopLayerRenderTargetContext()) {
        rtc->priv().testingOnly_addDrawOp(skstd::make_unique<Op>(this));
        caption = GrCCPRCoverageProcessor::GetProcessorName(fMode);
    }

    SkPaint pointsPaint;
    pointsPaint.setColor(SK_ColorBLUE);
    pointsPaint.setStrokeWidth(8);
    pointsPaint.setAntiAlias(true);

    if (4 == num_points(fMode)) {
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, fPoints, pointsPaint);
    } else {
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, fPoints, pointsPaint);
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, fPoints + 3, pointsPaint);
    }

    SkPaint captionPaint;
    captionPaint.setTextSize(20);
    captionPaint.setColor(SK_ColorBLACK);
    captionPaint.setAntiAlias(true);
    canvas->drawText(caption, strlen(caption), 10, 30, captionPaint);
}

void CCPRGeometryView::updateGpuData() {
    int vertexCount = num_points(fMode);

    fGpuPoints.reset();
    fGpuInstances.reset();

    if (4 == vertexCount) {
        double t[2], s[2];
        SkCubicType type = SkClassifyCubic(fPoints, t, s);
        SkSTArray<2, float> chops;
        for (int i = 0; i < 2; ++i) {
            float chop = t[i] / s[i];
            if (chop > 0 && chop < 1) {
                chops.push_back(chop);
            }
        }

        int instanceCount = chops.count() + 1;
        SkPoint chopped[10];
        SkChopCubicAt(fPoints, chopped, chops.begin(), chops.count());

        // Endpoints first, then control points.
        for (int i = 0; i <= instanceCount; ++i) {
            fGpuPoints.push_back(chopped[3*i]);
        }
        if (3 == instanceCount && SkCubicType::kLoop == type) {
            fGpuPoints[2] = fGpuPoints[1]; // Account for floating point error.
        }
        for (int i = 0; i < instanceCount; ++i) {
            fGpuPoints.push_back(chopped[3*i + 1]);
            fGpuPoints.push_back(chopped[3*i + 2]);
            // FIXME: we don't bother to send down the correct KLM t,s roots.
            fGpuPoints.push_back({0, 0});
            fGpuPoints.push_back({0, 0});
        }

        if (fMode < Mode::kLoopInsets && SkCubicType::kLoop == type) {
            fMode = (Mode) ((int) fMode + 2);
        }
        if (fMode >= Mode::kLoopInsets && SkCubicType::kLoop != type) {
            fMode = (Mode) ((int) fMode - 2);
        }

        int controlPointsIdx = instanceCount + 1;
        for (int i = 0; i < instanceCount; ++i) {
            fGpuInstances.push_back().fCubicData = {controlPointsIdx + i * 4, i};
        }
    } else if (is_curve(fMode)) {
        SkPoint P[3] = {fPoints[0], fPoints[1], fPoints[3]};
        SkPoint chopped[5];
        fGpuPoints.push_back(P[0]);
        if (GrPathUtils::chopMonotonicQuads(P, chopped)) {
            // Endpoints.
            fGpuPoints.push_back(chopped[2]);
            fGpuPoints.push_back(chopped[4]);
            // Control points.
            fGpuPoints.push_back(chopped[1]);
            fGpuPoints.push_back(chopped[3]);
            fGpuInstances.push_back().fQuadraticData = {3, 0};
            fGpuInstances.push_back().fQuadraticData = {4, 1};
        } else {
            fGpuPoints.push_back(P[2]);
            fGpuPoints.push_back(P[1]);
            fGpuInstances.push_back().fQuadraticData = {2, 0};
        }
    } else {
        fGpuPoints.push_back(fPoints[0]);
        fGpuPoints.push_back(fPoints[3]);
        fGpuPoints.push_back(fPoints[1]);
        fGpuInstances.push_back().fTriangleData = {0, 2, 1}; // Texel buffer has endpoints first.
    }

    for (PrimitiveInstance& instance : fGpuInstances) {
        instance.fPackedAtlasOffset = 0;
    }
}

void CCPRGeometryView::Op::onExecute(GrOpFlushState* state) {
    GrResourceProvider* rp = state->resourceProvider();
    GrContext* context = state->gpu()->getContext();
    GrGLGpu* glGpu = kOpenGL_GrBackend == context->contextPriv().getBackend() ?
                     static_cast<GrGLGpu*>(state->gpu()) : nullptr;
    int vertexCount = num_points(fView->fMode);

    sk_sp<GrBuffer> pointsBuffer(rp->createBuffer(fView->fGpuPoints.count() * sizeof(SkPoint),
                                                  kTexel_GrBufferType, kDynamic_GrAccessPattern,
                                                  GrResourceProvider::kNoPendingIO_Flag |
                                                  GrResourceProvider::kRequireGpuMemory_Flag,
                                                  fView->fGpuPoints.begin()));
    if (!pointsBuffer) {
        return;
    }

    sk_sp<GrBuffer> instanceBuffer(rp->createBuffer(fView->fGpuInstances.count() * 4 * sizeof(int),
                                                    kVertex_GrBufferType, kDynamic_GrAccessPattern,
                                                    GrResourceProvider::kNoPendingIO_Flag |
                                                    GrResourceProvider::kRequireGpuMemory_Flag,
                                                    fView->fGpuInstances.begin()));
    if (!instanceBuffer) {
        return;
    }

    GrPipeline pipeline(state->drawOpArgs().fProxy, GrPipeline::ScissorState::kDisabled,
                        SkBlendMode::kSrcOver);

    GrCCPRCoverageProcessor ccprProc(fView->fMode, pointsBuffer.get());
    SkDEBUGCODE(ccprProc.enableDebugVisualizations();)

    GrMesh mesh(4 == vertexCount ?  GrPrimitiveType::kLinesAdjacency : GrPrimitiveType::kTriangles);
    mesh.setInstanced(instanceBuffer.get(), fView->fGpuInstances.count(), 0, vertexCount);

    if (glGpu) {
        glGpu->handleDirtyContext();
        GR_GL_CALL(glGpu->glInterface(), PolygonMode(GR_GL_FRONT_AND_BACK, GR_GL_LINE));
        GR_GL_CALL(glGpu->glInterface(), Enable(GR_GL_LINE_SMOOTH));
    }

    state->commandBuffer()->draw(pipeline, ccprProc, &mesh, nullptr, 1, this->bounds());

    if (glGpu) {
        context->resetContext(kMisc_GrGLBackendState);
    }
}

class CCPRGeometryView::Click : public SampleView::Click {
public:
    Click(SkView* target, int ptIdx) : SampleView::Click(target), fPtIdx(ptIdx) {}

    void doClick(SkPoint points[]) {
        if (fPtIdx >= 0) {
            this->dragPoint(points, fPtIdx);
        } else {
            for (int i = 0; i < 4; ++i) {
                this->dragPoint(points, i);
            }
        }
    }

private:
    void dragPoint(SkPoint points[], int idx)  {
        SkIPoint delta = fICurr - fIPrev;
        points[idx] += SkPoint::Make(delta.x(), delta.y());
    }

    int fPtIdx;
};

SkView::Click* CCPRGeometryView::onFindClickHandler(SkScalar x, SkScalar y, unsigned) {
    for (int i = 0; i < 4; ++i) {
        if (4 != num_points(fMode) && 2 == i) {
            continue;
        }
        if (fabs(x - fPoints[i].x()) < 20 && fabsf(y - fPoints[i].y()) < 20) {
            return new Click(this, i);
        }
    }
    return new Click(this, -1);
}

bool CCPRGeometryView::onClick(SampleView::Click* click) {
    Click* myClick = (Click*) click;
    myClick->doClick(fPoints);
    this->updateAndInval();
    return true;
}

bool CCPRGeometryView::onQuery(SkEvent* evt) {
    if (SampleCode::TitleQ(*evt)) {
        SampleCode::TitleR(evt, "CCPRGeometry");
        return true;
    }
    SkUnichar unichar;
    if (SampleCode::CharQ(*evt, &unichar)) {
        if (unichar >= '1' && unichar <= '7') {
            fMode = Mode(unichar - '1');
            if (fMode >= Mode::kCombinedTriangleHullsAndEdges) {
                fMode = Mode(int(fMode) + 1);
            }
            this->updateAndInval();
            return true;
        }
        if (unichar == 'D') {
            SkDebugf("    SkPoint fPoints[4] = {\n");
            SkDebugf("        {%f, %f},\n", fPoints[0].x(), fPoints[0].y());
            SkDebugf("        {%f, %f},\n", fPoints[1].x(), fPoints[1].y());
            SkDebugf("        {%f, %f},\n", fPoints[2].x(), fPoints[2].y());
            SkDebugf("        {%f, %f}\n", fPoints[3].x(), fPoints[3].y());
            SkDebugf("    };\n");
            return true;
        }
    }
    return this->INHERITED::onQuery(evt);
}

DEF_SAMPLE( return new CCPRGeometryView; )

#endif // SK_SUPPORT_GPU
