
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SampleCode.h"
#include "SkBlurMask.h"
#include "SkBlurMaskFilter.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkXfermode.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkTime.h"
#include "SkTypeface.h"
#include "SkView.h"

#include "SkOSFile.h"
#include "SkStream.h"

static void check_for_nonwhite(const SkBitmap& bm, int alpha) {
    if (bm.colorType() != kRGB_565_SkColorType) {
        return;
    }

    for (int y = 0; y < bm.height(); y++) {
        for (int x = 0; x < bm.width(); x++) {
            uint16_t c = *bm.getAddr16(x, y);
            if (c != 0xFFFF) {
                SkDebugf("------ nonwhite alpha=%x [%d %d] %x\n", alpha, x, y, c);
                return;
            }
        }
    }
}

class TextAlphaView : public SampleView {
public:
    TextAlphaView() {
        fByte = 0xFF;
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt)  {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "TextAlpha");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        const char* str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        SkPaint paint;
        SkScalar    x = SkIntToScalar(10);
        SkScalar    y = SkIntToScalar(20);

        paint.setFlags(0x105);

        paint.setARGB(fByte, 0xFF, 0xFF, 0xFF);

        paint.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
                                    SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3))));
        paint.getMaskFilter()->unref();

        SkRandom rand;

        for (int ps = 6; ps <= 35; ps++) {
            paint.setColor(rand.nextU() | (0xFF << 24));
            paint.setTextSize(SkIntToScalar(ps));
            paint.setTextSize(SkIntToScalar(24));
            canvas->drawText(str, strlen(str), x, y, paint);
            y += paint.getFontMetrics(NULL);
        }
        if (false) { // avoid bit rot, suppress warning
            check_for_nonwhite(canvas->getDevice()->accessBitmap(false), fByte);
            SkDebugf("------ byte %x\n", fByte);
        }

        if (false) {
            fByte += 1;
            fByte &= 0xFF;
            this->inval(NULL);
        }
    }

    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) SK_OVERRIDE {
        return new Click(this);
    }

    virtual bool onClick(Click* click) {
        int y = click->fICurr.fY;
        if (y < 0) {
            y = 0;
        } else if (y > 255) {
            y = 255;
        }
        fByte = y;
        this->inval(NULL);
        return true;
    }

private:
    int fByte;

    typedef SampleView INHERITED;
};

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

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