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

#include "gm.h"
#if SK_SUPPORT_GPU
#include "GrFragmentProcessor.h"
#include "GrCoordTransform.h"
#include "GrInvariantOutput.h"
#include "effects/GrXfermodeFragmentProcessor.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "Resources.h"
#include "SkReadBuffer.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkTypeface.h"
#include "SkWriteBuffer.h"

namespace skiagm {

///////////////////////////////////////////////////////////////////////////////

class DCShader : public SkShader {
public:
    DCShader(const SkMatrix& matrix) : fDeviceMatrix(matrix) {}

    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DCShader);

    void flatten(SkWriteBuffer& buf) const override {
        buf.writeMatrix(fDeviceMatrix);
    }

    sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;

#ifndef SK_IGNORE_TO_STRING
    void toString(SkString* str) const override {
        str->appendf("DCShader: ()");
    }
#endif

private:
    const SkMatrix fDeviceMatrix;
};

sk_sp<SkFlattenable> DCShader::CreateProc(SkReadBuffer& buf) {
    SkMatrix matrix;
    buf.readMatrix(&matrix);
    return sk_make_sp<DCShader>(matrix);
}

class DCFP : public GrFragmentProcessor {
public:
    DCFP(const SkMatrix& m) : fDeviceTransform(kDevice_GrCoordSet, m) {
        this->addCoordTransform(&fDeviceTransform);
        this->initClassID<DCFP>();
    }

    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
        class DCGLFP : public GrGLSLFragmentProcessor {
            void emitCode(EmitArgs& args) override {
                GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
                SkString coords2d = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
                fragBuilder->codeAppendf("vec2 c = %s;", coords2d.c_str());
                fragBuilder->codeAppend("vec2 r = mod(c, vec2(20.0));");
                fragBuilder->codeAppend("vec4 color = vec4(0.5*sin(c.x / 15.0) + 0.5,"
                                                      "0.5*cos((c.x + c.y) / 15.0) + 0.5,"
                                                      "(r.x + r.y) / 20.0,"
                                                      "distance(r, vec2(15.0)) / 20.0 + 0.2);");
                fragBuilder->codeAppendf("color.rgb *= color.a;"
                                         "%s = color * %s;",
                                         args.fOutputColor, GrGLSLExpr4(args.fInputColor).c_str());
            }
            void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override {}
        };
        return new DCGLFP;
    }

    const char* name() const override { return "DCFP"; }

    void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
        inout->mulByUnknownFourComponents();
    }

private:
    void onGetGLSLProcessorKey(const GrGLSLCaps& caps,
                               GrProcessorKeyBuilder* b) const override {}

    bool onIsEqual(const GrFragmentProcessor&) const override { return true; }

    GrCoordTransform fDeviceTransform;
};

sk_sp<GrFragmentProcessor> DCShader::asFragmentProcessor(const AsFPArgs&) const {
    sk_sp<GrFragmentProcessor> inner(new DCFP(fDeviceMatrix));
    return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner));
}

class DCShaderGM : public GM {
public:
    DCShaderGM() {
        this->setBGColor(sk_tool_utils::color_to_565(0xFFAABBCC));
    }

    ~DCShaderGM() override {
        for (int i = 0; i < fPrims.count(); ++i) {
            delete fPrims[i];
        }
    }

protected:

    SkString onShortName() override {
        return SkString("dcshader");
    }

    SkISize onISize() override { return SkISize::Make(1000, 900); }

    void onOnceBeforeDraw() override {
        struct Rect : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkRect rect = SkRect::MakeXYWH(0, 0, 50, 50);
                canvas->drawRect(rect, paint);
                return rect;
            }
        };

        struct Circle : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                constexpr SkScalar radius = 25;
                canvas->drawCircle(radius, radius, radius, paint);
                return SkRect::MakeXYWH(0, 0, 2 * radius, 2 * radius);
            }
        };

        struct RRect : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkRRect rrect;
                rrect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 10, 10);
                canvas->drawRRect(rrect, paint);
                return rrect.getBounds();
            }
        };

        struct DRRect : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkRRect outerRRect;
                outerRRect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 5, 5);
                SkRRect innerRRect;
                innerRRect.setRectXY(SkRect::MakeXYWH(5, 8, 35, 30), 8, 3);
                canvas->drawDRRect(outerRRect, innerRRect, paint);
                return outerRRect.getBounds();
            }
        };
        struct Path : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkPath path;
                path.addCircle(15, 15, 10);
                path.addOval(SkRect::MakeXYWH(2, 2, 22, 37));
                path.setFillType(SkPath::kEvenOdd_FillType);
                canvas->drawPath(path, paint);
                return path.getBounds();
            }
        };

        struct Points : public Prim {
            Points(SkCanvas::PointMode mode) : fMode(mode) {}

            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkRandom random;
                SkPoint points[500];
                SkRect bounds = SkRect::MakeWH(50, 50);
                int count = SkToInt(SK_ARRAY_COUNT(points));
                if (SkCanvas::kPoints_PointMode != fMode) {
                    count = SkTMin(count, 10);
                }
                for (int p = 0; p < count; ++p) {
                    points[p].fX = random.nextUScalar1() * bounds.width();
                    points[p].fY = random.nextUScalar1() * bounds.width();
                }
                canvas->drawPoints(fMode, count, points, paint);
                return bounds;
            }
            SkCanvas::PointMode fMode;
        };

        struct Text : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& origPaint) override {
                SkPaint paint = origPaint;
                paint.setTextSize(30.f);
                this->setFont(&paint);
                const char* text = this->text();
                const SkVector offset = SkVector::Make(10, 10);
                canvas->drawText(text, strlen(text), offset.fX, offset.fY, paint);
                SkRect bounds;
                paint.measureText(text, strlen(text), &bounds);
                bounds.offset(offset);
                return bounds;
            }

            virtual void setFont(SkPaint* paint) {
                sk_tool_utils::set_portable_typeface(paint);
            }

            virtual const char* text() const { return "Hello, Skia!"; }
        };

        fPrims.push_back(new Rect);
        fPrims.push_back(new Circle);
        fPrims.push_back(new RRect);
        fPrims.push_back(new DRRect);
        fPrims.push_back(new Path);
        fPrims.push_back(new Points(SkCanvas::kPoints_PointMode));
        fPrims.push_back(new Points(SkCanvas::kLines_PointMode));
        fPrims.push_back(new Points(SkCanvas::kPolygon_PointMode));
        fPrims.push_back(new Text);
    }

    void onDraw(SkCanvas* canvas) override {
        // This GM exists to test a specific feature of the GPU backend. It does not work with the
        // sw rasterizer, tile modes, etc.
        if (nullptr == canvas->getGrContext()) {
            skiagm::GM::DrawGpuOnlyMessage(canvas);
            return;
        }
        SkPaint paint;
        SkTArray<SkMatrix> devMats;
        devMats.push_back().reset();
        devMats.push_back().setRotate(45, 500, 500);
        devMats.push_back().setRotate(-30, 200, 200);
        devMats.back().setPerspX(-SK_Scalar1 / 2000);
        devMats.back().setPerspY(SK_Scalar1 / 1000);


        SkTArray<SkMatrix> viewMats;
        viewMats.push_back().setScale(0.75f, 0.75f);
        viewMats.push_back().setRotate(45, 50, 50);
        viewMats.back().postScale(0.5f, 1.1f);

        canvas->translate(10, 20);
        canvas->save();
        SkScalar tx = 0, maxTy = 0;
        constexpr SkScalar kW = 900;

        for (int aa = 0; aa < 2; ++aa) {
            for (int i = 0; i < fPrims.count(); ++i) {
                for (int j = 0; j < devMats.count(); ++j) {
                    for (int k = 0; k < viewMats.count(); ++k) {
                        paint.setShader(sk_make_sp<DCShader>(devMats[j]));
                        paint.setAntiAlias(SkToBool(aa));
                        canvas->save();
                        canvas->concat(viewMats[k]);
                        SkRect bounds = fPrims[i]->draw(canvas, paint);
                        canvas->restore();
                        viewMats[k].mapRect(&bounds);
                        // add margins
                        bounds.fRight += 20;
                        bounds.fBottom += 20;
                        canvas->translate(bounds.fRight, 0);
                        tx += bounds.fRight;
                        maxTy = SkTMax(bounds.fBottom, maxTy);
                        if (tx > kW) {
                            tx = 0;
                            canvas->restore();
                            canvas->translate(0, maxTy);
                            canvas->save();
                            maxTy = 0;
                        }
                    }
                }
            }
        }
        canvas->restore();
    }

private:
    struct Prim {
        virtual ~Prim() {}
        virtual SkRect draw(SkCanvas*, const SkPaint&) = 0;
    };

    SkTArray<Prim*> fPrims;

    typedef GM INHERITED;
};

DEF_GM(return new DCShaderGM;)
}
#endif
