
/*
 * 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 "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkImageDecoder.h"

#include "SkBlurMaskFilter.h"
#include "SkTableMaskFilter.h"

#define kNearlyZero     (SK_Scalar1 / 8092)

static void test_bigblur(SkCanvas* canvas) {
    canvas->drawColor(SK_ColorBLACK);

    SkBitmap orig, mask;
    SkImageDecoder::DecodeFile("/skimages/app_icon.png", &orig);

    SkMaskFilter* mf = SkBlurMaskFilter::Create(8, SkBlurMaskFilter::kNormal_BlurStyle);
    SkPaint paint;
    paint.setMaskFilter(mf)->unref();
    SkIPoint offset;
    orig.extractAlpha(&mask, &paint, &offset);

    paint.setColor(0xFFBB8800);
    paint.setColor(SK_ColorWHITE);

    int i;
    canvas->save();
    float gamma = 0.8;
    for (i = 0; i < 5; i++) {
        paint.setMaskFilter(SkTableMaskFilter::CreateGamma(gamma))->unref();
        canvas->drawBitmap(mask, 0, 0, &paint);
        paint.setMaskFilter(NULL);
        canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
        gamma -= 0.1;
        canvas->translate(120, 0);
    }
    canvas->restore();
    canvas->translate(0, 160);

    for (i = 0; i < 5; i++) {
        paint.setMaskFilter(SkTableMaskFilter::CreateClip(i*30, 255 - 20))->unref();
        canvas->drawBitmap(mask, 0, 0, &paint);
        paint.setMaskFilter(NULL);
        canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
        canvas->translate(120, 0);
    }

#if 0
    paint.setColor(0xFFFFFFFF);
    canvas->drawBitmap(mask, 0, 0, &paint);
    paint.setMaskFilter(NULL);
    canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);

    canvas->translate(120, 0);

    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);

    canvas->translate(120, 0);

    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);

    canvas->translate(120, 0);

    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);

    canvas->translate(120, 0);

    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(mask, 0, 0, &paint);
    canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
#endif
}

#include "SkMeshUtils.h"

static SkPoint SkMakePoint(SkScalar x, SkScalar y) {
    SkPoint pt;
    pt.set(x, y);
    return pt;
}

static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
    return SkMakePoint(SkScalarInterp(a.fX, b.fX, t),
                       SkScalarInterp(a.fY, b.fY, t));
}

#include "SkBoundaryPatch.h"

static void set_cubic(SkPoint pts[4], SkScalar x0, SkScalar y0,
                      SkScalar x3, SkScalar y3, SkScalar scale = 1) {
    SkPoint tmp, tmp2;

    pts[0].set(x0, y0);
    pts[3].set(x3, y3);

    tmp = SkPointInterp(pts[0], pts[3], SK_Scalar1/3);
    tmp2 = pts[0] - tmp;
    tmp2.rotateCW();
    tmp2.scale(scale);
    pts[1] = tmp + tmp2;

    tmp = SkPointInterp(pts[0], pts[3], 2*SK_Scalar1/3);
    tmp2 = pts[3] - tmp;
    tmp2.rotateCW();
    tmp2.scale(scale);
    pts[2] = tmp + tmp2;
}

static void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale) {
    SkCubicBoundary cubic;
    set_cubic(cubic.fPts + 0, 0, 0, 100, 0, scale);
    set_cubic(cubic.fPts + 3, 100, 0, 100, 100, scale);
    set_cubic(cubic.fPts + 6, 100, 100,  0, 100, -scale);
    set_cubic(cubic.fPts + 9, 0, 100, 0, 0, 0);

    SkBoundaryPatch patch;
    patch.setBoundary(&cubic);

    const int Rows = 16;
    const int Cols = 16;
    SkPoint pts[Rows * Cols];
    patch.evalPatch(pts, Rows, Cols);

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setFilterBitmap(true);
    paint.setStrokeWidth(1);
    paint.setStrokeCap(SkPaint::kRound_Cap);

    canvas->translate(50, 50);
    canvas->scale(3, 3);

    SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
}

static void test_drag(SkCanvas* canvas, const SkBitmap& bm,
                      const SkPoint& p0, const SkPoint& p1) {
    SkCubicBoundary cubic;
    set_cubic(cubic.fPts + 0, 0, 0, 100, 0, 0);
    set_cubic(cubic.fPts + 3, 100, 0, 100, 100, 0);
    set_cubic(cubic.fPts + 6, 100, 100,  0, 100, 0);
    set_cubic(cubic.fPts + 9, 0, 100, 0, 0, 0);

#if 0
    cubic.fPts[1] += p1 - p0;
    cubic.fPts[2] += p1 - p0;
#else
    SkScalar dx = p1.fX - p0.fX;
    if (dx > 0) dx = 0;
    SkScalar dy = p1.fY - p0.fY;
    if (dy > 0) dy = 0;

    cubic.fPts[1].fY += dy;
    cubic.fPts[2].fY += dy;
    cubic.fPts[10].fX += dx;
    cubic.fPts[11].fX += dx;
#endif

    SkBoundaryPatch patch;
    patch.setBoundary(&cubic);

    const int Rows = 16;
    const int Cols = 16;
    SkPoint pts[Rows * Cols];
    patch.evalPatch(pts, Rows, Cols);

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setFilterBitmap(true);
    paint.setStrokeWidth(1);
    paint.setStrokeCap(SkPaint::kRound_Cap);

    canvas->translate(50, 50);
    canvas->scale(3, 3);

    SkAutoCanvasRestore acr(canvas, true);

    SkRect r = { 0, 0, 100, 100 };
    canvas->clipRect(r);
    SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
}

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

class Mesh {
public:
    Mesh();
    ~Mesh();

    Mesh& operator=(const Mesh& src);

    void init(const SkRect& bounds, int rows, int cols,
              const SkRect& texture);

    const SkRect& bounds() const { return fBounds; }

    int rows() const { return fRows; }
    int cols() const { return fCols; }
    SkPoint& pt(int row, int col) {
        return fPts[row * (fRows + 1) + col];
    }

    void draw(SkCanvas*, const SkPaint&);
    void drawWireframe(SkCanvas* canvas, const SkPaint& paint);

private:
    SkRect      fBounds;
    int         fRows, fCols;
    SkPoint*    fPts;
    SkPoint*    fTex;   // just points into fPts, not separately allocated
    int         fCount;
    uint16_t*   fIndices;
    int         fIndexCount;
};

Mesh::Mesh() : fPts(NULL), fCount(0), fIndices(NULL), fIndexCount(0) {}

Mesh::~Mesh() {
    delete[] fPts;
    delete[] fIndices;
}

Mesh& Mesh::operator=(const Mesh& src) {
    delete[] fPts;
    delete[] fIndices;

    fBounds = src.fBounds;
    fRows = src.fRows;
    fCols = src.fCols;

    fCount = src.fCount;
    fPts = new SkPoint[fCount * 2];
    fTex = fPts + fCount;
    memcpy(fPts, src.fPts, fCount * 2 * sizeof(SkPoint));

    delete[] fIndices;
    fIndexCount = src.fIndexCount;
    fIndices = new uint16_t[fIndexCount];
    memcpy(fIndices, src.fIndices, fIndexCount * sizeof(uint16_t));

    return *this;
}

void Mesh::init(const SkRect& bounds, int rows, int cols,
                const SkRect& texture) {
    SkASSERT(rows > 0 && cols > 0);

    fBounds = bounds;
    fRows = rows;
    fCols = cols;

    delete[] fPts;
    fCount = (rows + 1) * (cols + 1);
    fPts = new SkPoint[fCount * 2];
    fTex = fPts + fCount;

    delete[] fIndices;
    fIndexCount = rows * cols * 6;
    fIndices = new uint16_t[fIndexCount];

    SkPoint* pts = fPts;
    const SkScalar dx = bounds.width() / rows;
    const SkScalar dy = bounds.height() / cols;
    SkPoint* tex = fTex;
    const SkScalar dtx = texture.width() / rows;
    const SkScalar dty = texture.height() / cols;
    uint16_t* idx = fIndices;
    int index = 0;
    for (int y = 0; y <= cols; y++) {
        for (int x = 0; x <= rows; x++) {
            pts->set(bounds.fLeft + x*dx, bounds.fTop + y*dy);
            pts += 1;
            tex->set(texture.fLeft + x*dtx, texture.fTop + y*dty);
            tex += 1;

            if (y < cols && x < rows) {
                *idx++ = index;
                *idx++ = index + rows + 1;
                *idx++ = index + 1;

                *idx++ = index + 1;
                *idx++ = index + rows + 1;
                *idx++ = index + rows + 2;

                index += 1;
            }
        }
        index += 1;
    }
}

void Mesh::draw(SkCanvas* canvas, const SkPaint& paint) {
    canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
                         fPts, fTex, NULL, NULL, fIndices, fIndexCount,
                         paint);
}

void Mesh::drawWireframe(SkCanvas* canvas, const SkPaint& paint) {
    canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
                         fPts, NULL, NULL, NULL, fIndices, fIndexCount,
                         paint);
}

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

class WarpView : public SkView {
    Mesh        fMesh, fOrig;
    SkBitmap    fBitmap;
    SkMatrix    fMatrix, fInverse;
public:
    WarpView() {
        SkBitmap bm;
//        SkImageDecoder::DecodeFile("/skimages/marker.png", &bm);
        SkImageDecoder::DecodeFile("/skimages/logo.gif", &bm);
   //     SkImageDecoder::DecodeFile("/beach_shot.JPG", &bm);
        fBitmap = bm;

        SkRect bounds, texture;
        texture.set(0, 0, SkIntToScalar(fBitmap.width()),
                    SkIntToScalar(fBitmap.height()));
        bounds = texture;

//        fMesh.init(bounds, fBitmap.width() / 40, fBitmap.height() / 40, texture);
        fMesh.init(bounds, fBitmap.width()/16, fBitmap.height()/16, texture);
        fOrig = fMesh;

        fP0.set(0, 0);
        fP1 = fP0;

        fMatrix.setScale(2, 2);
        fMatrix.invert(&fInverse);
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Warp");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    static SkPoint apply_warp(const SkVector& drag, SkScalar dragLength,
                              const SkPoint& dragStart, const SkPoint& dragCurr,
                              const SkPoint& orig) {
        SkVector delta = orig - dragCurr;
        SkScalar length = SkPoint::Normalize(&delta);
        if (length <= kNearlyZero) {
            return orig;
        }

        const SkScalar period = 20;
        const SkScalar mag = dragLength / 3;

        SkScalar d = length / (period);
        d = mag * SkScalarSin(d) / d;
        SkScalar dx = delta.fX * d;
        SkScalar dy = delta.fY * d;
        SkScalar px = orig.fX + dx;
        SkScalar py = orig.fY + dy;
        return SkPoint::Make(px, py);
    }

    static SkPoint apply_warp2(const SkVector& drag, SkScalar dragLength,
                              const SkPoint& dragStart, const SkPoint& dragCurr,
                              const SkPoint& orig) {
        SkVector delta = orig - dragCurr;
        SkScalar length = SkPoint::Normalize(&delta);
        if (length <= kNearlyZero) {
            return orig;
        }

        const SkScalar period = 10 + dragLength/4;
        const SkScalar mag = dragLength / 3;

        SkScalar d = length / (period);
        if (d > SK_ScalarPI) {
            d = SK_ScalarPI;
        }

        d = -mag * SkScalarSin(d);

        SkScalar dx = delta.fX * d;
        SkScalar dy = delta.fY * d;
        SkScalar px = orig.fX + dx;
        SkScalar py = orig.fY + dy;
        return SkPoint::Make(px, py);
    }

    typedef SkPoint (*WarpProc)(const SkVector& drag, SkScalar dragLength,
                             const SkPoint& dragStart, const SkPoint& dragCurr,
                             const SkPoint& orig);

    void warp(const SkPoint& p0, const SkPoint& p1) {
        WarpProc proc = apply_warp2;
        SkPoint delta = p1 - p0;
        SkScalar length = SkPoint::Normalize(&delta);
        for (int y = 0; y < fMesh.rows(); y++) {
            for (int x = 0; x < fMesh.cols(); x++) {
                fMesh.pt(x, y) = proc(delta, length, p0, p1, fOrig.pt(x, y));
            }
        }
        fP0 = p0;
        fP1 = p1;
    }

    virtual void onDraw(SkCanvas* canvas) {
        canvas->drawColor(SK_ColorLTGRAY);
     //   test_bigblur(canvas); return;

        canvas->concat(fMatrix);

        SkPaint paint;
        paint.setFilterBitmap(true);
        paint.setShader(SkShader::CreateBitmapShader(fBitmap,
                                                     SkShader::kClamp_TileMode,
                                                     SkShader::kClamp_TileMode))->unref();
        fMesh.draw(canvas, paint); //return;

        paint.setShader(NULL);
        paint.setColor(SK_ColorRED);
        fMesh.draw(canvas, paint);

    //    test_drag(canvas, fBitmap, fP0, fP1);
    }

    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
        return new Click(this);
    }

    virtual bool onClick(Click* click) {
        SkPoint pts[2] = { click->fOrig, click->fCurr };
        fInverse.mapPoints(pts, 2);
        this->warp(pts[0], pts[1]);
        this->inval(NULL);
        return true;
    }

private:
    SkIRect    fBase, fRect;
    SkPoint     fP0, fP1;
    typedef SkView INHERITED;
};

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

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