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

#include "src/utils/SkCanvasStack.h"

#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/private/base/SkTDArray.h"
#include <utility>

class SkPath;
class SkRRect;

SkCanvasStack::SkCanvasStack(int width, int height)
        : INHERITED(width, height) {}

SkCanvasStack::~SkCanvasStack() {
    this->removeAll();
}

void SkCanvasStack::pushCanvas(std::unique_ptr<SkCanvas> canvas, const SkIPoint& origin) {
    if (canvas) {
        // compute the bounds of this canvas
        const SkIRect canvasBounds = SkIRect::MakeSize(canvas->getBaseLayerSize());

        // push the canvas onto the stack
        this->INHERITED::addCanvas(canvas.get());

        // push the canvas data onto the stack
        CanvasData* data = &fCanvasData.push_back();
        data->origin = origin;
        data->requiredClip.setRect(canvasBounds);
        data->ownedCanvas = std::move(canvas);

        // subtract this region from the canvas objects already on the stack.
        // This ensures they do not draw into the space occupied by the layers
        // above them.
        for (int i = fList.size() - 1; i > 0; --i) {
            SkIRect localBounds = canvasBounds;
            localBounds.offset(origin - fCanvasData[i-1].origin);

            fCanvasData[i-1].requiredClip.op(localBounds, SkRegion::kDifference_Op);
            fList[i-1]->clipRegion(fCanvasData[i-1].requiredClip);
        }
    }
    SkASSERT(fList.size() == fCanvasData.size());
}

void SkCanvasStack::removeAll() {
    this->INHERITED::removeAll();   // call the baseclass *before* we actually delete the canvases
    fCanvasData.clear();
}

/**
 * Traverse all canvases (e.g. layers) the stack and ensure that they are clipped
 * to their bounds and that the area covered by any canvas higher in the stack is
 * also clipped out.
 */
void SkCanvasStack::clipToZOrderedBounds() {
    SkASSERT(fList.size() == fCanvasData.size());
    for (int i = 0; i < fList.size(); ++i) {
        fList[i]->clipRegion(fCanvasData[i].requiredClip);
    }
}

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

/**
 * We need to handle setMatrix specially as it overwrites the matrix in each
 * canvas unlike all other matrix operations (i.e. translate, scale, etc) which
 * just pre-concatenate with the existing matrix.
 */
void SkCanvasStack::didSetM44(const SkM44& mx) {
    SkASSERT(fList.size() == fCanvasData.size());
    for (int i = 0; i < fList.size(); ++i) {
        fList[i]->setMatrix(SkM44::Translate(SkIntToScalar(-fCanvasData[i].origin.x()),
                                             SkIntToScalar(-fCanvasData[i].origin.y())) * mx);
    }
    this->SkCanvas::didSetM44(mx);
}

void SkCanvasStack::onClipRect(const SkRect& r, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->INHERITED::onClipRect(r, op, edgeStyle);
    this->clipToZOrderedBounds();
}

void SkCanvasStack::onClipRRect(const SkRRect& rr, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->INHERITED::onClipRRect(rr, op, edgeStyle);
    this->clipToZOrderedBounds();
}

void SkCanvasStack::onClipPath(const SkPath& p, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->INHERITED::onClipPath(p, op, edgeStyle);
    this->clipToZOrderedBounds();
}

void SkCanvasStack::onClipShader(sk_sp<SkShader> cs, SkClipOp op) {
    this->INHERITED::onClipShader(std::move(cs), op);
    // we don't change the "bounds" of the clip, so we don't need to update zorder
}

void SkCanvasStack::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
    SkASSERT(fList.size() == fCanvasData.size());
    for (int i = 0; i < fList.size(); ++i) {
        SkRegion tempRegion;
        deviceRgn.translate(-fCanvasData[i].origin.x(),
                            -fCanvasData[i].origin.y(), &tempRegion);
        tempRegion.op(fCanvasData[i].requiredClip, SkRegion::kIntersect_Op);
        fList[i]->clipRegion(tempRegion, op);
    }
    this->SkCanvas::onClipRegion(deviceRgn, op);
}
