
/*
 * 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);

