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

#include "Sample.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkFont.h"
#include "SkFontMetrics.h"
#include "SkGradientShader.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUTF.h"

#include <math.h>

static void test_strokerect(SkCanvas* canvas) {
    int width = 100;
    int height = 100;

    SkBitmap bitmap;
    bitmap.allocPixels(SkImageInfo::MakeA8(width*2, height*2));
    bitmap.eraseColor(SK_ColorTRANSPARENT);

    SkScalar dx = 20;
    SkScalar dy = 20;

    SkPath path;
    path.addRect(0.0f, 0.0f,
                 SkIntToScalar(width), SkIntToScalar(height),
                 SkPath::kCW_Direction);
    SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));

    SkCanvas c(bitmap);
    c.translate(dx, dy);

    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(1);

    // use the rect
    c.clear(SK_ColorTRANSPARENT);
    c.drawRect(r, paint);
    canvas->drawBitmap(bitmap, 0, 0, nullptr);

    // use the path
    c.clear(SK_ColorTRANSPARENT);
    c.drawPath(path, paint);
    canvas->drawBitmap(bitmap, SkIntToScalar(2*width), 0, nullptr);
}

static void drawFadingText(SkCanvas* canvas,
                           const char* text, size_t len, SkScalar x, SkScalar y,
                           const SkFont& font, const SkPaint& paint) {
    // Need a bounds for the text
    SkRect bounds;
    SkFontMetrics fm;

    font.getMetrics(&fm);
    bounds.set(x, y + fm.fTop, x + font.measureText(text, len, kUTF8_SkTextEncoding), y + fm.fBottom);

    // may need to outset bounds a little, to account for hinting and/or
    // antialiasing
    bounds.inset(-SkIntToScalar(2), -SkIntToScalar(2));

    canvas->saveLayer(&bounds, nullptr);
    canvas->drawSimpleText(text, len, kUTF8_SkTextEncoding, x, y, font, paint);

    const SkPoint pts[] = {
        { bounds.fLeft, y },
        { bounds.fRight, y }
    };
    const SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 };

    // pos[1] value is where we start to fade, relative to the width
    // of our pts[] array.
    const SkScalar pos[] = { 0, 0.9f, SK_Scalar1 };

    SkPaint p;
    p.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 3, SkTileMode::kClamp));
    p.setBlendMode(SkBlendMode::kDstIn);
    canvas->drawRect(bounds, p);

    canvas->restore();
}

static void test_text(SkCanvas* canvas) {
    SkPaint paint;
    paint.setAntiAlias(true);

    SkFont font;
    font.setSize(20);

    const char* str = "Hamburgefons";
    size_t len = strlen(str);
    SkScalar x = 20;
    SkScalar y = 20;

    canvas->drawSimpleText(str, len, kUTF8_SkTextEncoding, x, y, font, paint);

    y += 20;

    const SkPoint pts[] = { { x, y }, { x + font.measureText(str, len, kUTF8_SkTextEncoding), y } };
    const SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 };
    const SkScalar pos[] = { 0, 0.9f, 1 };
    paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos,
                                                 SK_ARRAY_COUNT(colors),
                                                 SkTileMode::kClamp));
    canvas->drawSimpleText(str, len, kUTF8_SkTextEncoding, x, y, font, paint);

    y += 20;
    paint.setShader(nullptr);
    drawFadingText(canvas, str, len, x, y, font, paint);
}

static void scale_rect(SkIRect* dst, const SkIRect& src, float scale) {
    dst->fLeft = (int)::roundf(src.fLeft * scale);
    dst->fTop = (int)::roundf(src.fTop * scale);
    dst->fRight = (int)::roundf(src.fRight * scale);
    dst->fBottom = (int)::roundf(src.fBottom * scale);
}

static void scale_rgn(SkRegion* dst, const SkRegion& src, float scale) {
    SkRegion tmp;
    SkRegion::Iterator iter(src);

    for (; !iter.done(); iter.next()) {
        SkIRect r;
        scale_rect(&r, iter.rect(), scale);
        tmp.op(r, SkRegion::kUnion_Op);
    }
    dst->swap(tmp);
}

static void paint_rgn(SkCanvas* canvas, const SkRegion& rgn,
                      const SkPaint& paint) {
    SkRegion scaled;
    scale_rgn(&scaled, rgn, 0.5f);

    SkRegion::Iterator  iter(rgn);

    for (; !iter.done(); iter.next())
    {
        SkRect    r;
        r.set(iter.rect());
        canvas->drawRect(r, paint);
    }
}

class RegionView : public Sample {
public:
    RegionView() {
        fBase.set(100, 100, 150, 150);
        fRect = fBase;
        fRect.inset(5, 5);
        fRect.offset(25, 25);
        this->setBGColor(0xFFDDDDDD);
    }

    void build_base_rgn(SkRegion* rgn) {
        rgn->setRect(fBase);
        SkIRect r = fBase;
        r.offset(75, 20);
        rgn->op(r, SkRegion::kUnion_Op);
    }

    void build_rgn(SkRegion* rgn, SkRegion::Op op) {
        build_base_rgn(rgn);
        rgn->op(fRect, op);
    }


protected:
    bool onQuery(Sample::Event* evt) override {
        if (Sample::TitleQ(*evt)) {
            Sample::TitleR(evt, "Regions");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    static void drawstr(SkCanvas* canvas, const char text[], const SkPoint& loc,
                        bool hilite) {
        SkPaint paint;
        paint.setColor(hilite ? SK_ColorRED : 0x40FF0000);
        SkFont font;
        font.setSize(SkIntToScalar(20));
        canvas->drawSimpleText(text, strlen(text), kUTF8_SkTextEncoding, loc.fX, loc.fY, font, paint);
    }

    void drawPredicates(SkCanvas* canvas, const SkPoint pts[]) {
        SkRegion rgn;
        build_base_rgn(&rgn);

        drawstr(canvas, "Intersects", pts[0], rgn.intersects(fRect));
        drawstr(canvas, "Contains", pts[1], rgn.contains(fRect));
    }

    void drawOrig(SkCanvas* canvas, bool bg) {
        SkRect      r;
        SkPaint     paint;

        paint.setStyle(SkPaint::kStroke_Style);
        if (bg)
            paint.setColor(0xFFBBBBBB);

        SkRegion rgn;
        build_base_rgn(&rgn);
        paint_rgn(canvas, rgn, paint);

        r.set(fRect);
        canvas->drawRect(r, paint);
    }

    void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
        SkRegion    rgn;

        this->build_rgn(&rgn, op);

        {
            SkRegion tmp, tmp2(rgn);

            tmp = tmp2;
            tmp.translate(5, -3);

            {
                char    buffer[1000];
                SkDEBUGCODE(size_t  size = ) tmp.writeToMemory(nullptr);
                SkASSERT(size <= sizeof(buffer));
                SkDEBUGCODE(size_t  size2 = ) tmp.writeToMemory(buffer);
                SkASSERT(size == size2);

                SkRegion    tmp3;
                SkDEBUGCODE(size2 = ) tmp3.readFromMemory(buffer, 1000);
                SkASSERT(size == size2);

                SkASSERT(tmp3 == tmp);
            }

            rgn.translate(20, 30, &tmp);
            SkASSERT(rgn.isEmpty() || tmp != rgn);
            tmp.translate(-20, -30);
            SkASSERT(tmp == rgn);
        }

        this->drawOrig(canvas, true);

        SkPaint paint;
        paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24));
        paint_rgn(canvas, rgn, paint);

        paint.setStyle(SkPaint::kStroke_Style);
        paint.setColor(color);
        paint_rgn(canvas, rgn, paint);
    }

    void drawPathOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
        SkRegion    rgn;
        SkPath      path;

        this->build_rgn(&rgn, op);
        rgn.getBoundaryPath(&path);

        this->drawOrig(canvas, true);

        SkPaint paint;

        paint.setStyle(SkPaint::kFill_Style);
        paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24));
        canvas->drawPath(path, paint);
        paint.setColor(color);
        paint.setStyle(SkPaint::kStroke_Style);
        canvas->drawPath(path, paint);
    }

    void onDrawContent(SkCanvas* canvas) override {
        if (false) { // avoid bit rot, suppress warning
            test_strokerect(canvas);
            return;
        }
        if (false) { // avoid bit rot, suppress warning
            test_text(canvas);
            return;
        }

        const SkPoint origins[] = {
            { 30*SK_Scalar1, 50*SK_Scalar1 },
            { 150*SK_Scalar1, 50*SK_Scalar1 },
        };
        this->drawPredicates(canvas, origins);

        static const struct {
            SkColor         fColor;
            const char*     fName;
            SkRegion::Op    fOp;
        } gOps[] = {
            { SK_ColorBLACK,    "Difference",   SkRegion::kDifference_Op    },
            { SK_ColorRED,      "Intersect",    SkRegion::kIntersect_Op     },
            { 0xFF008800,       "Union",        SkRegion::kUnion_Op         },
            { SK_ColorBLUE,     "XOR",          SkRegion::kXOR_Op           }
        };

        SkFont font;
        font.setSize(SK_Scalar1*24);

        this->drawOrig(canvas, false);
        canvas->save();
            canvas->translate(SkIntToScalar(200), 0);
            this->drawRgnOped(canvas, SkRegion::kUnion_Op, SK_ColorBLACK);
        canvas->restore();

        canvas->translate(0, SkIntToScalar(200));

        for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
            canvas->drawSimpleText(gOps[op].fName, strlen(gOps[op].fName), kUTF8_SkTextEncoding,
                                   SkIntToScalar(75), SkIntToScalar(50), font, SkPaint());

            this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);

            canvas->save();
            canvas->translate(0, SkIntToScalar(200));
            this->drawPathOped(canvas, gOps[op].fOp, gOps[op].fColor);
            canvas->restore();

            canvas->translate(SkIntToScalar(200), 0);
        }
    }

    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                              unsigned modi) override {
        return fRect.contains(SkScalarRoundToInt(x),
                              SkScalarRoundToInt(y)) ? new Click(this) : nullptr;
    }

    bool onClick(Click* click) override {
        fRect.offset(click->fICurr.fX - click->fIPrev.fX,
                     click->fICurr.fY - click->fIPrev.fY);
        return true;
    }

private:
    SkIRect    fBase, fRect;

    typedef Sample INHERITED;
};

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

DEF_SAMPLE( return new RegionView(); )
