
/*
 * 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 "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 "SkTime.h"
#include "SkTypeface.h"

#include "SkImageRef_GlobalPool.h"
#include "SkStream.h"

static const char* gNames[] = {
    "1.bmp", "1.gif", "1.jpg", "1.png",
    "2.bmp", "2.gif", "2.jpg", "2.png"
};

static bool SetImageRef(SkBitmap* bitmap, SkStream* stream,
                        SkBitmap::Config pref, const char name[] = NULL)
{
    if (SkImageDecoder::DecodeStream(stream, bitmap, pref,
                                 SkImageDecoder::kDecodeBounds_Mode, NULL)) {
        SkASSERT(bitmap->config() != SkBitmap::kNo_Config);
    
        SkImageRef* ref = new SkImageRef_GlobalPool(stream, bitmap->config());
        ref->setURI(name);
        bitmap->setPixelRef(ref)->unref();
        return true;
    } else {
        return false;
    }
}

class ImageView : public SkView {
public:
    SkBitmap*   fBitmaps;
    SkShader*   fShader;

	ImageView() {
        SkImageRef_GlobalPool::SetRAMBudget(32 * 1024);
        
        int i, N = SK_ARRAY_COUNT(gNames);
        fBitmaps = new SkBitmap[N];
        
        for (i = 0; i < N; i++) {
            SkString str("/skimages/");
            str.append(gNames[i]);
            SkFILEStream* stream = new SkFILEStream(str.c_str());
            
            SetImageRef(&fBitmaps[i], stream, SkBitmap::kNo_Config, gNames[i]);
            if (i & 1)
                fBitmaps[i].buildMipMap();
            stream->unref();
        }
        
        fShader = SkShader::CreateBitmapShader(fBitmaps[5],
                                               SkShader::kRepeat_TileMode,
                                               SkShader::kRepeat_TileMode);
        
        if (true) {
            SkMatrix m;
            
            m.setRotate(SkIntToScalar(30));
            fShader->setLocalMatrix(m);
        }
        
#if 0
        SkImageRef::DumpPool();
        for (i = 0; i < N; i++) {
            SkBitmap& bm = fBitmaps[i];

            SkDebugf("<%s> addr=%p", gNames[i], bm.getPixels());
            bool success = bm.lockPixels();
            SkDebugf(" addr=%d", bm.getPixels());
            if (success)
                bm.unlockPixels();
            SkDebugf(" addr=%p", bm.getPixels());
            success = bm.lockPixels();
            SkDebugf(" addr=%d", bm.getPixels());
            if (success)
                bm.unlockPixels();            
            SkDebugf("\n");
        }
        SkImageRef::DumpPool();
#endif
    }
    
    virtual ~ImageView() {
        delete[] fBitmaps;
        delete fShader;

        SkImageRef_GlobalPool::DumpPool();
    }
    
protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Image");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }
    
    void drawBG(SkCanvas* canvas) {
        canvas->drawColor(0xFFDDDDDD);
//        canvas->drawColor(SK_ColorWHITE);
    }
    
    virtual void onDraw(SkCanvas* canvas) {
        this->drawBG(canvas);
        
        canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
        
        SkScalar x = 0, y = 0;
        
        for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); i++) {
            canvas->drawBitmap(fBitmaps[i], x, y);
            x += SkIntToScalar(fBitmaps[i].width() + 10);
        }
        
        canvas->translate(0, SkIntToScalar(120));

        SkPaint paint;
        paint.setShader(fShader);
        paint.setFilterBitmap(true);
        SkRect r = { 0, 0, SkIntToScalar(300), SkIntToScalar(100) };
        
        canvas->drawRect(r, paint);
    }
    
    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
        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 ImageView; }
static SkViewRegister reg(MyFactory);

