
/*
 * 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 "SkConcaveToTriangles.h"

#define SIZE    SkIntToScalar(150)

typedef void (*PathProc)(SkPath*);

static void make_path0(SkPath* path) {
    SkRect r;
    r.set(0, 0, SIZE, SIZE);
    path->addRect(r);
}

static void make_path1(SkPath* path) {
    SkRect r;
    r.set(0, 0, SIZE, SIZE);
    path->addRoundRect(r, SIZE/4, SIZE/4);
}

static void make_path2(SkPath* path) {
    SkRect r;
    r.set(0, 0, SIZE, SIZE);
    path->addOval(r);
}

static const PathProc gProcs[] = {
    make_path0,
    make_path1,
    make_path2,
};

#define COUNT_PROCS SK_ARRAY_COUNT(gProcs)

class TriangleView : public SkView {
public:
    SkPath fPaths[COUNT_PROCS];

	TriangleView() {
        for (size_t i = 0; i < COUNT_PROCS; i++) {
            gProcs[i](&fPaths[i]);
        }
    }
    
protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Triangles");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }
    
    void drawBG(SkCanvas* canvas) {
        canvas->drawColor(SK_ColorGRAY);
    }
    
    static void draw_path(SkCanvas* canvas, const SkPaint& pathPaint,
                          const SkPath& path, const SkPaint& triPaint) {
        canvas->drawPath(path, pathPaint);
        
        int n = path.getPoints(NULL, 0);
        SkPoint* pts = new SkPoint[n];
        path.getPoints(pts, n);
        
        SkTDArray<SkPoint> triangles;
        if (SkConcaveToTriangles(n, pts, &triangles)) {
            canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
                                 triangles.count(), triangles.begin(), NULL,
                                 NULL, NULL, NULL, 0, triPaint);
        }
        
        SkPaint paint;
        paint.setColor(SK_ColorGREEN);
        paint.setStrokeWidth(SkIntToScalar(4));
        canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts, paint);
        delete[] pts;
    }

    virtual void onDraw(SkCanvas* canvas) {
        this->drawBG(canvas);
        
        canvas->translate(SIZE/2, SIZE/2);

        SkPaint pathPaint, triPaint;
        
        pathPaint.setColor(SK_ColorBLUE);
        pathPaint.setStrokeWidth(SIZE / 12);

        triPaint.setColor(SK_ColorRED);
        triPaint.setStyle(SkPaint::kStroke_Style);

        for (size_t i = 0; i < COUNT_PROCS; i++) {
            pathPaint.setStyle(SkPaint::kFill_Style);
            draw_path(canvas, pathPaint, fPaths[i], triPaint);

            canvas->save();
            canvas->translate(0, SIZE * 6 / 5);

            pathPaint.setStyle(SkPaint::kStroke_Style);
            draw_path(canvas, pathPaint, fPaths[i], triPaint);
            
            canvas->restore();
            canvas->translate(SIZE * 6 / 5, 0);
        }
    }
    
private:
    typedef SkView INHERITED;
};

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

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

