/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "Snapshot.h"

#include <SkClipOp.h>
#include <SkMatrix.h>
#include <SkPath.h>
#include <SkRegion.h>

namespace android {
namespace uirenderer {

/**
 * Abstract base class for any class containing CanvasState.
 * Defines three mandatory callbacks.
 */
class CanvasStateClient {
public:
    CanvasStateClient() {}
    virtual ~CanvasStateClient() {}

    /**
     * Callback allowing embedder to take actions in the middle of a
     * setViewport() call.
     */
    virtual void onViewportInitialized() = 0;

    /**
     * Callback allowing embedder to take actions in the middle of a
     * restore() call.  May be called several times sequentially.
     */
    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0;

    /**
     * Allows subclasses to control what value is stored in snapshot's
     * fbo field in * initializeSaveStack.
     */
    virtual GLuint getTargetFbo() const = 0;

};  // class CanvasStateClient

/**
 * Implements Canvas state methods on behalf of Renderers.
 *
 * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the
 * Renderer interface. Drawing and recording classes that include a CanvasState will have
 * different use cases:
 *
 * Drawing code maintaining canvas state (e.g. FrameBuilder) can query attributes (such as
 * transform) or hook into changes (e.g. save/restore) with minimal surface area for manipulating
 * the stack itself.
 *
 * Recording code maintaining canvas state (e.g. RecordingCanvas) can both record and pass
 * through state operations to CanvasState, so that not only will querying operations work
 * (getClip/Matrix), but so that quickRejection can also be used.
 */

class CanvasState {
public:
    explicit CanvasState(CanvasStateClient& renderer);
    ~CanvasState();

    /**
     * Initializes the first snapshot, computing the projection matrix,
     * and stores the dimensions of the render target.
     */
    void initializeRecordingSaveStack(int viewportWidth, int viewportHeight);

    /**
     * Initializes the first snapshot, computing the projection matrix,
     * and stores the dimensions of the render target.
     */
    void initializeSaveStack(int viewportWidth, int viewportHeight, float clipLeft, float clipTop,
                             float clipRight, float clipBottom, const Vector3& lightCenter);

    bool hasRectToRectTransform() const { return CC_LIKELY(currentTransform()->rectToRect()); }

    // Save (layer)
    int getSaveCount() const { return mSaveCount; }
    int save(int flags);
    void restore();
    void restoreToCount(int saveCount);

    // Save/Restore without side-effects
    int saveSnapshot(int flags);
    void restoreSnapshot();

    // Matrix
    void getMatrix(SkMatrix* outMatrix) const;
    void translate(float dx, float dy, float dz = 0.0f);
    void rotate(float degrees);
    void scale(float sx, float sy);
    void skew(float sx, float sy);

    void setMatrix(const SkMatrix& matrix);
    void setMatrix(const Matrix4& matrix);  // internal only convenience method
    void concatMatrix(const SkMatrix& matrix);
    void concatMatrix(const Matrix4& matrix);  // internal only convenience method

    // Clip
    const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); }
    const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); }

    bool quickRejectConservative(float left, float top, float right, float bottom) const;

    bool clipRect(float left, float top, float right, float bottom, SkClipOp op);
    bool clipPath(const SkPath* path, SkClipOp op);

    /**
     * Sets a "clipping outline", which is independent from the regular clip.
     * Currently only supports rectangles or rounded rectangles; passing in a
     * more complicated outline fails silently. Replaces any previous clipping
     * outline.
     */
    void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
    void setClippingRoundRect(LinearAllocator& allocator, const Rect& rect, float radius,
                              bool highPriority = true) {
        mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority);
    }
    void setProjectionPathMask(const SkPath* path) { mSnapshot->setProjectionPathMask(path); }

    /**
     * Returns true if drawing in the rectangle (left, top, right, bottom)
     * will be clipped out. Is conservative: might return false when subpixel-
     * perfect tests would return true.
     */
    bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
                                        bool* clipRequired, bool* roundRectClipRequired,
                                        bool snapOut) const;

    void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; }

    inline const mat4* currentTransform() const { return currentSnapshot()->transform; }
    inline const Rect& currentRenderTargetClip() const {
        return currentSnapshot()->getRenderTargetClip();
    }
    inline int currentFlags() const { return currentSnapshot()->flags; }
    const Vector3& currentLightCenter() const {
        return currentSnapshot()->getRelativeLightCenter();
    }
    int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); }
    int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); }
    int getWidth() const { return mWidth; }
    int getHeight() const { return mHeight; }
    bool clipIsSimple() const { return currentSnapshot()->clipIsSimple(); }

    inline const Snapshot* currentSnapshot() const { return mSnapshot; }
    inline Snapshot* writableSnapshot() { return mSnapshot; }
    inline const Snapshot* firstSnapshot() const { return &mFirstSnapshot; }

private:
    Snapshot* allocSnapshot(Snapshot* previous, int savecount);
    void freeSnapshot(Snapshot* snapshot);
    void freeAllSnapshots();

    /// Dimensions of the drawing surface
    int mWidth, mHeight;

    /// Number of saved states
    int mSaveCount;

    /// Base state
    Snapshot mFirstSnapshot;

    /// Host providing callbacks
    CanvasStateClient& mCanvas;

    /// Current state
    Snapshot* mSnapshot;

    // Pool of allocated snapshots to re-use
    // NOTE: The dtors have already been invoked!
    Snapshot* mSnapshotPool = nullptr;
    int mSnapshotPoolCount = 0;

};  // class CanvasState

};  // namespace uirenderer
};  // namespace android
