/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"

#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkPoint.h"
#include "SkShader.h"
#include "SkTextBlob.h"
#include "SkTDArray.h"
#include "SkTypeface.h"

// This GM exercises drawTextBlob offset vs. shader space behavior.
class TextBlobShaderGM : public skiagm::GM {
public:
    TextBlobShaderGM(const char* txt) {
        SkPaint p;
        size_t txtLen = strlen(txt);
        fGlyphs.append(p.textToGlyphs(txt, txtLen, NULL));
        p.textToGlyphs(txt, txtLen, fGlyphs.begin());
    }

protected:

    void onOnceBeforeDraw() SK_OVERRIDE {
        SkPaint p;
        p.setAntiAlias(true);
        p.setSubpixelText(true);
        p.setTextSize(30);
        p.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

        SkTextBlobBuilder builder;
        int glyphCount = fGlyphs.count();
        const SkTextBlobBuilder::RunBuffer* run;

        run = &builder.allocRun(p, glyphCount, 10, 10, NULL);
        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));

        run = &builder.allocRunPosH(p, glyphCount,  80, NULL);
        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
        for (int i = 0; i < glyphCount; ++i) {
            run->pos[i] = p.getTextSize() * i * .75f;
        }

        run = &builder.allocRunPos(p, glyphCount, NULL);
        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
        for (int i = 0; i < glyphCount; ++i) {
            run->pos[i * 2] = p.getTextSize() * i * .75f;
            run->pos[i * 2 + 1] = 150 + 5 * sinf((float)i * 8 / glyphCount);
        }

        fBlob.reset(builder.build());

        SkColor  colors[2];
        colors[0] = SK_ColorRED;
        colors[1] = SK_ColorGREEN;

        SkScalar pos[SK_ARRAY_COUNT(colors)];
        for (unsigned i = 0; i < SK_ARRAY_COUNT(pos); ++i) {
            pos[i] = (float)i / (SK_ARRAY_COUNT(pos) - 1);
        }

        SkISize sz = this->onISize();
        fShader.reset(SkGradientShader::CreateRadial(SkPoint::Make(SkIntToScalar(sz.width() / 2),
                                                                   SkIntToScalar(sz.height() / 2)),
                                                     sz.width() * .66f, colors, pos,
                                                     SK_ARRAY_COUNT(colors),
                                                     SkShader::kRepeat_TileMode));
    }

    uint32_t onGetFlags() const SK_OVERRIDE {
        return kSkip565_Flag;
    }

    SkString onShortName() SK_OVERRIDE {
        return SkString("textblobshader");
    }

    SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(640, 480);
    }

    void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkPaint p;
        p.setStyle(SkPaint::kFill_Style);
        p.setShader(fShader);

        SkISize sz = this->onISize();
        static const int kXCount = 4;
        static const int kYCount = 3;
        for (int i = 0; i < kXCount; ++i) {
            for (int j = 0; j < kYCount; ++j) {
                canvas->drawTextBlob(fBlob,
                                     SkIntToScalar(i * sz.width() / kXCount),
                                     SkIntToScalar(j * sz.height() / kYCount),
                                     p);
            }
        }
    }

private:
    SkTDArray<uint16_t>            fGlyphs;
    SkAutoTUnref<const SkTextBlob> fBlob;
    SkAutoTUnref<SkShader>         fShader;

    typedef skiagm::GM INHERITED;
};

DEF_GM( return SkNEW_ARGS(TextBlobShaderGM, ("Blobber")); )
