/*
 * 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 "DecodeFile.h"
#include "SampleCode.h"
#include "SkDumpCanvas.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkOSFile.h"
#include "SkPath.h"
#include "SkPicture.h"
#include "SkPictureRecorder.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 "SkSurface.h"

#include "SkGlyphCache.h"

#include "SkDrawFilter.h"
class SkCounterDrawFilter : public SkDrawFilter {
public:
    SkCounterDrawFilter(int count) : fCount(count) {}

    bool filter(SkPaint*, Type t) override {
        return --fCount >= 0;
    }

    int fCount;
};

class PictFileView : public SampleView {
public:
    PictFileView(const char name[] = nullptr)
        : fFilename(name)
        , fBBox(kNo_BBoxType)
        , fTileSize(SkSize::Make(0, 0)) {
        for (int i = 0; i < kBBoxTypeCount; ++i) {
            fPictures[i] = nullptr;
        }
        fCount = 0;
    }

    ~PictFileView() override {
        this->freePictures();
    }
    
    void freePictures() {
        for (int i = 0; i < kBBoxTypeCount; ++i) {
            SkSafeUnref(fPictures[i]);
            fPictures[i] = nullptr;
        }
    }

    void onTileSizeChanged(const SkSize &tileSize) override {
        if (tileSize != fTileSize) {
            fTileSize = tileSize;
        }
    }

protected:
    // overrides from SkEventSink
    bool onQuery(SkEvent* evt) override {
        if (SampleCode::TitleQ(*evt)) {
            SkString name("P:");
            const char* basename = strrchr(fFilename.c_str(), SkPATH_SEPARATOR);
            name.append(basename ? basename+1: fFilename.c_str());
            switch (fBBox) {
            case kNo_BBoxType:
                // No name appended
                break;
            case kRTree_BBoxType:
                name.append(" <bbox: R>");
                break;
            default:
                SkASSERT(false);
                break;
            }
            SampleCode::TitleR(evt, name.c_str());
            return true;
        }
        SkUnichar uni;
        if (SampleCode::CharQ(*evt, &uni)) {
            switch (uni) {
                case 'n': fCount += 1; this->inval(nullptr); return true;
                case 'p': fCount -= 1; this->inval(nullptr); return true;
                case 's': fCount =  0; this->inval(nullptr); return true;
                case 'F':
                    fFilterQuality = (kNone_SkFilterQuality == fFilterQuality) ?
                                     kHigh_SkFilterQuality : kNone_SkFilterQuality;
                    this->freePictures();
                    this->inval(nullptr);
                    return true;
                default: break;
            }
        }
        return this->INHERITED::onQuery(evt);
    }

    bool onEvent(const SkEvent& evt) override {
        if (evt.isType("PictFileView::toggleBBox")) {
            fBBox = (BBoxType)((fBBox + 1) % kBBoxTypeCount);
            return true;
        }
        return this->INHERITED::onEvent(evt);
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkASSERT(static_cast<int>(fBBox) < kBBoxTypeCount);
        SkPicture** picture = fPictures + fBBox;

#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
        SkGraphics::PurgeFontCache();
#endif

        if (!*picture) {
            *picture = LoadPicture(fFilename.c_str(), fBBox).release();
        }
        if (*picture) {
            SkCounterDrawFilter filter(fCount);
            if (fCount > 0) {
                canvas->setDrawFilter(&filter);
            }
            canvas->drawPicture(*picture);
            canvas->setDrawFilter(nullptr);
        }

#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
        SkGlyphCache::Dump();
        SkDebugf("\n");
#endif
    }

private:
    enum BBoxType {
        kNo_BBoxType,
        kRTree_BBoxType,

        kLast_BBoxType = kRTree_BBoxType,
    };
    static const int kBBoxTypeCount = kLast_BBoxType + 1;

    SkString    fFilename;
    SkPicture*  fPictures[kBBoxTypeCount];
    BBoxType    fBBox;
    SkSize      fTileSize;
    int         fCount;
    SkFilterQuality fFilterQuality = kNone_SkFilterQuality;

    sk_sp<SkPicture> LoadPicture(const char path[], BBoxType bbox) {
        sk_sp<SkPicture> pic;

        if (sk_sp<SkImage> img = decode_file(path)) {
            SkPictureRecorder recorder;
            SkCanvas* can = recorder.beginRecording(SkIntToScalar(img->width()),
                                                    SkIntToScalar(img->height()),
                                                    nullptr, 0);
            SkPaint paint;
            paint.setFilterQuality(fFilterQuality);
            can->drawImage(img, 0, 0, &paint);
            pic = recorder.finishRecordingAsPicture();
        } else {
            SkFILEStream stream(path);
            if (stream.isValid()) {
                pic = SkPicture::MakeFromStream(&stream);
            } else {
                SkDebugf("coun't load picture at \"path\"\n", path);
            }

            if (false) { // re-record
                SkPictureRecorder recorder;
                pic->playback(recorder.beginRecording(pic->cullRect().width(),
                                                      pic->cullRect().height(),
                                                      nullptr, 0));
                sk_sp<SkPicture> p2(recorder.finishRecordingAsPicture());

                SkString path2(path);
                path2.append(".new.skp");
                SkFILEWStream writer(path2.c_str());
                p2->serialize(&writer);
            }
        }

        if (nullptr == pic) {
            return nullptr;
        }

        SkAutoTDelete<SkBBHFactory> factory;
        switch (bbox) {
        case kNo_BBoxType:
            // no bbox playback necessary
            return pic;
        case kRTree_BBoxType:
            factory.reset(new SkRTreeFactory);
            break;
        default:
            SkASSERT(false);
        }

        SkPictureRecorder recorder;
        pic->playback(recorder.beginRecording(pic->cullRect().width(),
                                              pic->cullRect().height(),
                                              factory.get(), 0));
        return recorder.finishRecordingAsPicture();
    }

    typedef SampleView INHERITED;
};

SampleView* CreateSamplePictFileView(const char filename[]);
SampleView* CreateSamplePictFileView(const char filename[]) {
    return new PictFileView(filename);
}

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

#if 0
static SkView* MyFactory() { return new PictFileView; }
static SkViewRegister reg(MyFactory);
#endif
