/*
 * 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.
 */

#ifndef ANDROID_HWUI_CANVAS_STATE_H
#define ANDROID_HWUI_CANVAS_STATE_H

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

#include "Snapshot.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 (i.e. OpenGLRenderer) 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 (i.e. DisplayListCanvas) 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 ANDROID_API CanvasState {
public:
    CanvasState(CanvasStateClient& renderer);
    ~CanvasState();

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

    void setViewport(int width, int height);

    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, SkRegion::Op op);
    bool clipPath(const SkPath* path, SkRegion::Op op);
    bool clipRegion(const SkRegion* region, SkRegion::Op 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);

    /**
     * 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 setDirtyClip(bool opaque) { mDirtyClip = opaque; }
    bool getDirtyClip() const { return mDirtyClip; }

    void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; }
    void setEmpty(bool value) { mSnapshot->empty = value; }
    void setInvisible(bool value) { mSnapshot->invisible = value; }

    inline const mat4* currentTransform() const { return currentSnapshot()->transform; }
    inline const Rect& currentClipRect() const { return currentSnapshot()->getClipRect(); }
    inline Region* currentRegion() const { return currentSnapshot()->region; }
    inline int currentFlags() const { return currentSnapshot()->flags; }
    const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); }
    inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); }
    int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); }
    int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); }
    int getWidth() { return mWidth; }
    int getHeight() { return mHeight; }

    inline const Snapshot* currentSnapshot() const {
        return mSnapshot != nullptr ? mSnapshot.get() : mFirstSnapshot.get();
    }
    inline Snapshot* writableSnapshot() { return mSnapshot.get(); }
    inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); }

private:
    /// No default constructor - must supply a CanvasStateClient (mCanvas).
    CanvasState();

    /// indicates that the clip has been changed since the last time it was consumed
    bool mDirtyClip;

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

    /// Number of saved states
    int mSaveCount;

    /// Base state
    sp<Snapshot> mFirstSnapshot;

    /// Host providing callbacks
    CanvasStateClient& mCanvas;

    /// Current state
    sp<Snapshot> mSnapshot;

}; // class CanvasState

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

#endif // ANDROID_HWUI_CANVAS_STATE_H
