
/*
 * 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"

#include "SkBitmap.h"
#include "SkGradientShader.h"
#include "SkTLList.h"

static SkBitmap make_bmp(int w, int h) {
    SkBitmap bmp;
    bmp.allocN32Pixels(w, h, true);

    SkCanvas canvas(bmp);
    SkScalar wScalar = SkIntToScalar(w);
    SkScalar hScalar = SkIntToScalar(h);

    SkPoint     pt = { wScalar / 2, hScalar / 2 };

    SkScalar    radius = 3 * SkMaxScalar(wScalar, hScalar);

    SkColor     colors[] = { SK_ColorDKGRAY, 0xFF222255,
                             0xFF331133, 0xFF884422,
                             0xFF000022, SK_ColorWHITE,
                             0xFFAABBCC};

    SkScalar    pos[] = {0,
                         SK_Scalar1 / 6,
                         2 * SK_Scalar1 / 6,
                         3 * SK_Scalar1 / 6,
                         4 * SK_Scalar1 / 6,
                         5 * SK_Scalar1 / 6,
                         SK_Scalar1};

    SkPaint paint;
    SkRect rect = SkRect::MakeWH(wScalar, hScalar);
    SkMatrix mat = SkMatrix::I();
    for (int i = 0; i < 4; ++i) {
        paint.setShader(SkGradientShader::CreateRadial(
                        pt, radius,
                        colors, pos,
                        SK_ARRAY_COUNT(colors),
                        SkShader::kRepeat_TileMode,
                        0, &mat))->unref();
        canvas.drawRect(rect, paint);
        rect.inset(wScalar / 8, hScalar / 8);
        mat.preTranslate(6 * wScalar, 6 * hScalar);
        mat.postScale(SK_Scalar1 / 3, SK_Scalar1 / 3);
    }

    paint.setAntiAlias(true);
    sk_tool_utils::set_portable_typeface(&paint);
    paint.setTextSize(wScalar / 2.2f);
    paint.setShader(0);
    paint.setColor(SK_ColorLTGRAY);
    static const char kTxt[] = "Skia";
    SkPoint texPos = { wScalar / 17, hScalar / 2 + paint.getTextSize() / 2.5f };
    canvas.drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1, texPos.fX, texPos.fY, paint);
    paint.setColor(SK_ColorBLACK);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(SK_Scalar1);
    canvas.drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1, texPos.fX, texPos.fY, paint);
    return bmp;
}

namespace skiagm {
/**
 * This GM tests convex polygon clips.
 */
class ConvexPolyClip : public GM {
public:
    ConvexPolyClip() {
        this->setBGColor(0xFFFFFFFF);
    }

protected:
    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("convex_poly_clip");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        // When benchmarking the saveLayer set of draws is skipped.
        int w = 435;
        if (kBench_Mode != this->getMode()) {
            w *= 2;
        }
        return SkISize::Make(w, 540);
    }

    virtual void onOnceBeforeDraw() SK_OVERRIDE {
        SkPath tri;
        tri.moveTo(5.f, 5.f);
        tri.lineTo(100.f, 20.f);
        tri.lineTo(15.f, 100.f);

        fClips.addToTail()->setPath(tri);

        SkPath hexagon;
        static const SkScalar kRadius = 45.f;
        const SkPoint center = { kRadius, kRadius };
        for (int i = 0; i < 6; ++i) {
            SkScalar angle = 2 * SK_ScalarPI * i / 6;
            SkPoint point;
            point.fY = SkScalarSinCos(angle, &point.fX);
            point.scale(kRadius);
            point = center + point;
            if (0 == i) {
                hexagon.moveTo(point);
            } else {
                hexagon.lineTo(point);
            }
        }
        fClips.addToTail()->setPath(hexagon);

        SkMatrix scaleM;
        scaleM.setScale(1.1f, 0.4f, kRadius, kRadius);
        hexagon.transform(scaleM);
        fClips.addToTail()->setPath(hexagon);

        fClips.addToTail()->setRect(SkRect::MakeXYWH(8.3f, 11.6f, 78.2f, 72.6f));

        SkPath rotRect;
        SkRect rect = SkRect::MakeLTRB(10.f, 12.f, 80.f, 86.f);
        rotRect.addRect(rect);
        SkMatrix rotM;
        rotM.setRotate(23.f, rect.centerX(), rect.centerY());
        rotRect.transform(rotM);
        fClips.addToTail()->setPath(rotRect);

        fBmp = make_bmp(100, 100);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkScalar y = 0;
        static const SkScalar kMargin = 10.f;

        SkPaint bgPaint;
        bgPaint.setAlpha(0x15);
        SkISize size = canvas->getDeviceSize();
        SkRect dstRect = SkRect::MakeWH(SkIntToScalar(size.fWidth),
                                        SkIntToScalar(size.fHeight));
        canvas->drawBitmapRectToRect(fBmp, NULL, dstRect, &bgPaint);

        static const char kTxt[] = "Clip Me!";
        SkPaint txtPaint;
        txtPaint.setTextSize(23.f);
        txtPaint.setAntiAlias(true);
        sk_tool_utils::set_portable_typeface(&txtPaint);
        txtPaint.setColor(SK_ColorDKGRAY);
        SkScalar textW = txtPaint.measureText(kTxt, SK_ARRAY_COUNT(kTxt)-1);

        SkScalar startX = 0;
        int testLayers = kBench_Mode != this->getMode();
        for (int doLayer = 0; doLayer <= testLayers; ++doLayer) {
            for (SkTLList<Clip>::Iter iter(fClips, SkTLList<Clip>::Iter::kHead_IterStart);
                 iter.get();
                 iter.next()) {
                const Clip* clip = iter.get();
                SkScalar x = startX;
                for (int aa = 0; aa < 2; ++aa) {
                    if (doLayer) {
                        SkRect bounds;
                        clip->getBounds(&bounds);
                        bounds.outset(2, 2);
                        bounds.offset(x, y);
                        canvas->saveLayer(&bounds, NULL);
                    } else {
                        canvas->save();
                    }
                    canvas->translate(x, y);
                    clip->setOnCanvas(canvas, SkRegion::kIntersect_Op, SkToBool(aa));
                    canvas->drawBitmap(fBmp, 0, 0);
                    canvas->restore();
                    x += fBmp.width() + kMargin;
                }
                for (int aa = 0; aa < 2; ++aa) {

                    SkPaint clipOutlinePaint;
                    clipOutlinePaint.setAntiAlias(true);
                    clipOutlinePaint.setColor(0x50505050);
                    clipOutlinePaint.setStyle(SkPaint::kStroke_Style);
                    clipOutlinePaint.setStrokeWidth(0);

                    if (doLayer) {
                        SkRect bounds;
                        clip->getBounds(&bounds);
                        bounds.outset(2, 2);
                        bounds.offset(x, y);
                        canvas->saveLayer(&bounds, NULL);
                    } else {
                        canvas->save();
                    }
                    canvas->translate(x, y);
                    SkPath closedClipPath;
                    clip->asClosedPath(&closedClipPath);
                    canvas->drawPath(closedClipPath, clipOutlinePaint);
                    clip->setOnCanvas(canvas, SkRegion::kIntersect_Op, SkToBool(aa));
                    canvas->scale(1.f, 1.8f);
                    canvas->drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1,
                                     0, 1.5f * txtPaint.getTextSize(),
                                     txtPaint);
                    canvas->restore();
                    x += textW + 2 * kMargin;
                }
                y += fBmp.height() + kMargin;
            }
            y = 0;
            startX += 2 * fBmp.width() + SkScalarCeilToInt(2 * textW) + 6 * kMargin;
        }
    }

    virtual uint32_t onGetFlags() const {
        return kAsBench_Flag | kSkipTiled_Flag;
    }

private:
    class Clip {
    public:
        enum ClipType {
            kNone_ClipType,
            kPath_ClipType,
            kRect_ClipType
        };

        Clip () : fClipType(kNone_ClipType) {}

        void setOnCanvas(SkCanvas* canvas, SkRegion::Op op, bool aa) const {
            switch (fClipType) {
                case kPath_ClipType:
                    canvas->clipPath(fPath, op, aa);
                    break;
                case kRect_ClipType:
                    canvas->clipRect(fRect, op, aa);
                    break;
                case kNone_ClipType:
                    SkDEBUGFAIL("Uninitialized Clip.");
                    break;
            }
        }

        void asClosedPath(SkPath* path) const {
            switch (fClipType) {
                case kPath_ClipType:
                    *path = fPath;
                    path->close();
                    break;
                case kRect_ClipType:
                    path->reset();
                    path->addRect(fRect);
                    break;
                case kNone_ClipType:
                    SkDEBUGFAIL("Uninitialized Clip.");
                    break;
            }
        }

        void setPath(const SkPath& path) {
            fClipType = kPath_ClipType;
            fPath = path;
        }

        void setRect(const SkRect& rect) {
            fClipType = kRect_ClipType;
            fRect = rect;
            fPath.reset();
        }

        ClipType getType() const { return fClipType; }

        void getBounds(SkRect* bounds) const {
            switch (fClipType) {
                case kPath_ClipType:
                    *bounds = fPath.getBounds();
                    break;
                case kRect_ClipType:
                    *bounds = fRect;
                    break;
                case kNone_ClipType:
                    SkDEBUGFAIL("Uninitialized Clip.");
                    break;
            }
        }

    private:
        ClipType fClipType;
        SkPath fPath;
        SkRect fRect;
    };

    SkTLList<Clip>   fClips;
    SkBitmap         fBmp;

    typedef GM INHERITED;
};

DEF_GM( return SkNEW(ConvexPolyClip); )

}
