
#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkXfermode.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkParsePath.h"
#include "SkTime.h"
#include "SkTypeface.h"

#include "SkGeometry.h"

// http://code.google.com/p/skia/issues/detail?id=32
static void test_cubic() {
    SkPoint src[4] = {
        { 556.25000, 523.03003 },
        { 556.23999, 522.96002 },
        { 556.21997, 522.89001 },
        { 556.21997, 522.82001 }
    };
    SkPoint dst[11];
    dst[10].set(42, -42);   // one past the end, that we don't clobber these
    SkScalar tval[] = { 0.33333334f, 0.99999994f };

    SkChopCubicAt(src, dst, tval, 2);

#if 0
    for (int i = 0; i < 11; i++) {
        SkDebugf("--- %d [%g %g]\n", i, dst[i].fX, dst[i].fY);
    }
#endif
}

static void test_cubic2() {
    const char* str = "M2242 -590088L-377758 9.94099e+07L-377758 9.94099e+07L2242 -590088Z";
    SkPath path;
    SkParsePath::FromSVGString(str, &path);
    
    {
#ifdef SK_BUILD_FOR_WIN
        // windows doesn't have strtof
        float x = (float)strtod("9.94099e+07", NULL);
#else
        float x = strtof("9.94099e+07", NULL);
#endif
        int ix = (int)x;
        int fx = (int)(x * 65536);
        int ffx = SkScalarToFixed(x);
        printf("%g %x %x %x\n", x, ix, fx, ffx);
        
        SkRect r = path.getBounds();
        SkIRect ir;
        r.round(&ir);
        printf("[%g %g %g %g] [%x %x %x %x]\n",
               r.fLeft, r.fTop, r.fRight, r.fBottom,
               ir.fLeft, ir.fTop, ir.fRight, ir.fBottom);
    }
    
    SkBitmap bitmap;
    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 300, 200);
    bitmap.allocPixels();

    SkCanvas canvas(bitmap);
    SkPaint paint;
    paint.setAntiAlias(true);
    canvas.drawPath(path, paint);
}

class PathView : public SkView {
public:
    int fDStroke, fStroke, fMinStroke, fMaxStroke;
    SkPath fPath[6];
    bool fShowHairline;
    
	PathView() {
        test_cubic();
        test_cubic2();

        fShowHairline = false;
        
        fDStroke = 1;
        fStroke = 10;
        fMinStroke = 10;
        fMaxStroke = 180;

        const int V = 85;
        
        fPath[0].moveTo(SkIntToScalar(40), SkIntToScalar(70));
        fPath[0].lineTo(SkIntToScalar(70), SkIntToScalar(70) + SK_Scalar1/1);
        fPath[0].lineTo(SkIntToScalar(110), SkIntToScalar(70));
        
        fPath[1].moveTo(SkIntToScalar(40), SkIntToScalar(70));
        fPath[1].lineTo(SkIntToScalar(70), SkIntToScalar(70) - SK_Scalar1/1);
        fPath[1].lineTo(SkIntToScalar(110), SkIntToScalar(70));
        
        fPath[2].moveTo(SkIntToScalar(V), SkIntToScalar(V));
        fPath[2].lineTo(SkIntToScalar(50), SkIntToScalar(V));
        fPath[2].lineTo(SkIntToScalar(50), SkIntToScalar(50));
        
        fPath[3].moveTo(SkIntToScalar(50), SkIntToScalar(50));
        fPath[3].lineTo(SkIntToScalar(50), SkIntToScalar(V));
        fPath[3].lineTo(SkIntToScalar(V), SkIntToScalar(V));
        
        fPath[4].moveTo(SkIntToScalar(50), SkIntToScalar(50));
        fPath[4].lineTo(SkIntToScalar(50), SkIntToScalar(V));
        fPath[4].lineTo(SkIntToScalar(52), SkIntToScalar(50));
        
        fPath[5].moveTo(SkIntToScalar(52), SkIntToScalar(50));
        fPath[5].lineTo(SkIntToScalar(50), SkIntToScalar(V));
        fPath[5].lineTo(SkIntToScalar(50), SkIntToScalar(50));
    }
    
    virtual ~PathView()
    {
    }
    
    void nextStroke()
    {
        fStroke += fDStroke;
        if (fStroke > fMaxStroke || fStroke < fMinStroke)
            fDStroke = -fDStroke;
    }
    
protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt)
    {
        if (SampleCode::TitleQ(*evt))
        {
            SampleCode::TitleR(evt, "Paths");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }
    
    void drawBG(SkCanvas* canvas)
    {
        canvas->drawColor(0xFFDDDDDD);
//        canvas->drawColor(SK_ColorWHITE);
    }
    
    void drawPath(SkCanvas* canvas, const SkPath& path, SkPaint::Join j)
    {
        SkPaint paint;
        
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeJoin(j);
        paint.setStrokeWidth(SkIntToScalar(fStroke));

        if (fShowHairline)
        {
            SkPath  fill;
            
            paint.getFillPath(path, &fill);            
            paint.setStrokeWidth(0);
            canvas->drawPath(fill, paint);
        }
        else
            canvas->drawPath(path, paint);
        
        paint.setColor(SK_ColorRED);
        paint.setStrokeWidth(0);
        canvas->drawPath(path, paint);
    }
    
    virtual void onDraw(SkCanvas* canvas)
    {
        this->drawBG(canvas);
        
        canvas->translate(SkIntToScalar(50), SkIntToScalar(50));

        static const SkPaint::Join gJoins[] = {
            SkPaint::kBevel_Join,
            SkPaint::kMiter_Join,
            SkPaint::kRound_Join
        };

        for (int i = 0; i < SK_ARRAY_COUNT(gJoins); i++)
        {
            canvas->save();
            for (int j = 0; j < SK_ARRAY_COUNT(fPath); j++)
            {
                this->drawPath(canvas, fPath[j], gJoins[i]);
                canvas->translate(SkIntToScalar(200), 0);
            }
            canvas->restore();
            
            canvas->translate(0, SkIntToScalar(200));
        }
        
        this->nextStroke();
        this->inval(NULL);
    }
    
    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) 
    {
        fShowHairline = !fShowHairline;
        this->inval(NULL);
        return this->INHERITED::onFindClickHandler(x, y);
    }
    
    virtual bool onClick(Click* click) 
    {
        return this->INHERITED::onClick(click);
    }
    
private:
    typedef SkView INHERITED;
};

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

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

