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

#ifndef MSKPPlayer_DEFINED
#define MSKPPlayer_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"

#include <unordered_map>
#include <vector>

class SkCanvas;
class SkStreamSeekable;
class SkSurface;

/**
 * Plays frames/pages of a MSKP to a canvas. This class uses the term "frame" as though the MSKP
 * contains an animation, though it could indeed contain pages of a static document.
 */
class MSKPPlayer {
public:
    ~MSKPPlayer();

    /** Make a player from a MSKP stream, or null if stream can't be read as MSKP. */
    static std::unique_ptr<MSKPPlayer> Make(SkStreamSeekable* stream);

    /** Maximum width and height across all frames. */
    SkISize maxDimensions() const { return fMaxDimensions; }

    /** Total number of frames. */
    int numFrames() const { return static_cast<int>(fRootLayers.size()); }

    /** Size of an individual frame. */
    SkISize frameDimensions(int i) const;

    /**
     * Plays a frame into the passed canvas. Frames can be randomly accessed. Offscreen layers are
     * incrementally updated from their current state to the state required for the frame
     * (redrawing from scratch if their current state is ahead of the passed frame index).
     */
    bool playFrame(SkCanvas* canvas, int i);

    /** Destroys any cached offscreen layers. */
    void resetLayers();

    /**
     * Forces all offscreen layers to re-render the next time they're required for a frame but
     * preserves the backing stores for them if already allocated.
     */
    void rewindLayers();

    /**
     * Creates backing stores for any offscreen layers using the passed canvas's makeSurface().
     * Existing layers that match the canvas's recording context are not reallocated or rewound.
     */
    void allocateLayers(SkCanvas*);

private:
    MSKPPlayer() = default;
    // noncopyable, nonmoveable.
    MSKPPlayer(const MSKPPlayer&) = delete;
    MSKPPlayer(MSKPPlayer&&) = delete;
    MSKPPlayer& operator=(const MSKPPlayer&) = delete;
    MSKPPlayer& operator=(MSKPPlayer&&) = delete;

    // Cmds are used to draw content to the frame root layer and to offscreen layers.
    struct Cmd;
    // Draws a SkPicture.
    struct PicCmd;
    // Draws another layer. Stores the ID of the layer to draw and what command index on that
    // layer should be current when the layer is drawn. The layer contents are updated to the
    // stored command index before the layer is drawn.
    struct DrawLayerCmd;

    // The commands for a root/offscreen layer and dimensions of the layer.
    struct Layer {
        Layer() = default;
        Layer(Layer&&) = default;
        SkISize fDimensions;
        std::vector<std::unique_ptr<Cmd>> fCmds;
    };

    // Playback state of layer: the last command index drawn to it and the SkSurface with contents.
    struct LayerState {
        size_t fCurrCmd = -1;
        sk_sp<SkSurface> fSurface;
    };

    static sk_sp<SkSurface> MakeSurfaceForLayer(const Layer&, SkCanvas* rootCanvas);

    // MSKP layer ID -> Layer
    using LayerMap = std::unordered_map<int, Layer>;
    // MSKP layer ID -> LayerState
    using LayerStateMap = std::unordered_map<int, LayerState>;

    /**
     * A SkCanvas that consumes the SkPicture and records Cmds into a Layer. It will spawn
     * additional Layers and record nested SkPictures into those using additional CmdRecordCanvas
     * CmdRecordCanvas instances. It needs access to fOffscreenLayers to create and update Layer
     * structs for offscreen layers.
     */
    class CmdRecordCanvas;

    SkISize            fMaxDimensions = {0, 0};  // Max dimensions across all frames.
    LayerMap           fOffscreenLayers;         // All the offscreen layers for all frames.
    LayerStateMap      fOffscreenLayerStates;    // Current surfaces and command idx for offscreen
                                                 // layers
    std::vector<Layer> fRootLayers;              // One root layer for each frame.
};

#endif
