/*
 * Copyright 2016 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"
#include "SkRRect.h"
#include "SkGaussianEdgeShader.h"

//#define VIZ 1

#ifdef VIZ
#include "SkStroke.h"

static void draw_stroke(SkCanvas* canvas, const SkRRect& rr, const SkPaint& p, SkColor color) {
    SkPath output;

    if (SkPaint::kFill_Style == p.getStyle()) {
        output.addRRect(rr);
    } else {
        SkPath input;
        input.addRRect(rr);

        SkStroke stroke(p);
        stroke.strokePath(input, &output);
    }

    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(color);

    canvas->drawPath(output, paint);
}

static void extract_pts(const SkBitmap& bm, SkTDArray<SkPoint>* pts,
                        int xOff, int width) {
    pts->rewind();

    for (int x = 0; x < width; ++x) {
        SkColor color = bm.getColor(xOff+x, 0);    

        pts->append()->set(SkIntToScalar(x), 255.0f-SkColorGetB(color));
        if (x > 0 && x < width-1) {
            pts->append()->set(SkIntToScalar(x), 255.0f-SkColorGetB(color));
        }
    }
}

static void draw_row(SkCanvas* canvas, int row, int width) {
    SkPaint paint;
    paint.setAntiAlias(true);

    SkBitmap readback;

    if (!canvas->readPixels(SkIRect::MakeXYWH(0, row, width, 1), &readback)) {
        return;
    }

    SkTDArray<SkPoint> pts;
    pts.setReserve(width/3);

    extract_pts(readback, &pts, 0, width/3);
    paint.setColor(SK_ColorRED);
    canvas->drawPoints(SkCanvas::kLines_PointMode, pts.count(), pts.begin(), paint);

    extract_pts(readback, &pts, width/3, width/3);
    paint.setColor(SK_ColorGREEN);
    canvas->drawPoints(SkCanvas::kLines_PointMode, pts.count(), pts.begin(), paint);

    extract_pts(readback, &pts, 2*width/3, width/3);
    paint.setColor(SK_ColorBLUE);
    canvas->drawPoints(SkCanvas::kLines_PointMode, pts.count(), pts.begin(), paint);
}
#endif

namespace skiagm {

// This GM exercises the SkGaussianEdgeShader.
// It draws three columns showing filled, stroked, and stroke and filled rendering.
// It draws three rows showing a blur radius smaller than, equal to
// and, finally, double the RRect's corner radius
// In VIZ mode an extra column is drawn showing the blur ramps (they should all line up).
class GaussianEdgeGM : public GM {
public:
    GaussianEdgeGM() {
        this->setBGColor(SK_ColorWHITE);
    }

protected:

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

    SkISize onISize() override {
        int numCols = kNumBaseCols;
#ifdef VIZ
        numCols++;
#endif

        return SkISize::Make(kPad + numCols*(kCellWidth+kPad),
                             kPad + kNumRows*(kCellWidth+kPad));
    }

    static void DrawRow(SkCanvas* canvas, int blurRad, int midLine) {
        SkAutoCanvasRestore acr(canvas, true);

        SkRRect rrects[kNumBaseCols];
        SkPaint paints[kNumBaseCols];

        {
            const SkRect r = SkRect::MakeIWH(kRRSize, kRRSize);
            const SkRRect baseRR = SkRRect::MakeRectXY(r,
                                                       SkIntToScalar(kRRRad),
                                                       SkIntToScalar(kRRRad));

            SkPaint basePaint;
            basePaint.setAntiAlias(true);
            basePaint.setShader(SkGaussianEdgeShader::Make());
            basePaint.setColor(SkColorSetARGB(255, (4 * blurRad) >> 8, (4 * blurRad) & 0xff, 0));

            //----
            paints[0] = basePaint;
            rrects[0] = baseRR;

            //----
            paints[1] = basePaint;
            paints[1].setStyle(SkPaint::kStroke_Style);

            rrects[1] = baseRR;
            if (blurRad/2.0f < kRRRad) {
                rrects[1].inset(blurRad/2.0f, blurRad/2.0f);
                paints[1].setStrokeWidth(SkIntToScalar(blurRad));
            } else {
                SkScalar inset = kRRRad - 0.5f;
                rrects[1].inset(inset, inset);
                SkScalar pad = blurRad/2.0f - inset;
                paints[1].setStrokeWidth(blurRad + 2.0f * pad);                
                paints[1].setColor(SkColorSetARGB(255, (4 * blurRad) >> 8, (4 * blurRad) & 0xff,
                                                  (int)(4.0f*pad)));
            }

            //----
            paints[2] = basePaint;
            paints[2].setStyle(SkPaint::kStrokeAndFill_Style);

            rrects[2] = baseRR;
            if (blurRad/2.0f < kRRRad) {
                rrects[2].inset(blurRad/2.0f, blurRad/2.0f);
                paints[2].setStrokeWidth(SkIntToScalar(blurRad));
            } else {
                SkScalar inset = kRRRad - 0.5f;
                rrects[2].inset(inset, inset);
                SkScalar pad = blurRad/2.0f - inset;
                paints[2].setStrokeWidth(blurRad + 2.0f * pad);                
                paints[2].setColor(SkColorSetARGB(255, (4 * blurRad) >> 8, (4 * blurRad) & 0xff,
                                                  (int)(4.0f*pad)));
            }
        }

        //----
        canvas->save();
            // draw the shadows
            for (int i = 0; i < kNumBaseCols; ++i) {
                canvas->drawRRect(rrects[i], paints[i]);
                canvas->translate(SkIntToScalar(kCellWidth+kPad), 0.0f);
            }

#ifdef VIZ
            // draw the visualization of the shadow ramps
            draw_row(canvas, midLine, 3*(kRRSize+kPad));
#endif
        canvas->restore();

#ifdef VIZ
        const SkColor colors[kNumBaseCols] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };

        // circle back and draw the stroked geometry (they would mess up the viz otherwise)
        for (int i = 0; i < kNumBaseCols; ++i) {
            draw_stroke(canvas, rrects[i], paints[i], colors[i]);
            canvas->translate(SkIntToScalar(kCellWidth+kPad), 0.0f);
        }
#endif
    }

    void onDraw(SkCanvas* canvas) override {
        GrRenderTargetContext* renderTargetContext =
            canvas->internal_private_accessTopLayerRenderTargetContext();
        if (!renderTargetContext) {
            skiagm::GM::DrawGpuOnlyMessage(canvas);
            return;
        }

        const int blurRadii[kNumRows] = { kRRRad/2, kRRRad, 2*kRRRad };

        canvas->translate(SkIntToScalar(kPad), SkIntToScalar(kPad));
        for (int i = 0; i < kNumRows; ++i) {
            DrawRow(canvas, blurRadii[i], kPad+(i*kRRSize)+kRRSize/2);
            canvas->translate(0.0f, SkIntToScalar(kCellWidth+kPad));
        }
    }

private:
    static const int kNumRows = 3;
    static const int kNumBaseCols = 3;
    static const int kPad = 5;
    static const int kRRSize = 256;
    static const int kRRRad = 64;
    static const int kCellWidth = kRRSize;

    typedef GM INHERITED;
};

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

DEF_GM(return new GaussianEdgeGM;)
}
