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

#include "include/effects/SkTrimPathEffect.h"

#include "include/core/SkFlattenable.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPathMeasure.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkTPin.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"
#include "src/effects/SkTrimPE.h"

#include <cstddef>
#include <cstdint>

class SkMatrix;
class SkStrokeRec;
struct SkRect;

namespace {

// Returns the number of contours iterated to satisfy the request.
static size_t add_segments(const SkPath& src, SkScalar start, SkScalar stop, SkPath* dst,
                           bool requires_moveto = true) {
    SkASSERT(start < stop);

    SkPathMeasure measure(src, false);

    SkScalar current_segment_offset = 0;
    size_t            contour_count = 1;

    do {
        const auto next_offset = current_segment_offset + measure.getLength();

        if (start < next_offset) {
            measure.getSegment(start - current_segment_offset,
                               stop  - current_segment_offset,
                               dst, requires_moveto);

            if (stop <= next_offset)
                break;
        }

        contour_count++;
        current_segment_offset = next_offset;
    } while (measure.nextContour());

    return contour_count;
}

} // namespace

SkTrimPE::SkTrimPE(SkScalar startT, SkScalar stopT, SkTrimPathEffect::Mode mode)
    : fStartT(startT), fStopT(stopT), fMode(mode) {}

bool SkTrimPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
                            const SkMatrix&) const {
    if (fStartT >= fStopT) {
        SkASSERT(fMode == SkTrimPathEffect::Mode::kNormal);
        return true;
    }

    // First pass: compute the total len.
    SkScalar len = 0;
    SkPathMeasure meas(src, false);
    do {
        len += meas.getLength();
    } while (meas.nextContour());

    const auto arcStart = len * fStartT,
               arcStop  = len * fStopT;

    // Second pass: actually add segments.
    if (fMode == SkTrimPathEffect::Mode::kNormal) {
        // Normal mode -> one span.
        if (arcStart < arcStop) {
            add_segments(src, arcStart, arcStop, dst);
        }
    } else {
        // Inverted mode -> one logical span which wraps around at the end -> two actual spans.
        // In order to preserve closed path continuity:
        //
        //   1) add the second/tail span first
        //
        //   2) skip the head span move-to for single-closed-contour paths

        bool requires_moveto = true;
        if (arcStop < len) {
            // since we're adding the "tail" first, this is the total number of contours
            const auto contour_count = add_segments(src, arcStop, len, dst);

            // if the path consists of a single closed contour, we don't want to disconnect
            // the two parts with a moveto.
            if (contour_count == 1 && src.isLastContourClosed()) {
                requires_moveto = false;
            }
        }
        if (0 <  arcStart) {
            add_segments(src, 0, arcStart, dst, requires_moveto);
        }
    }

    return true;
}

void SkTrimPE::flatten(SkWriteBuffer& buffer) const {
    buffer.writeScalar(fStartT);
    buffer.writeScalar(fStopT);
    buffer.writeUInt(static_cast<uint32_t>(fMode));
}

sk_sp<SkFlattenable> SkTrimPE::CreateProc(SkReadBuffer& buffer) {
    const auto start = buffer.readScalar(),
               stop  = buffer.readScalar();
    const auto mode  = buffer.readUInt();

    return SkTrimPathEffect::Make(start, stop,
        (mode & 1) ? SkTrimPathEffect::Mode::kInverted : SkTrimPathEffect::Mode::kNormal);
}

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

sk_sp<SkPathEffect> SkTrimPathEffect::Make(SkScalar startT, SkScalar stopT, Mode mode) {
    if (!SkIsFinite(startT, stopT)) {
        return nullptr;
    }

    if (startT <= 0 && stopT >= 1 && mode == Mode::kNormal) {
        return nullptr;
    }

    startT = SkTPin(startT, 0.f, 1.f);
    stopT  = SkTPin(stopT,  0.f, 1.f);

    if (startT >= stopT && mode == Mode::kInverted) {
        return nullptr;
    }

    return sk_sp<SkPathEffect>(new SkTrimPE(startT, stopT, mode));
}
