/*
 * 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 "include/core/SkCanvas.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "src/core/SkArenaAlloc.h"

#ifdef SK_SUPPORT_LEGACY_DRAWLOOPER

#include "include/core/SkDrawLooper.h"

void SkDrawLooper::Context::Info::applyToCTM(SkMatrix* ctm) const {
    if (fApplyPostCTM) {
        ctm->postTranslate(fTranslate.fX, fTranslate.fY);
    } else {
        ctm->preTranslate(fTranslate.fX, fTranslate.fY);
    }
}

void SkDrawLooper::Context::Info::applyToCanvas(SkCanvas* canvas) const {
    if (fApplyPostCTM) {
        canvas->setMatrix(canvas->getLocalToDevice().postTranslate(fTranslate.fX, fTranslate.fY));
    } else {
        canvas->translate(fTranslate.fX, fTranslate.fY);
    }
}

bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const {
    SkSTArenaAlloc<48> alloc;

    SkDrawLooper::Context* context = this->makeContext(&alloc);
    for (;;) {
        SkPaint p(paint);
        SkDrawLooper::Context::Info info;
        if (context->next(&info, &p)) {
            if (!p.canComputeFastBounds()) {
                return false;
            }
        } else {
            break;
        }
    }
    return true;
}

void SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& s,
                                     SkRect* dst) const {
    // src and dst rects may alias and we need to keep the original src, so copy it.
    const SkRect src = s;

    SkSTArenaAlloc<48> alloc;

    *dst = src;   // catch case where there are no loops
    SkDrawLooper::Context* context = this->makeContext(&alloc);

    for (bool firstTime = true;; firstTime = false) {
        SkPaint p(paint);
        SkDrawLooper::Context::Info info;
        if (context->next(&info, &p)) {
            SkRect r(src);

            p.computeFastBounds(r, &r);
            r.offset(info.fTranslate.fX, info.fTranslate.fY);

            if (firstTime) {
                *dst = r;
            } else {
                dst->join(r);
            }
        } else {
            break;
        }
    }
}

bool SkDrawLooper::asABlurShadow(BlurShadowRec*) const {
    return false;
}

void SkDrawLooper::apply(SkCanvas* canvas, const SkPaint& paint,
                         std::function<void(SkCanvas*, const SkPaint&)> proc) {
    SkSTArenaAlloc<256> alloc;
    Context* ctx = this->makeContext(&alloc);
    if (ctx) {
        Context::Info info;
        for (;;) {
            SkPaint p = paint;
            if (!ctx->next(&info, &p)) {
                break;
            }
            canvas->save();
            if (info.fApplyPostCTM) {
                canvas->setMatrix(canvas->getLocalToDevice().postTranslate(info.fTranslate.fX,
                                                                           info.fTranslate.fY));
            } else {
                canvas->translate(info.fTranslate.fX, info.fTranslate.fY);
            }
            proc(canvas, p);
            canvas->restore();
        }
    }
}

#endif
