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

#include "include/core/SkTypes.h"
#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRegion.h"
#include "include/core/SkScalar.h"
#include "include/utils/SkCanvasStateUtils.h"
#include "tests/CanvasStateHelpers.h"

#include <memory>

void complex_layers_draw(SkCanvas* canvas, float left, float top,
                         float right, float bottom, int32_t spacer) {
    SkPaint bluePaint;
    bluePaint.setColor(SK_ColorBLUE);
    bluePaint.setStyle(SkPaint::kFill_Style);

    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
    canvas->drawRect(rect, bluePaint);
    canvas->translate(0, rect.height() + spacer);
    canvas->drawRect(rect, bluePaint);
}

extern "C" bool complex_layers_draw_from_canvas_state(SkCanvasState* state,
        float left, float top, float right, float bottom, int32_t spacer) {
    std::unique_ptr<SkCanvas> canvas = SkCanvasStateUtils::MakeFromCanvasState(state);
    if (!canvas) {
        return false;
    }
    complex_layers_draw(canvas.get(), left, top, right, bottom, spacer);
    return true;
}

void complex_clips_draw(SkCanvas* canvas, int32_t left, int32_t top,
        int32_t right, int32_t bottom, int32_t clipOp, const SkRegion& localRegion) {
    canvas->save();
    SkRect clipRect = SkRect::MakeLTRB(SkIntToScalar(left), SkIntToScalar(top),
                                       SkIntToScalar(right), SkIntToScalar(bottom));
    canvas->clipRect(clipRect, (SkRegion::Op) clipOp);
    canvas->drawColor(SK_ColorBLUE);
    canvas->restore();

    canvas->clipRegion(localRegion, (SkClipOp) clipOp);
    canvas->drawColor(SK_ColorBLUE);
}

extern "C" bool complex_clips_draw_from_canvas_state(SkCanvasState* state,
        int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t clipOp,
        int32_t regionRects, int32_t* rectCoords) {
    std::unique_ptr<SkCanvas> canvas = SkCanvasStateUtils::MakeFromCanvasState(state);
    if (!canvas) {
        return false;
    }

    SkRegion localRegion;
    for (int32_t i = 0; i < regionRects; ++i) {
        localRegion.op(rectCoords[0], rectCoords[1], rectCoords[2], rectCoords[3],
                       SkRegion::kUnion_Op);
        rectCoords += 4;
    }

    complex_clips_draw(canvas.get(), left, top, right, bottom, clipOp, localRegion);
    return true;
}
#endif // SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
