
/*
 * 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 "SkCanvas.h"
#include "SkPaint.h"
#include "SkView.h"
#include "SkLayer.h"

#include "SkMatrix44.h"
static void test_inv(const char label[], const SkMatrix44& mat) {
    SkDebugf("%s\n", label);
    mat.dump();

    SkMatrix44 inv;
    if (mat.invert(&inv)) {
        inv.dump();
    } else {
        SkDebugf("--- invert failed\n");
    }

    SkMatrix44 a, b;
    a.setConcat(mat, inv);
    b.setConcat(inv, mat);
    SkDebugf("concat mat with inverse pre=%d post=%d\n", a.isIdentity(), b.isIdentity());
    if (!a.isIdentity()) {
        a.dump();
    }
    if (!b.isIdentity()) {
        b.dump();
    }
    SkDebugf("\n");
}

static void test_map(SkScalar x0, SkScalar y0, SkScalar z0,
                     const SkMatrix44& mat,
                     SkScalar x1, SkScalar y1, SkScalar z1) {
    SkVector4 src, dst;
    src.set(x0, y0, z0);
    dst = mat * src;
    SkDebugf("map: src: %g %g %g dst: %g %g %g (%g) expected: %g %g %g match: %d\n",
             x0, y0, z0,
             dst.fData[0], dst.fData[1], dst.fData[2], dst.fData[3],
             x1, y1, z1,
             dst.fData[0] == x1 && dst.fData[1] == y1 && dst.fData[2] == z1);
}

static void test_33(const SkMatrix44& mat,
                    SkScalar x0, SkScalar x1, SkScalar x2,
                    SkScalar y0, SkScalar y1, SkScalar y2) {
    SkMatrix dst = mat;
    if (dst[0] != x0 || dst[1] != x1 || dst[2] != x2 ||
        dst[3] != y0 || dst[4] != y1 || dst[5] != y2) {
        SkString str;
        dst.toString(&str);
        SkDebugf("3x3: expected 3x3 [%g %g %g] [%g %g %g] bug got %s\n",
                 x0, x1, x2, y0, y1, y2, str.c_str());
    }
}

static void test44() {
    SkMatrix44 m0, m1, m2;

    test_inv("identity", m0);
    m0.setTranslate(2,3,4);
    test_inv("translate", m0);
    m0.setScale(2,3,4);
    test_inv("scale", m0);
    m0.postTranslate(5, 6, 7);
    test_inv("postTranslate", m0);
    m0.setScale(2,3,4);
    m1.setTranslate(5, 6, 7);
    m0.setConcat(m0, m1);
    test_inv("postTranslate2", m0);
    m0.setScale(2,3,4);
    m0.preTranslate(5, 6, 7);
    test_inv("preTranslate", m0);

    m0.setScale(2, 4, 6);
    m0.postScale(SkDoubleToMScalar(0.5));
    test_inv("scale/postscale to 1,2,3", m0);

    m0.reset();
    test_map(1, 0, 0, m0, 1, 0, 0);
    test_map(0, 1, 0, m0, 0, 1, 0);
    test_map(0, 0, 1, m0, 0, 0, 1);
    m0.setScale(2, 3, 4);
    test_map(1, 0, 0, m0, 2, 0, 0);
    test_map(0, 1, 0, m0, 0, 3, 0);
    test_map(0, 0, 1, m0, 0, 0, 4);
    m0.setTranslate(2, 3, 4);
    test_map(0, 0, 0, m0, 2, 3, 4);
    m0.preScale(5, 6, 7);
    test_map(1, 0, 0, m0, 7, 3, 4);
    test_map(0, 1, 0, m0, 2, 9, 4);
    test_map(0, 0, 1, m0, 2, 3, 11);

    SkMScalar deg = 45;
    m0.setRotateDegreesAbout(0, 0, 1, deg);
    test_map(1, 0, 0, m0, 0.707106769, -0.707106769, 0);

    m0.reset();
    test_33(m0, 1, 0, 0, 0, 1, 0);
    m0.setTranslate(3, 4, 5);
    test_33(m0, 1, 0, 3, 0, 1, 4);
}

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

static void dump_layers(const SkLayer* layer, int tab = 0) {
    SkMatrix matrix;
    SkString matrixStr;

    layer->getLocalTransform(&matrix);
    matrix.toString(&matrixStr);

    for (int j = 0; j < tab; j++) {
        SkDebugf(" ");
    }
    SkDebugf("layer=%p parent=%p size=[%g %g] transform=%s\n",
             layer, layer->getParent(), layer->getWidth(), layer->getHeight(),
             matrixStr.c_str());
    for (int i = 0; i < layer->countChildren(); i++) {
        dump_layers(layer->getChild(i), tab + 4);
    }
}

class TestLayer : public SkLayer {
public:
    TestLayer(SkColor c) : fColor(c) {}

protected:
    virtual void onDraw(SkCanvas* canvas, SkScalar opacity) {
        SkRect r;
        r.set(0, 0, this->getWidth(), this->getHeight());

        SkPaint paint;
        paint.setColor(fColor);
        paint.setAlpha(SkScalarRound(opacity * 255));

        canvas->drawRect(r, paint);
    }

private:
    SkColor fColor;
};

class SkLayerView : public SkView {
private:
    SkLayer* fRootLayer;
    SkLayer* fLastChild;
public:
    SkLayerView() {
        test44();
        static const int W = 600;
        static const int H = 440;
        static const struct {
            int fWidth;
            int fHeight;
            SkColor fColor;
            int fPosX;
            int fPosY;
        } gData[] = {
            { 120, 80, SK_ColorRED, 0, 0 },
            { 120, 80, SK_ColorGREEN, W - 120, 0 },
            { 120, 80, SK_ColorBLUE, 0, H - 80 },
            { 120, 80, SK_ColorMAGENTA, W - 120, H - 80 },
        };

        fRootLayer = new TestLayer(0xFFDDDDDD);
        fRootLayer->setSize(W, H);
        for (size_t i = 0; i < SK_ARRAY_COUNT(gData); i++) {
            SkLayer* child = new TestLayer(gData[i].fColor);
            child->setSize(gData[i].fWidth, gData[i].fHeight);
            child->setPosition(gData[i].fPosX, gData[i].fPosY);
            fRootLayer->addChild(child)->unref();
        }

        SkLayer* child = new TestLayer(0xFFDD8844);
        child->setSize(120, 80);
        child->setPosition(fRootLayer->getWidth()/2 - child->getWidth()/2,
                           fRootLayer->getHeight()/2 - child->getHeight()/2);
        child->setAnchorPoint(SK_ScalarHalf, SK_ScalarHalf);
        {
            SkMatrix m;
            m.setRotate(SkIntToScalar(30));
            child->setMatrix(m);
        }
        fLastChild = child;
        fRootLayer->addChild(child)->unref();

        if (false) {
            SkMatrix matrix;
            matrix.setScale(0.5, 0.5);
            fRootLayer->setMatrix(matrix);
        }

//        dump_layers(fRootLayer);
    }

    virtual ~SkLayerView() {
        SkSafeUnref(fRootLayer);
    }

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

    virtual void onDraw(SkCanvas* canvas) {
        canvas->drawColor(SK_ColorWHITE);

        canvas->translate(20, 20);
        fRootLayer->draw(canvas);

        // visual test of getLocalTransform
        if (true) {
            SkMatrix matrix;
            fLastChild->localToGlobal(&matrix);
            SkPaint paint;
            paint.setStyle(SkPaint::kStroke_Style);
            paint.setStrokeWidth(5);
            paint.setColor(0x88FF0000);
            canvas->concat(matrix);
            canvas->drawRect(SkRect::MakeSize(fLastChild->getSize()), paint);
        }
    }

private:
    typedef SkView INHERITED;
};

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

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