#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGraphics.h"
#include "SkRandom.h"

static void test_clearonlayers(SkCanvas* canvas) {
    SkCanvas& c = *canvas;
    
    SkPaint paint;
    paint.setColor(SK_ColorBLUE);
    paint.setStyle(SkPaint::kStrokeAndFill_Style);
    SkRect rect = SkRect::MakeXYWH(25, 25, 50, 50);
    c.drawRect(rect, paint);
    
    c.clipRect(rect);
    
    c.saveLayer(NULL, NULL);
    rect = SkRect::MakeXYWH(50, 10, 40, 80);
    c.clipRect(rect, SkRegion::kUnion_Op);
    
    rect = SkRect::MakeXYWH(50, 0, 50, 100);
    // You might draw something here, but it's not necessary.
    // paint.setColor(SK_ColorRED);
    // c.drawRect(rect, paint);
    paint.setXfermodeMode(SkXfermode::kClear_Mode);
    c.drawRect(rect, paint);
    c.restore();
}

static void test_strokerect(SkCanvas* canvas, const SkRect& r) {
    SkPaint p;
    
    p.setAntiAlias(true);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(4);
    
    canvas->drawRect(r, p);

    SkPath path;
    SkRect r2(r);
    r2.offset(18, 0);
    path.addRect(r2);

    canvas->drawPath(path, p);
}

static void test_strokerect(SkCanvas* canvas) {
    canvas->drawColor(SK_ColorWHITE);

    SkRect r;

    r.set(10, 10, 14, 14);
    r.offset(0.25f, 0.3333f);
    test_strokerect(canvas, r);
    canvas->translate(0, 20);
    
    r.set(10, 10, 14.5f, 14.5f);
    r.offset(0.25f, 0.3333f);
    test_strokerect(canvas, r);
    canvas->translate(0, 20);
    
    r.set(10, 10, 14.5f, 20);
    r.offset(0.25f, 0.3333f);
    test_strokerect(canvas, r);
    canvas->translate(0, 20);
    
    r.set(10, 10, 20, 14.5f);
    r.offset(0.25f, 0.3333f);
    test_strokerect(canvas, r);
    canvas->translate(0, 20);
    
    r.set(10, 10, 20, 20);
    r.offset(0.25f, 0.3333f);
    test_strokerect(canvas, r);
    canvas->translate(0, 20);
    
}

class Draw : public SkRefCnt {
public:
    Draw() : fFlags(0) {}

    enum Flags {
        kSelected_Flag  = 1 << 0
    };
    int getFlags() const { return fFlags; }
    void setFlags(int flags);

    bool isSelected() const { return SkToBool(fFlags & kSelected_Flag); }
    void setSelected(bool pred) {
        if (pred) {
            fFlags |= kSelected_Flag;
        } else {
            fFlags &= ~kSelected_Flag;
        }
    }

    void draw(SkCanvas* canvas) {
        int sc = canvas->save();
        this->onDraw(canvas);
        canvas->restoreToCount(sc);

        if (this->isSelected()) {
            this->drawSelection(canvas);
        }
    }

    void drawSelection(SkCanvas* canvas) {
        int sc = canvas->save();
        this->onDrawSelection(canvas);
        canvas->restoreToCount(sc);
    }

    void getBounds(SkRect* bounds) {
        this->onGetBounds(bounds);
    }

    bool hitTest(SkScalar x, SkScalar y) {
        return this->onHitTest(x, y);
    }

    void offset(SkScalar dx, SkScalar dy) {
        if (dx || dy) {
            this->onOffset(dx, dy);
        }
    }

protected:
    virtual void onDraw(SkCanvas*) = 0;
    virtual void onGetBounds(SkRect*) = 0;
    virtual void onOffset(SkScalar dx, SkScalar dy) = 0;
    virtual void onDrawSelection(SkCanvas* canvas) {
        SkRect r;
        this->getBounds(&r);
        SkPaint paint;
        SkPoint pts[4];
        r.toQuad(pts);
        paint.setStrokeWidth(SkIntToScalar(10));
        paint.setColor(0x80FF8844);
        paint.setStrokeCap(SkPaint::kRound_Cap);
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, pts, paint);
    }
    virtual bool onHitTest(SkScalar x, SkScalar y) {
        SkRect bounds;
        this->getBounds(&bounds);
        return bounds.contains(x, y);
    }

private:
    int fFlags;
};

class RDraw : public Draw {
public:
    enum Style {
        kRect_Style,
        kOval_Style,
        kRRect_Style,
        kFrame_Style
    };

    RDraw(const SkRect& r, Style s) : fRect(r), fStyle(s) {}

    void setRect(const SkRect& r) {
        fRect = r;
    }

    void setPaint(const SkPaint& p) {
        fPaint = p;
    }

protected:
    virtual void onDraw(SkCanvas* canvas) {
        switch (fStyle) {
            case kRect_Style:
                canvas->drawRect(fRect, fPaint);
                break;
            case kOval_Style:
                canvas->drawOval(fRect, fPaint);
                break;
            case kRRect_Style: {
                SkScalar rx = fRect.width() / 5;
                SkScalar ry = fRect.height() / 5;
                if (rx < ry) {
                    ry = rx;
                } else {
                    rx = ry;
                }
                canvas->drawRoundRect(fRect, rx, ry, fPaint);
                break;
            }
            case kFrame_Style: {
                SkPath path;
                path.addOval(fRect, SkPath::kCW_Direction);
                SkRect r = fRect;
                r.inset(fRect.width()/6, 0);
                path.addOval(r, SkPath::kCCW_Direction);
                canvas->drawPath(path, fPaint);
                break;
            }
        }
    }

    virtual void onGetBounds(SkRect* bounds) {
        *bounds = fRect;
    }

    virtual void onOffset(SkScalar dx, SkScalar dy) {
        fRect.offset(dx, dy);
    }

private:
    SkRect  fRect;
    SkPaint fPaint;
    Style   fStyle;
};

class DrawFactory {
public:
    DrawFactory() {
        fPaint.setAntiAlias(true);
    }

    const SkPaint& getPaint() const { return fPaint; }

    void setPaint(const SkPaint& p) {
        fPaint = p;
    }

    virtual Draw* create(const SkPoint&, const SkPoint&) = 0;
    
private:
    SkPaint fPaint;
};

class RectFactory : public DrawFactory {
public:
    virtual Draw* create(const SkPoint& p0, const SkPoint& p1) {
        SkRect r;
        r.set(p0.x(), p0.y(), p1.x(), p1.y());
        r.sort();

//        RDraw* d = new RDraw(r, RDraw::kRRect_Style);
        RDraw* d = new RDraw(r, RDraw::kFrame_Style);
        d->setPaint(this->getPaint());
        return d;
    }
};

class DrawView : public SkView {
    Draw*           fDraw;
    DrawFactory*    fFactory;
    SkRandom        fRand;
    SkTDArray<Draw*> fList;

public:
    DrawView() : fDraw(NULL) {
        fFactory = new RectFactory;
    }

    virtual ~DrawView() {
        fList.unrefAll();
        SkSafeUnref(fDraw);
    }

    Draw* setDraw(Draw* d) {
        SkRefCnt_SafeAssign(fDraw, d);
        return d;
    }

    SkColor randColor() {
        return (SkColor)fRand.nextU() | 0xFF000000;
    }

    Draw* hitTestList(SkScalar x, SkScalar y) const {
        Draw** first = fList.begin();
        for (Draw** iter = fList.end(); iter > first;) {
            --iter;
            if ((*iter)->hitTest(x, y)) {
                return *iter;
            }
        }
        return NULL;
    }
    
protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Draw");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    void drawBG(SkCanvas* canvas) {
        canvas->drawColor(0xFFDDDDDD);
//        canvas->drawColor(SK_ColorWHITE);
    }

    virtual void onDraw(SkCanvas* canvas) {
        this->drawBG(canvas);
        test_clearonlayers(canvas); return;
     //   test_strokerect(canvas); return;

        for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
            (*iter)->draw(canvas);
        }
        if (fDraw) {
            fDraw->draw(canvas);
        }
    }

    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
        for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
            (*iter)->setSelected(false);
        }

        Click* c = new Click(this);
        Draw* d = this->hitTestList(x, y);
        if (d) {
            d->setSelected(true);
            c->setType("dragger");
        } else {
            c->setType("maker");
        }
        return c;
    }

    virtual bool onClick(Click* click) {
        if (Click::kUp_State == click->fState) {
            if (click->isType("maker")) {
                if (SkPoint::Distance(click->fOrig, click->fCurr) > SkIntToScalar(3)) {
                    *fList.append() = fDraw;
                } else {
                    fDraw->unref();
                }
                fDraw = NULL;
            }
            return true;
        }

        if (Click::kDown_State == click->fState) {
            SkPaint p = fFactory->getPaint();
            p.setColor(this->randColor());
            fFactory->setPaint(p);
        }

        if (click->isType("maker")) {
            this->setDraw(fFactory->create(click->fOrig, click->fCurr))->unref();
        } else if (click->isType("dragger")) {
            for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
                if ((*iter)->isSelected()) {
                    (*iter)->offset(click->fCurr.x() - click->fPrev.x(),
                                    click->fCurr.y() - click->fPrev.y());
                }
            }
        }
        this->inval(NULL);
        return true;
    }

private:
    typedef SkView INHERITED;
};

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

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

