#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);

