
/*
 * 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 "SkCornerPathEffect.h"
#include "SkCullPoints.h"
#include "SkGradientShader.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkRandom.h"

static void addbump(SkPath* path, const SkPoint pts[2], SkScalar bump) {
    SkVector    tang;
    
    tang.setLength(pts[1].fX - pts[0].fX, pts[1].fY - pts[0].fY, bump);

    path->lineTo(SkScalarHalf(pts[0].fX + pts[1].fX) - tang.fY,
                 SkScalarHalf(pts[0].fY + pts[1].fY) + tang.fX);
    path->lineTo(pts[1]);
}

static void subdivide(SkPath* path, SkScalar bump) {
    SkPath::Iter    iter(*path, false);
    SkPoint         pts[4];
    SkPath          tmp;
    
    for (;;)
        switch (iter.next(pts)) {
        case SkPath::kMove_Verb:
            tmp.moveTo(pts[0]);
            break;
        case SkPath::kLine_Verb:
            addbump(&tmp, pts, bump);
            bump = -bump;
            break;
        case SkPath::kDone_Verb:
            goto FINISH;
        default:
            break;
        }

FINISH:
    path->swap(tmp);
}

static SkIPoint* getpts(const SkPath& path, int* count) {
    SkPoint     pts[4];
    int         n = 1;
    SkIPoint*   array;

    {
        SkPath::Iter    iter(path, false);
        for (;;)
            switch (iter.next(pts)) {
            case SkPath::kLine_Verb:
                n += 1;
                break;
            case SkPath::kDone_Verb:
                goto FINISHED;
            default:
                break;
            }
    }

FINISHED:
    array = new SkIPoint[n];
    n = 0;

    {
        SkPath::Iter    iter(path, false);
        for (;;)
            switch (iter.next(pts)) {
            case SkPath::kMove_Verb:
                array[n++].set(SkScalarRound(pts[0].fX), SkScalarRound(pts[0].fY));
                break;
            case SkPath::kLine_Verb:
                array[n++].set(SkScalarRound(pts[1].fX), SkScalarRound(pts[1].fY));
                break;
            case SkPath::kDone_Verb:
                goto FINISHED2;
            default:
                break;
            }
    }
    
FINISHED2:
    *count = n;
    return array;
}

static SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) {
    return min + SkScalarMul(rand.nextUScalar1(), max - min);
}

class CullView : public SampleView {
public:
	CullView() {
        fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
        
        SkRandom    rand;
        
        for (int i = 0; i < 50; i++) {
            SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2);
            SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2);
            if (i == 0)
                fPath.moveTo(x, y);
            else
                fPath.lineTo(x, y);
        }
        
        SkScalar bump = fClip.width()/8;
        subdivide(&fPath, bump);
        subdivide(&fPath, bump);
        subdivide(&fPath, bump);
        fPoints = getpts(fPath, &fPtCount);
        
        this->setBGColor(0xFFDDDDDD);
    }
    
    virtual ~CullView() {
        delete[] fPoints;
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Culling");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }
    
    virtual void onDrawContent(SkCanvas* canvas) {
        SkAutoCanvasRestore ar(canvas, true);

        canvas->translate(  SkScalarHalf(this->width() - fClip.width()),
                            SkScalarHalf(this->height() - fClip.height()));

   //     canvas->scale(SK_Scalar1*3, SK_Scalar1*3, 0, 0);

        SkPaint paint;
        
    //    paint.setAntiAliasOn(true);
        paint.setStyle(SkPaint::kStroke_Style);

        canvas->drawRect(fClip, paint);

#if 1
        paint.setColor(0xFF555555);
        paint.setStrokeWidth(SkIntToScalar(2));
//        paint.setPathEffect(new SkCornerPathEffect(SkIntToScalar(30)))->unref();
        canvas->drawPath(fPath, paint);
//        paint.setPathEffect(NULL);
#endif

        SkPath  tmp;
        SkIRect iclip;
        fClip.round(&iclip);
        
        SkCullPointsPath    cpp(iclip, &tmp);
        
        cpp.moveTo(fPoints[0].fX, fPoints[0].fY);
        for (int i = 0; i < fPtCount; i++)
            cpp.lineTo(fPoints[i].fX, fPoints[i].fY);
        
        paint.setColor(SK_ColorRED);
        paint.setStrokeWidth(SkIntToScalar(3));
        paint.setStrokeJoin(SkPaint::kRound_Join);
        canvas->drawPath(tmp, paint);
        
        this->inval(NULL);
    }
    
private:
    SkRect      fClip;
    SkIPoint*   fPoints;
    SkPath      fPath;
    int         fPtCount;

    typedef SampleView INHERITED;
};

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

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

