/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"
#include "SkTArray.h"

class ConicPathsGM : public skiagm::GM {
protected:

    SkString onShortName() override {
        return SkString("conicpaths");
    }

    SkISize onISize() override {
        return SkISize::Make(920, 960);
    }

    void onOnceBeforeDraw() override {
        {
            const SkScalar w = SkScalarSqrt(2)/2;
            SkPath* conicCirlce = &fPaths.push_back();
            conicCirlce->moveTo(0, 0);
            conicCirlce->conicTo(0, 50, 50, 50, w);
            conicCirlce->rConicTo(50, 0, 50, -50, w);
            conicCirlce->rConicTo(0, -50, -50, -50, w);
            conicCirlce->rConicTo(-50, 0, -50, 50, w);

        }
        {
            SkPath* hyperbola = &fPaths.push_back();
            hyperbola->moveTo(0, 0);
            hyperbola->conicTo(0, 100, 100, 100, 2);
        }
        {
            SkPath* thinHyperbola = &fPaths.push_back();
            thinHyperbola->moveTo(0, 0);
            thinHyperbola->conicTo(100, 100, 5, 0, 2);
        }
        {
            SkPath* veryThinHyperbola = &fPaths.push_back();
            veryThinHyperbola->moveTo(0, 0);
            veryThinHyperbola->conicTo(100, 100, 1, 0, 2);
        }
        {
            SkPath* closedHyperbola = &fPaths.push_back();
            closedHyperbola->moveTo(0, 0);
            closedHyperbola->conicTo(100, 100, 0, 0, 2);
        }
        {
            // using 1 as weight defaults to using quadTo
            SkPath* nearParabola = &fPaths.push_back();
            nearParabola->moveTo(0, 0);
            nearParabola->conicTo(0, 100, 100, 100, 0.999f);
        }
        {
            SkPath* thinEllipse = &fPaths.push_back();
            thinEllipse->moveTo(0, 0);
            thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf);
        }
        {
            SkPath* veryThinEllipse = &fPaths.push_back();
            veryThinEllipse->moveTo(0, 0);
            veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf);
        }
        {
            SkPath* closedEllipse = &fPaths.push_back();
            closedEllipse->moveTo(0,  0);
            closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf);
        }
        {
            const SkScalar w = SkScalarSqrt(2)/2;
            fGiantCircle.moveTo(2.1e+11f, -1.05e+11f);
            fGiantCircle.conicTo(2.1e+11f, 0, 1.05e+11f, 0, w);
            fGiantCircle.conicTo(0, 0, 0, -1.05e+11f, w);
            fGiantCircle.conicTo(0, -2.1e+11f, 1.05e+11f, -2.1e+11f, w);
            fGiantCircle.conicTo(2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, w);

        }
    }

    void drawGiantCircle(SkCanvas* canvas) {
        SkPaint paint;
        canvas->drawPath(fGiantCircle, paint);
    }

    void onDraw(SkCanvas* canvas) override {
        const SkAlpha kAlphaValue[] = { 0xFF, 0x40 };

        const SkScalar margin = 15;
        canvas->translate(margin, margin);

        SkPaint paint;
        for (int p = 0; p < fPaths.count(); ++p) {
            canvas->save();
            for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) {
                paint.setARGB(kAlphaValue[a], 0, 0, 0);
                for (int aa = 0; aa < 2; ++aa) {
                    paint.setAntiAlias(SkToBool(aa));
                    for (int fh = 0; fh < 2; ++fh) {
                        paint.setStyle(fh ? SkPaint::kStroke_Style : SkPaint::kFill_Style);

                        const SkRect& bounds = fPaths[p].getBounds();
                        canvas->save();
                        canvas->translate(-bounds.fLeft, -bounds.fTop);
                        canvas->drawPath(fPaths[p], paint);
                        canvas->restore();

                        canvas->translate(110, 0);
                    }
                }
            }
            canvas->restore();
            canvas->translate(0, 110);
        }
        canvas->restore();

        this->drawGiantCircle(canvas);  
    }

private:
    SkTArray<SkPath> fPaths;
    SkPath           fGiantCircle;
    typedef skiagm::GM INHERITED;
};
DEF_GM(return new ConicPathsGM;)

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

