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

#include "SampleCode.h"
#include "SkCanvas.h"
#include "SkInterpolator.h"
#include "SkPath.h"
#include "SkRRect.h"
#include "SkTime.h"

// This slide tests out the match up between BW clipping and rendering. It can
// draw a large rect through some clip geometry and draw the same geometry
// normally. Which one is drawn first can be toggled. The pair of objects is translated
// fractionally (via an animator) to expose snapping bugs. The key bindings are:
//      1-9: the different geometries
//      t:   toggle which is drawn first the clip or the normal geometry
//      f:   flip-flops which corner the bottom AA clip rect occupies in the complex clip cases

// The possible geometric combinations to test
enum Geometry {
    kRect_Geometry,
    kRRect_Geometry,
    kCircle_Geometry,
    kConvexPath_Geometry,
    kConcavePath_Geometry,
    kRectAndRect_Geometry,
    kRectAndRRect_Geometry,
    kRectAndConvex_Geometry,
    kRectAndConcave_Geometry
};

// The basic rect used is [kMin,kMin]..[kMax,kMax]
static const float kMin = 100.5f;
static const float kMid = 200.0f;
static const float kMax = 299.5f;

// The translation applied to the base AA rect in the combination cases
// (i.e., kRectAndRect through kRectAndConcave)
static const float kXlate = 100.0f;

SkRect create_rect(const SkPoint& offset) {
    SkRect r = SkRect::MakeLTRB(kMin, kMin, kMax, kMax);
    r.offset(offset);
    return r;
}

SkRRect create_rrect(const SkPoint& offset) {
    SkRRect rrect;
    rrect.setRectXY(create_rect(offset), 10, 10);
    return rrect;
}

SkRRect create_circle(const SkPoint& offset) {
    SkRRect circle;
    circle.setOval(create_rect(offset));
    return circle;
}

SkPath create_convex_path(const SkPoint& offset) {
    SkPath convexPath;
    convexPath.moveTo(kMin, kMin);
    convexPath.lineTo(kMax, kMax);
    convexPath.lineTo(kMin, kMax);
    convexPath.close();
    convexPath.offset(offset.fX, offset.fY);
    return convexPath;
}

SkPath create_concave_path(const SkPoint& offset) {
    SkPath concavePath;
    concavePath.moveTo(kMin, kMin);
    concavePath.lineTo(kMid, 105.0f);
    concavePath.lineTo(kMax, kMin);
    concavePath.lineTo(295.0f, kMid);
    concavePath.lineTo(kMax, kMax);
    concavePath.lineTo(kMid, 295.0f);
    concavePath.lineTo(kMin, kMax);
    concavePath.lineTo(105.0f, kMid);
    concavePath.close();

    concavePath.offset(offset.fX, offset.fY);
    return concavePath;
}

static void draw_normal_geom(SkCanvas* canvas, const SkPoint& offset, int geom, bool useAA) {
    SkPaint p;
    p.setAntiAlias(useAA);
    p.setColor(SK_ColorBLACK);

    switch (geom) {
    case kRect_Geometry:                // fall thru
    case kRectAndRect_Geometry:
        canvas->drawRect(create_rect(offset), p);
        break;
    case kRRect_Geometry:               // fall thru
    case kRectAndRRect_Geometry:
        canvas->drawRRect(create_rrect(offset), p);
        break;
    case kCircle_Geometry:
        canvas->drawRRect(create_circle(offset), p);
        break;
    case kConvexPath_Geometry:          // fall thru
    case kRectAndConvex_Geometry:
        canvas->drawPath(create_convex_path(offset), p);
        break;
    case kConcavePath_Geometry:         // fall thru
    case kRectAndConcave_Geometry:
        canvas->drawPath(create_concave_path(offset), p);
        break;
    }
}

class ClipDrawMatchView : public SampleView {
public:
    ClipDrawMatchView() : fTrans(2, 5), fGeom(kRect_Geometry), fClipFirst(true), fSign(1) {
        SkScalar values[2];

        fTrans.setRepeatCount(999);
        values[0] = values[1] = 0;
        fTrans.setKeyFrame(0, GetMSecs() + 1000, values);
        values[1] = 1;
        fTrans.setKeyFrame(1, GetMSecs() + 2000, values);
        values[0] = values[1] = 1;
        fTrans.setKeyFrame(2, GetMSecs() + 3000, values);
        values[1] = 0;
        fTrans.setKeyFrame(3, GetMSecs() + 4000, values);
        values[0] = 0;
        fTrans.setKeyFrame(4, GetMSecs() + 5000, values);
    }

protected:
    bool onQuery(SkEvent* evt) override {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "ClipDrawMatch");
            return true;
        }
        SkUnichar uni;
        if (SampleCode::CharQ(*evt, &uni)) {
            switch (uni) {
                case '1': fGeom = kRect_Geometry; this->inval(nullptr); return true;
                case '2': fGeom = kRRect_Geometry; this->inval(nullptr); return true;
                case '3': fGeom = kCircle_Geometry; this->inval(nullptr); return true;
                case '4': fGeom = kConvexPath_Geometry; this->inval(nullptr); return true;
                case '5': fGeom = kConcavePath_Geometry; this->inval(nullptr); return true;
                case '6': fGeom = kRectAndRect_Geometry; this->inval(nullptr); return true;
                case '7': fGeom = kRectAndRRect_Geometry; this->inval(nullptr); return true;
                case '8': fGeom = kRectAndConvex_Geometry; this->inval(nullptr); return true;
                case '9': fGeom = kRectAndConcave_Geometry; this->inval(nullptr); return true;
                case 'f': fSign = -fSign; this->inval(nullptr); return true;
                case 't': fClipFirst = !fClipFirst; this->inval(nullptr); return true;
                default: break;
            }
        }
        return this->INHERITED::onQuery(evt);
    }

    void drawClippedGeom(SkCanvas* canvas, const SkPoint& offset, bool useAA) {

        int count = canvas->save();

        switch (fGeom) {
        case kRect_Geometry:
            canvas->clipRect(create_rect(offset), SkRegion::kReplace_Op, useAA);
            break;
        case kRRect_Geometry:
            canvas->clipRRect(create_rrect(offset), SkRegion::kReplace_Op, useAA);
            break;
        case kCircle_Geometry:
            canvas->clipRRect(create_circle(offset), SkRegion::kReplace_Op, useAA);
            break;
        case kConvexPath_Geometry:
            canvas->clipPath(create_convex_path(offset), SkRegion::kReplace_Op, useAA);
            break;
        case kConcavePath_Geometry:
            canvas->clipPath(create_concave_path(offset), SkRegion::kReplace_Op, useAA);
            break;
        case kRectAndRect_Geometry: {
            SkRect r = create_rect(offset);
            r.offset(fSign * kXlate, fSign * kXlate);
            canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces shader clips
            canvas->clipRect(create_rect(offset), SkRegion::kIntersect_Op, useAA);
            } break;
        case kRectAndRRect_Geometry: {
            SkRect r = create_rect(offset);
            r.offset(fSign * kXlate, fSign * kXlate);
            canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces shader clips
            canvas->clipRRect(create_rrect(offset), SkRegion::kIntersect_Op, useAA);
            } break;
        case kRectAndConvex_Geometry: {
            SkRect r = create_rect(offset);
            r.offset(fSign * kXlate, fSign * kXlate);
            canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces shader clips
            canvas->clipPath(create_convex_path(offset), SkRegion::kIntersect_Op, useAA);
            } break;
        case kRectAndConcave_Geometry: {
            SkRect r = create_rect(offset);
            r.offset(fSign * kXlate, fSign * kXlate);
            canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces shader clips
            canvas->clipPath(create_concave_path(offset), SkRegion::kIntersect_Op, useAA);
            } break;
        }

        SkISize size = canvas->getDeviceSize();
        SkRect bigR = SkRect::MakeWH(SkIntToScalar(size.width()), SkIntToScalar(size.height()));

        SkPaint p;
        p.setColor(SK_ColorRED);

        canvas->drawRect(bigR, p);
        canvas->restoreToCount(count);
    }

    // Draw a big red rect through some clip geometry and also draw that same
    // geometry in black. The order in which they are drawn can be swapped.
    // This tests whether the clip and normally drawn geometry match up.
    void drawGeometry(SkCanvas* canvas, const SkPoint& offset, bool useAA) {
        if (fClipFirst) {
            this->drawClippedGeom(canvas, offset, useAA);
        }

        draw_normal_geom(canvas, offset, fGeom, useAA);

        if (!fClipFirst) {
            this->drawClippedGeom(canvas, offset, useAA);
        }
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkScalar trans[2];
        fTrans.timeToValues(GetMSecs(), trans);

        SkPoint offset;
        offset.set(trans[0], trans[1]);

        int saveCount = canvas->save();
        this->drawGeometry(canvas, offset, false);
        canvas->restoreToCount(saveCount);

        this->inval(nullptr);
    }

    SkMSec GetMSecs() const {
        return static_cast<SkMSec>(SkTime::GetMSecs() - fStart);
    }

private:
    SkInterpolator  fTrans;
    Geometry        fGeom;
    bool            fClipFirst;
    int             fSign;
    const double    fStart = SkTime::GetMSecs();

    typedef SampleView INHERITED;
};

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

static SkView* MyFactory() { return new ClipDrawMatchView; }
static SkViewRegister reg(MyFactory);
