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

#include "SkStream.h"
#include "SkXMLParser.h"

static const int gKernel[3][3] = {
//    { -1, -2, -1 }, { -2, 12, -2 }, { -1, -2, -1 }
    { 1, 2, 1 }, { 2, 64-12, 2 }, { 1, 2, 1 }
};
static const int gShift = 6;

class ReduceNoise : public SkKernel33ProcMaskFilter {
public:
    ReduceNoise(int percent256) : SkKernel33ProcMaskFilter(percent256) {}
    virtual uint8_t computeValue(uint8_t* const* srcRows)
    {
        int c = srcRows[1][1];
        int min = 255, max = 0;
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                if (i != 1 || j != 1)
                {
                    int v = srcRows[i][j];
                    if (max < v)
                        max = v;
                    if  (min > v)
                        min = v;
                }
        if (c > max) c = max;
    //    if (c < min) c = min;
        return c;
    }
    virtual Factory getFactory() { return Create; }
private:
    ReduceNoise(SkFlattenableReadBuffer& rb) : SkKernel33ProcMaskFilter(rb) {}
    static SkFlattenable* Create(SkFlattenableReadBuffer& rb)
    {
        return new ReduceNoise(rb);
    }
};

class Darken : public SkKernel33ProcMaskFilter {
public:
    Darken(int percent256) : SkKernel33ProcMaskFilter(percent256) {}
    virtual uint8_t computeValue(uint8_t* const* srcRows)
    {
        int c = srcRows[1][1];
        float f = c / 255.f;
        
        if (c >= 0)
        {
            f = sqrtf(f);
        }
        else
        {
            f *= f;
        }
        SkASSERT(f >= 0 && f <= 1);
        return (int)(f * 255);
    }
    virtual Factory getFactory() { return Create; }
private:
    Darken(SkFlattenableReadBuffer& rb) : SkKernel33ProcMaskFilter(rb) {}
    static SkFlattenable* Create(SkFlattenableReadBuffer& rb)
    {
        return new Darken(rb);
    }
};

static SkMaskFilter* makemf() { return new Darken(0x30); }

//#ifdef TEST_CLICKX

static void test_typefaceCache()
{
#ifdef ANDROID
    SkTypeface* t0 = SkTypeface::CreateFromName("sans-serif",
                                                SkTypeface::kNormal);
    SkTypeface* t1 = SkTypeface::CreateFromName(NULL, SkTypeface::kNormal);
    SkTypeface* t2 = SkTypeface::CreateFromName("arial", SkTypeface::kNormal);
    SkTypeface* t3 = SkTypeface::CreateFromName("helvetica", SkTypeface::kItalic);
    
    SkASSERT(t0 == t1);
    SkASSERT(t0 == t2);
    SkASSERT(t0 == t3);
#endif
}

static void test_breakText()
{
    SkPaint paint;
    const char* text = "sdfkljAKLDFJKEWkldfjlk#$%&sdfs.dsj";
    size_t length = strlen(text);
    SkScalar width = paint.measureText(text, length);
    
    SkScalar mm = 0;
    SkScalar nn = 0;
    for (SkScalar w = 0; w <= width; w += SK_Scalar1)
    {
        SkScalar m;
        size_t n = paint.breakText(text, length, w, &m,
                                    SkPaint::kBackward_TextBufferDirection);
        
        SkASSERT(n <= length);
        SkASSERT(m <= width);
    
        if (n == 0)
            SkASSERT(m == 0);
        else
        {
            // now assert that we're monotonic
            if (n == nn)
                SkASSERT(m == mm);
            else
            {
                SkASSERT(n > nn);
                SkASSERT(m > mm);
            }
        }
        nn = n;
        mm = m;
    }

    nn = paint.breakText(text, length, width, &mm);
    SkASSERT(nn == length);
    SkASSERT(mm == width);
}

static SkRandom gRand;

class SkPowerMode : public SkXfermode {
public:
    SkPowerMode(SkScalar exponent) { this->init(exponent); }

    virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, const SkAlpha aa[]);

    typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
    
    // overrides for SkFlattenable
    virtual Factory getFactory() { return Create; }
    virtual void flatten(SkFlattenableWriteBuffer& b)
    {
    //    this->INHERITED::flatten(b);  How can we know if this is legal????
        b.write32(SkScalarToFixed(fExp));
    }
    
private:
    SkScalar fExp;          // user's value
    uint8_t fTable[256];    // cache

    void init(SkScalar exponent);
    SkPowerMode(SkFlattenableReadBuffer& b) : SkXfermode(b)
    {
        // read the exponent
        this->init(SkFixedToScalar(b.readS32()));
    }
    static SkFlattenable* Create(SkFlattenableReadBuffer& b)
    {
        return SkNEW_ARGS(SkPowerMode, (b));
    }
    
    typedef SkXfermode INHERITED;
};

void SkPowerMode::init(SkScalar e)
{
    fExp = e;
    float ee = SkScalarToFloat(e);
    
    printf("------ %g\n", ee);
    for (int i = 0; i < 256; i++)
    {
        float x = i / 255.f;
     //   printf(" %d %g", i, x);
        x = powf(x, ee);
     //   printf(" %g", x);
        int xx = SkScalarRound(SkFloatToScalar(x * 255));
     //   printf(" %d\n", xx);
        fTable[i] = SkToU8(xx);
    }
}

void SkPowerMode::xfer16(uint16_t dst[], const SkPMColor src[], int count, const SkAlpha aa[])
{
    for (int i = 0; i < count; i++)
    {
        SkPMColor c = src[i];
        int r = SkGetPackedR32(c);
        int g = SkGetPackedG32(c);
        int b = SkGetPackedB32(c);
        r = fTable[r];
        g = fTable[g];
        b = fTable[b];
        dst[i] = SkPack888ToRGB16(r, g, b);
    }
}

static const struct {
    const char* fName;
    uint32_t    fFlags;
    bool        fFlushCache;
} gHints[] = {
    { "Linear", SkPaint::kLinearText_Flag,     false },
    { "Normal",   0,                           true },
    { "Subpixel", SkPaint::kSubpixelText_Flag, true }
};

#ifdef SK_DEBUG
    #define REPEAT_COUNT    1
#else
    #define REPEAT_COUNT    5000
#endif

static int count_char_points(const SkPaint& paint, char c)
{
    SkPath  path;
    
    paint.getTextPath(&c, 1, 0, 0, &path);
    return path.getPoints(NULL, 0);
}

static int gOld, gNew, gCount;

static void dump(int c, int oldc, int newc)
{
    if (oldc != newc)
    {
        gOld += oldc;
        gNew += newc;
        gCount += 1;
        printf("char %c: old = %3d, new = %3d, reduction %g%%\n", c, oldc, newc, 100. * (oldc - newc) / oldc);
    }
}

static void tab(int n)
{
//    printf("[%d] ", n); return;
    SkASSERT(n >= 0);
    for (int i = 0; i < n; i++)
        printf("    ");
}

#if 0
#include "badrects.cpp"

static void make_badrgn(SkRegion* rgn, int insetAmount)
{
    SkRect16    r, bounds;
    int         i;
    
    rgn->setEmpty();
    bounds.setEmpty();

    for (i = 0; i < SK_ARRAY_COUNT(badrects); i++)
    {
        SkASSERT(badrects[i].width > 0 && badrects[i].height > 0);

        r.set(badrects[i].x, badrects[i].y, badrects[i].x + badrects[i].width, badrects[i].y + badrects[i].height);
        r.inset(insetAmount, insetAmount);
        rgn->op(r, SkRegion::kUnion_Op);
        bounds.join(r);
    }
    SkASSERT(bounds == rgn->getBounds());

    for (i = 0; i < SK_ARRAY_COUNT(badrects); i++)
    {
        r.set(badrects[i].x, badrects[i].y, badrects[i].x + badrects[i].width, badrects[i].y + badrects[i].height);        
        SkASSERT(rgn->contains(r));
    }
}
#endif

static void draw_rgn(const SkRegion& rgn, SkCanvas* canvas, const SkPaint& paint)
{
    SkRect    r;
    SkRegion::Iterator  iter(rgn);
    
    for (; !iter.done(); iter.next())
    {
        r.set(iter.rect());
        canvas->drawRect(r, paint);
    }
}

static void test_break(SkCanvas* canvas, const char text[], size_t length,
                        SkScalar x, SkScalar y, const SkPaint& paint,
                        SkScalar clickX)
{
    SkPaint linePaint;
    
    linePaint.setAntiAlias(true);
    
    SkScalar measured;
    
    if (paint.breakText(text, length, clickX - x, &measured, SkPaint::kForward_TextBufferDirection))
    {
        linePaint.setColor(SK_ColorRED);
        canvas->drawLine(x, y, x + measured, y, linePaint);
    }

    x += paint.measureText(text, length);
    if (paint.breakText(text, length, x - clickX, &measured, SkPaint::kBackward_TextBufferDirection))
    {
        linePaint.setColor(SK_ColorBLUE);
        canvas->drawLine(x - measured, y, x, y, linePaint);
    }
}

static void test_poly()
{
    static const SkPoint dst[] = {
        SkIntToScalar(2), SkIntToScalar(1),
        SkIntToScalar(5), SkIntToScalar(1),
        SkIntToScalar(5), SkIntToScalar(3),
        SkIntToScalar(2), SkIntToScalar(3)
    };
    
    static const SkPoint src[] = {
        SkIntToScalar(0), SkIntToScalar(0),
        SkIntToScalar(1), SkIntToScalar(0),
        SkIntToScalar(1), SkIntToScalar(1),
        SkIntToScalar(0), SkIntToScalar(1)
    };
    
    SkMatrix matrix;
    
    if (matrix.setPolyToPoly(src, dst, 4))
    {
        SkPoint pt = { SK_Scalar1/2, SK_Scalar1/2 };
        matrix.mapPoints(&pt, 1);        
        printf("---- x = %g y = %g\n", SkScalarToFloat(pt.fX), SkScalarToFloat(pt.fY));
    }
    else
        printf("---- setPolyToPoly failed\n");
}

#include "SkColorShader.h"

static void DrawTheText(SkCanvas* canvas, const char text[], size_t length,
                        SkScalar x, SkScalar y, const SkPaint& paint,
                        SkScalar clickX, SkMaskFilter* mf)
{
    SkPaint p(paint);

#if 0
    canvas->drawText(text, length, x, y, paint);
#else
    {
        SkPoint pts[1000];
        SkScalar xpos = x;
        SkASSERT(length <= SK_ARRAY_COUNT(pts));
        for (size_t i = 0; i < length; i++)
            pts[i].set(xpos, y), xpos += paint.getTextSize();
        canvas->drawPosText(text, length, pts, paint);
    }
#endif

    p.setSubpixelText(true);
    x += SkIntToScalar(180);
    canvas->drawText(text, length, x, y, p);

#ifdef TEST_CLICKX
    test_break(canvas, text, length, x, y, p, clickX);
#endif

#ifdef SK_DEBUG
    if (false)
    {
        SkColorShader   shader;
        p.setShader(&shader);
        x += SkIntToScalar(180);
        canvas->drawText(text, length, x, y, p);
        p.setShader(NULL);
    }

    if (true)
    {
    //    p.setMaskFilter(mf);
        p.setSubpixelText(false);
        p.setLinearText(true);
        x += SkIntToScalar(180);
        canvas->drawText(text, length, x, y, p);
    }
#endif
}

class TextSpeedView : public SkView {
public:
	TextSpeedView()
    {
        fMF = makemf();

        fHints = 0;

        if (false)
        {
            static const char extra[] = { '.', ',', ':', ';', '!' };
            SkPaint   paint, paint2;

            paint2.setTypeface(SkTypeface::CreateFromName(NULL,
                                                SkTypeface::kItalic))->unref();

            for (int i = 0; i < 26; i++)
                ::dump('a' + i, count_char_points(paint, 'a' + i), count_char_points(paint2, 'a' + i));
            for (int j = 0; j < SK_ARRAY_COUNT(extra); j++)
                ::dump(extra[j], count_char_points(paint, extra[j]), count_char_points(paint2, extra[j]));

            printf("--- ave reduction = %g%%\n", 100. * (gOld - gNew) / gOld);
        }
        
        if (true)
        {
            SkPoint pts[] = { SkIntToScalar(20), 0, SkIntToScalar(256+20), 0 };
            SkColor colors[] = { SkColorSetARGB(0, 255, 255, 255), SkColorSetARGB(255, 255, 255, 255) };
            fGradient = SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
        }
        
        fClickX = 0;

        test_breakText();        
        test_typefaceCache();
        test_poly();
    }
    
    virtual ~TextSpeedView()
    {
        fGradient->unref();
        fMF->safeUnref();
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt)
    {
        if (SampleCode::TitleQ(*evt))
        {
            SampleCode::TitleR(evt, "Text");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }
    
    void drawBG(SkCanvas* canvas)
    {
//        canvas->drawColor(0xFFDDDDDD);
        canvas->drawColor(SK_ColorWHITE);
   //     canvas->drawColor(SK_ColorBLACK);
    }
    
    static void make_textstrip(SkBitmap* bm)
    {
        bm->setConfig(SkBitmap::kRGB_565_Config, 200, 18);
        bm->allocPixels();
        bm->eraseColor(SK_ColorWHITE);
        
        SkCanvas    canvas(*bm);
        SkPaint     paint;
        const char* s = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit";
        
        paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag
                                        | SkPaint::kDevKernText_Flag);
        paint.setTextSize(SkIntToScalar(14));
        canvas.drawText(s, strlen(s), SkIntToScalar(8), SkIntToScalar(14), paint);
    }
    
    static void fill_pts(SkPoint pts[], size_t n, SkRandom* rand)
    {
        for (size_t i = 0; i < n; i++)
            pts[i].set(rand->nextUScalar1() * 640, rand->nextUScalar1() * 480);
    }
    
    virtual void onDraw(SkCanvas* canvas)
    {
        if (false)
        {
            canvas->translate(SkIntToScalar(480), 0);
            canvas->rotate(SkIntToScalar(90));
        }
        
        this->drawBG(canvas);
        
        if (false)
        {
            SkPaint p;
            
            p.setAntiAlias(true);
            p.setSubpixelText(true);
         //   p.setLinearText(true);
            
            SkScalar size = SkIntToScalar(6);
            SkMSec   dur = 0;
            const int LOOP = 16;
            const int TIMES = 10;
            
            for (int times = 0; times < TIMES; times++)
            {
                SkMSec now = SkTime::GetMSecs();
                for (int loop = 0; loop < LOOP; loop++)
                {
                    p.setTextSize(size);
                    size += SK_Scalar1/5;
                    canvas->drawText("Hamburgefons", 12, SkIntToScalar(10), SkIntToScalar(50), p);
                }
                dur += SkTime::GetMSecs() - now;
                SkGraphics::SetFontCacheUsed(0);
            }
            
            printf("----- duration = %g\n", dur * 1.0 / TIMES);
            this->inval(NULL);
            return;
        }
        
        if (false)
        {
            SkPaint p;
            p.setAntiAlias(true);
            for (int i = 6; i <= 36; i++)
            {
                SkRect r;
                SkPaint::FontMetrics m;
                p.setTextSize(SkIntToScalar(i));
                p.getFontMetrics(&m);
                int ascent = SkScalarRound(m.fAscent);
                int descent = SkScalarRound(m.fDescent);
                for (uint8_t c = ' '; c <= 127; c++)
                {
                    p.getTextWidths(&c, 1, NULL, &r);
                    if (SkScalarRound(r.fTop) < ascent)
                        printf("PS %d --- %c [%d] top=%g, ascent=%g ymax=%g\n", i, c, c,
                                SkScalarToFloat(r.fTop), SkScalarToFloat(m.fAscent), SkScalarToFloat(m.fTop));
                    if (SkScalarRound(r.fBottom) > descent)
                        printf("PS %d --- %c [%d] bottom=%g, descent=%g ymin=%g\n", i, c, c,
                                SkScalarToFloat(r.fBottom), SkScalarToFloat(m.fDescent), SkScalarToFloat(m.fBottom));
                }
            }
        }
        
        if (false)
        {
            SkPaint p;
            p.setShader(fGradient);

#ifdef SK_RELEASE
            SkMSec now = SkTime::GetMSecs();
            for (int i = 0; i < 100; i++)
#endif
            canvas->drawPaint(p);
#ifdef SK_RELEASE
            printf("----- %d ms\n", SkTime::GetMSecs() - now);
            this->inval(NULL);
#endif
            return;
        }
        
        if (false)
        {
            SkBitmap    bm;
            
            make_textstrip(&bm);
            canvas->translate(0, SkIntToScalar(50));
            for (int i = 0; i < 10; i++)
            {
                float gamma = 1 + i * 0.2f;
                SkPowerMode mode(SkFloatToScalar(1 / gamma));
                SkPaint     p;
                p.setXfermode(&mode);
                
                canvas->drawBitmap(bm, 0, SkIntToScalar(i) * bm.height(), &p);
            }
            return;
        }
        
        if (false)
        {
            SkPaint paint;
            
            paint.setAntiAlias(true);
            paint.setDevKernText(true);
            SkMSec now = SkTime::GetMSecs();
            for (int i = 0; i < 1000000; i++)
            {
                paint.measureText("Hamburgefons", 15, NULL, NULL);
            }
            printf("--------- measure %d\n", SkTime::GetMSecs() - now);
            this->inval(NULL);
            return;
        }

        if (false)
        {
            SkRegion    rgn;
            SkPath      path;
            SkPaint     paint;
            
        //    make_badrgn(&rgn, -2);
            
            if (false)
            {
                paint.setColor(SK_ColorBLUE);
                canvas->drawIRect(rgn.getBounds(), paint);
            }
            paint.setColor(SK_ColorRED);
            draw_rgn(rgn, canvas, paint);
            
            rgn.getBoundaryPath(&path);
            paint.setARGB(0x80, 0, 0, 0xFF);
            canvas->drawPath(path, paint);
            return;
        }

        if (false)
        {
            SkRect r = { SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(300), SkIntToScalar(300) };
            SkPaint p;
            
            p.setStyle(SkPaint::kStroke_Style);
            p.setAlpha(0x80);
            p.setStrokeWidth(SkIntToScalar(20));
            canvas->drawRect(r, p);
        }
        
        if (false)
        {
            SkPaint p;
            SkRect r = { SkIntToScalar(100), SkIntToScalar(100), SkIntToScalar(104), SkIntToScalar(104) };
         //   r.offset(SK_ScalarHalf, SK_ScalarHalf);
            p.setStyle(SkPaint::kStroke_Style);
            p.setStrokeWidth(SK_Scalar1*2);
        //    p.setAntiAliasOn(true);
            canvas->drawRect(r, p);
            return;
        }
        
        if (false)
        {
            Sk64    aa, bb;
            int64_t a = (int64_t)6062080 * -30596;
            int64_t b = (int64_t)4816896 * 57957;
            aa.setMul(6062080, -30596);
            bb.setMul(4816896, 57957);

            a += b;
            b = a >> 16;

//            SkFixed c = aa.addGetFixed(bb);
            
            printf("%d %d\n", (int)a, a >> 32);
            
            SkBitmap    bm;
            SkPaint     paint;
            SkScalar    scale = SkFloatToScalar(0.5625f);
            SkScalar    x = SkIntToScalar(100);
            SkScalar    y = SkIntToScalar(100);
            
            //paint.setFilterType(SkPaint::kBilinear_FilterType);
            
            SkImageDecoder::DecodeFile("/app_web_browser.png", &bm);
            
           // canvas->drawBitmap(bm, x, y, paint);
            x += SkIntToScalar(100);
            canvas->save();
                canvas->translate(x, y);
                canvas->scale(SkIntToScalar(2)/1, SkIntToScalar(2)/1);
                canvas->translate(-x, -y);
                canvas->drawBitmap(bm, x, y, &paint);
            canvas->restore();
            x += SkIntToScalar(100);
            canvas->save();
                canvas->translate(x, y);
                canvas->scale(scale, scale);
                canvas->translate(-x, -y);
            //    canvas->drawBitmap(bm, x, y, paint);
            canvas->restore();
            return;
        }
        
        SkAutoCanvasRestore restore(canvas, false);
        {
            SkRect r;
            r.set(0, 0, SkIntToScalar(1000), SkIntToScalar(20));
       //     canvas->saveLayer(&r, NULL, SkCanvas::kHasAlphaLayer_SaveFlag);
        }

        SkPaint paint;
//        const uint16_t glyphs[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 };
        int         index = fHints % SK_ARRAY_COUNT(gHints);
        index = 1;
//        const char* style = gHints[index].fName;
        
//        canvas->translate(0, SkIntToScalar(50));

  //      canvas->drawText(style, strlen(style), SkIntToScalar(20), SkIntToScalar(20), paint);

//        paint.setTypeface(SkTypeface::Create(NULL, SkTypeface::kItalic))->unref();
        paint.setAntiAlias(true);
        paint.setFlags(paint.getFlags() | gHints[index].fFlags);
        
        SkMSec now = 0;
        if (REPEAT_COUNT > 1)
            now = SkTime::GetMSecs();

        SkRect clip;
        clip.set(SkIntToScalar(25), SkIntToScalar(34), SkIntToScalar(88), SkIntToScalar(155));
        
        if (0) {
            canvas->clipRect(clip);
        }

        if (0) {
            SkPath clipPath;        
            clipPath.addOval(clip);
            canvas->clipPath(clipPath);
        }

        const char* text = "Hamburgefons";
        size_t length = strlen(text);

#ifdef TEST_CLICKX
        {
            SkPaint p;
            
            p.setColor(SK_ColorGREEN);
            p.setAntiAlias(true);
            canvas->drawLine(fClickX, 0, fClickX, SkIntToScalar(1000), p);
        }
#endif

        for (int j = 0; j < REPEAT_COUNT; j++)
        {
            SkScalar y = SkIntToScalar(0);
            for (int i = 9; i <= 24; i++) {
                paint.setTextSize(SkIntToScalar(i) /*+ (gRand.nextU() & 0xFFFF)*/);
                for (SkScalar dx = 0; dx <= SkIntToScalar(3)/4; dx += SkIntToScalar(1) /* /4 */)
                {
                    y += paint.getFontSpacing();
                    DrawTheText(canvas, text, length, SkIntToScalar(20) + dx, y, paint, fClickX, fMF);
                }
            }
            if (gHints[index].fFlushCache) {
                SkGraphics::SetFontCacheUsed(0);
            }
        }
        
        if (REPEAT_COUNT > 1)
        {
            printf("--------- FPS = %g\n", REPEAT_COUNT * 1000. / (SkTime::GetMSecs() - now));
            this->inval(NULL);
        }
    }
    
    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) 
    {
        fClickX = x;
        this->inval(NULL);
        return this->INHERITED::onFindClickHandler(x, y);
    }
    
    virtual bool onClick(Click* click) 
    {
        return this->INHERITED::onClick(click);
    }
    
private:
    int fHints;
    SkScalar fClickX;
    SkMaskFilter* fMF;
    SkShader* fGradient;

    typedef SkView INHERITED;
};

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

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

