/*
 * 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 "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 "ccpr/GrCCPRGeometry.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 chopped[5];
        fGpuPoints.push_back(fPoints[0]);
        if (GrCCPRChopMonotonicQuadratics(fPoints[0], fPoints[1], fPoints[3], 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(fPoints[3]);
            fGpuPoints.push_back(fPoints[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->rtCommandBuffer()->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
