
/*
 * 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"

// ensure that we don't accidentally screw up the bounds when the oval is
// fractional, and the impl computes the center and radii, and uses them to
// reconstruct the edges of the circle.
// see bug# 1504910
static void test_circlebounds(SkCanvas*) {
    SkRect r = { 1.39999998f, 1, 21.3999996f, 21 };
    SkPath p;
    p.addOval(r);
    SkASSERT(r == p.getBounds());
}

class CircleView : public SampleView {
public:
    static const SkScalar ANIM_DX;
    static const SkScalar ANIM_DY;
    static const SkScalar ANIM_RAD;
    SkScalar fDX, fDY, fRAD;

    CircleView() {
        fDX = fDY = fRAD = 0;
        fN = 3;
    }

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

    void circle(SkCanvas* canvas, int width, bool aa) {
        SkPaint paint;

        paint.setAntiAlias(aa);
        if (width < 0) {
            paint.setStyle(SkPaint::kFill_Style);
        } else {
            paint.setStyle(SkPaint::kStroke_Style);
            paint.setStrokeWidth(SkIntToScalar(width));
        }
        canvas->drawCircle(0, 0, SkIntToScalar(9) + fRAD, paint);
        if (false) { // avoid bit rot, suppress warning
            test_circlebounds(canvas);
        }
    }

    void drawSix(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
        for (int width = -1; width <= 1; width++) {
            canvas->save();
            circle(canvas, width, false);
            canvas->translate(0, dy);
            circle(canvas, width, true);
            canvas->restore();
            canvas->translate(dx, 0);
        }
    }

    static void make_poly(SkPath* path, int n) {
        if (n <= 0) {
            return;
        }
        path->incReserve(n + 1);
        path->moveTo(SK_Scalar1, 0);
        SkScalar step = SK_ScalarPI * 2 / n;
        SkScalar angle = 0;
        for (int i = 1; i < n; i++) {
            angle += step;
            SkScalar c, s = SkScalarSinCos(angle, &c);
            path->lineTo(c, s);
        }
        path->close();
    }

    static void rotate(SkCanvas* canvas, SkScalar angle, SkScalar px, SkScalar py) {
        canvas->translate(-px, -py);
        canvas->rotate(angle);
        canvas->translate(px, py);
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
//        canvas->drawCircle(250, 250, 220, paint);
        SkMatrix matrix;
        matrix.setScale(SkIntToScalar(100), SkIntToScalar(100));
        matrix.postTranslate(SkIntToScalar(200), SkIntToScalar(200));
        canvas->concat(matrix);
        for (int n = 3; n < 20; n++) {
            SkPath path;
            make_poly(&path, n);
            SkAutoCanvasRestore acr(canvas, true);
            canvas->rotate(SkIntToScalar(10) * (n - 3));
            canvas->translate(-SK_Scalar1, 0);
            canvas->drawPath(path, paint);
        }
    }

private:
    int fN;
    typedef SampleView INHERITED;
};

const SkScalar CircleView::ANIM_DX(SK_Scalar1 / 67);
const SkScalar CircleView::ANIM_DY(SK_Scalar1 / 29);
const SkScalar CircleView::ANIM_RAD(SK_Scalar1 / 19);

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

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