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

#include "AnimTimer.h"
#include "SkAndroidCodec.h"
#include "SkAnimatedImage.h"
#include "SkCanvas.h"
#include "SkFont.h"
#include "SkPaint.h"
#include "SkPictureRecorder.h"
#include "SkRect.h"
#include "SkScalar.h"
#include "SkString.h"

#include "Sample.h"
#include "Resources.h"

static constexpr char kPauseKey = 'p';
static constexpr char kResetKey = 'r';

class SampleAnimatedImage : public Sample {
public:
    SampleAnimatedImage()
        : INHERITED()
        , fYOffset(0)
    {}

protected:
    void onDrawBackground(SkCanvas* canvas) override {
        SkFont font;
        font.setSize(20);

        SkString str = SkStringPrintf("Press '%c' to start/pause; '%c' to reset.",
                kPauseKey, kResetKey);
        const char* text = str.c_str();
        SkRect bounds;
        font.measureText(text, strlen(text), kUTF8_SkTextEncoding, &bounds);
        fYOffset = bounds.height();

        canvas->drawSimpleText(text, strlen(text), kUTF8_SkTextEncoding, 5, fYOffset, font, SkPaint());
        fYOffset *= 2;
    }

    void onDrawContent(SkCanvas* canvas) override {
        if (!fImage) {
            return;
        }

        canvas->translate(0, fYOffset);

        canvas->drawDrawable(fImage.get());
        canvas->drawDrawable(fDrawable.get(), fImage->getBounds().width(), 0);
    }

    bool onAnimate(const AnimTimer& animTimer) override {
        if (!fImage) {
            return false;
        }

        const double lastWallTime = fLastWallTime;
        fLastWallTime = animTimer.msec();

        if (fRunning) {
            fCurrentTime += fLastWallTime - lastWallTime;
            if (fCurrentTime > fTimeToShowNextFrame) {
                fTimeToShowNextFrame += fImage->decodeNextFrame();
                if (fImage->isFinished()) {
                    fRunning = false;
                }
            }
        }

        return true;
    }

    void onOnceBeforeDraw() override {
        sk_sp<SkData> file(GetResourceAsData("images/alphabetAnim.gif"));
        std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(file));
        if (!codec) {
            return;
        }

        fImage = SkAnimatedImage::Make(SkAndroidCodec::MakeFromCodec(std::move(codec)));
        if (!fImage) {
            return;
        }

        fTimeToShowNextFrame = fImage->currentFrameDuration();
        SkPictureRecorder recorder;
        auto canvas = recorder.beginRecording(fImage->getBounds());
        canvas->drawDrawable(fImage.get());
        fDrawable = recorder.finishRecordingAsDrawable();
    }

    bool onQuery(Sample::Event* evt) override {
        if (Sample::TitleQ(*evt)) {
            Sample::TitleR(evt, "AnimatedImage");
            return true;
        }

        SkUnichar uni;
        if (fImage && Sample::CharQ(*evt, &uni)) {
            switch (uni) {
                case kPauseKey:
                    fRunning = !fRunning;
                    if (fImage->isFinished()) {
                        // fall through
                    } else {
                        return true;
                    }
                case kResetKey:
                    fImage->reset();
                    fCurrentTime = fLastWallTime;
                    fTimeToShowNextFrame = fCurrentTime + fImage->currentFrameDuration();
                    return true;
                default:
                    break;
            }
        }
        return this->INHERITED::onQuery(evt);
    }

private:
    sk_sp<SkAnimatedImage>  fImage;
    sk_sp<SkDrawable>       fDrawable;
    SkScalar                fYOffset;
    bool                    fRunning = false;
    double                  fCurrentTime = 0.0;
    double                  fLastWallTime = 0.0;
    double                  fTimeToShowNextFrame = 0.0;
    typedef Sample INHERITED;
};

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

DEF_SAMPLE( return new SampleAnimatedImage(); )
