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