
/*
 * 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 "SkDevice.h"
#include "SkPaint.h"
#include "SkUnitMappers.h"
#include "SkCubicInterval.h"

#include "SkWidgetViews.h"

static SkStaticTextView* make_textview(SkView* parent,
                                       const SkRect& bounds,
                                       const SkPaint& paint) {
    SkStaticTextView* view = new SkStaticTextView;
    view->setMode(SkStaticTextView::kFixedSize_Mode);
    view->setPaint(paint);
    view->setVisibleP(true);
    view->setSize(bounds.width(), bounds.height());
    view->setLoc(bounds.fLeft, bounds.fTop);
    parent->attachChildToFront(view)->unref();
    return view;
}

static void set_scalar(SkStaticTextView* view, SkScalar value) {
    SkString str;
    str.appendScalar(value);
    view->setText(str);
}

class UnitMapperView : public SampleView {
    SkPoint fPts[4];
    SkMatrix fMatrix;
    SkStaticTextView* fViews[4];

    void setViews() {
        set_scalar(fViews[0], fPts[1].fX);
        set_scalar(fViews[1], fPts[1].fY);
        set_scalar(fViews[2], fPts[2].fX);
        set_scalar(fViews[3], fPts[2].fY);
    }

public:
    UnitMapperView() {
        fPts[0].set(0, 0);
        fPts[1].set(SK_Scalar1 / 3, SK_Scalar1 / 3);
        fPts[2].set(SK_Scalar1 * 2 / 3, SK_Scalar1 * 2 / 3);
        fPts[3].set(SK_Scalar1, SK_Scalar1);

        fMatrix.setScale(SK_Scalar1 * 200, -SK_Scalar1 * 200);
        fMatrix.postTranslate(SkIntToScalar(100), SkIntToScalar(300));

        SkRect r = {
            SkIntToScalar(350), SkIntToScalar(100),
            SkIntToScalar(500), SkIntToScalar(130)
        };
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setTextSize(SkIntToScalar(25));
        for (int i = 0; i < 4; i++) {
            fViews[i] = make_textview(this, r, paint);
            r.offset(0, r.height());
        }
        this->setViews();
    }

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

    virtual void onDrawContent(SkCanvas* canvas) {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setColor(0xFF8888FF);

        SkRect r = { 0, 0, SK_Scalar1, SK_Scalar1 };

        canvas->concat(fMatrix);
        canvas->drawRect(r, paint);

        paint.setColor(SK_ColorBLACK);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(0);
        paint.setStrokeCap(SkPaint::kRound_Cap);

        SkPath path;
        path.moveTo(fPts[0]);
        path.cubicTo(fPts[1], fPts[2], fPts[3]);
        canvas->drawPath(path, paint);

        paint.setColor(SK_ColorRED);
        paint.setStrokeWidth(0);
        canvas->drawLine(0, 0, SK_Scalar1, SK_Scalar1, paint);

        paint.setColor(SK_ColorBLUE);
        paint.setStrokeWidth(SK_Scalar1 / 60);
        for (int i = 0; i < 50; i++) {
            SkScalar x = i * SK_Scalar1 / 49;
            canvas->drawPoint(x, SkEvalCubicInterval(&fPts[1], x), paint);
        }

        paint.setStrokeWidth(SK_Scalar1 / 20);
        paint.setColor(SK_ColorGREEN);
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, &fPts[1], paint);
    }

    bool invertPt(SkScalar x, SkScalar y, SkPoint* result) {
        if (NULL == result)
            return true;

        SkMatrix m;
        if (!fMatrix.invert(&m)) {
            return false;
        }

        m.mapXY(x, y, result);
        return true;
    }

    int hittest(SkScalar x, SkScalar y) {
        SkPoint target = { x, y };
        SkPoint pts[2] = { fPts[1], fPts[2] };
        fMatrix.mapPoints(pts, 2);
        for (int i = 0; i < 2; i++) {
            if (SkPoint::Distance(pts[i], target) < SkIntToScalar(4)) {
                return i + 1;
            }
        }
        return -1;
    }

    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) SK_OVERRIDE {
        fDragIndex = hittest(x, y);
        return fDragIndex >= 0 ? new Click(this) : NULL;
    }

    virtual bool onClick(Click* click) {
        if (fDragIndex >= 0) {
            if (!invertPt(click->fCurr.fX, click->fCurr.fY,
                          &fPts[fDragIndex])) {
                return false;
            }

            this->setViews();
            this->inval(NULL);
            return true;
        }
        return false;
    }

private:
    int fDragIndex;

    typedef SampleView INHERITED;
};

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

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