/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkPathOpsPoint.h"
#include "SkPathWriter.h"

// wrap path to keep track of whether the contour is initialized and non-empty
SkPathWriter::SkPathWriter(SkPath& path)
    : fPathPtr(&path)
    , fCloses(0)
    , fMoves(0)
{
    init();
}

void SkPathWriter::close() {
    if (!fHasMove) {
        return;
    }
    bool callClose = isClosed();
    lineTo();
    if (fEmpty) {
        return;
    }
    if (callClose) {
#if DEBUG_PATH_CONSTRUCTION
        SkDebugf("path.close();\n");
#endif
        fPathPtr->close();
        fCloses++;
    }
    init();
}

void SkPathWriter::cubicTo(const SkPoint& pt1, const SkPoint& pt2, const SkPoint& pt3) {
    lineTo();
    if (fEmpty && AlmostEqualUlps(fDefer[0], pt1) && AlmostEqualUlps(pt1, pt2)
            && AlmostEqualUlps(pt2, pt3)) {
        deferredLine(pt3);
        return;
    }
    moveTo();
    fDefer[1] = pt3;
    nudge();
    fDefer[0] = fDefer[1];
#if DEBUG_PATH_CONSTRUCTION
    SkDebugf("path.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.9g);\n",
            pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY);
#endif
    fPathPtr->cubicTo(pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY);
    fEmpty = false;
}

void SkPathWriter::deferredLine(const SkPoint& pt) {
    if (pt == fDefer[1]) {
        return;
    }
    if (changedSlopes(pt)) {
        lineTo();
        fDefer[0] = fDefer[1];
    }
    fDefer[1] = pt;
}

void SkPathWriter::deferredMove(const SkPoint& pt) {
    fMoved = true;
    fHasMove = true;
    fEmpty = true;
    fDefer[0] = fDefer[1] = pt;
}

void SkPathWriter::deferredMoveLine(const SkPoint& pt) {
    if (!fHasMove) {
        deferredMove(pt);
    }
    deferredLine(pt);
}

bool SkPathWriter::hasMove() const {
    return fHasMove;
}

void SkPathWriter::init() {
    fEmpty = true;
    fHasMove = false;
    fMoved = false;
}

bool SkPathWriter::isClosed() const {
    return !fEmpty && fFirstPt == fDefer[1];
}

void SkPathWriter::lineTo() {
    if (fDefer[0] == fDefer[1]) {
        return;
    }
    moveTo();
    nudge();
    fEmpty = false;
#if DEBUG_PATH_CONSTRUCTION
    SkDebugf("path.lineTo(%1.9g,%1.9g);\n", fDefer[1].fX, fDefer[1].fY);
#endif
    fPathPtr->lineTo(fDefer[1].fX, fDefer[1].fY);
    fDefer[0] = fDefer[1];
}

const SkPath* SkPathWriter::nativePath() const {
    return fPathPtr;
}

void SkPathWriter::nudge() {
    if (fEmpty || !AlmostEqualUlps(fDefer[1].fX, fFirstPt.fX)
            || !AlmostEqualUlps(fDefer[1].fY, fFirstPt.fY)) {
        return;
    }
    fDefer[1] = fFirstPt;
}

void SkPathWriter::quadTo(const SkPoint& pt1, const SkPoint& pt2) {
    lineTo();
    if (fEmpty && AlmostEqualUlps(fDefer[0], pt1) && AlmostEqualUlps(pt1, pt2)) {
        deferredLine(pt2);
        return;
    }
    moveTo();
    fDefer[1] = pt2;
    nudge();
    fDefer[0] = fDefer[1];
#if DEBUG_PATH_CONSTRUCTION
    SkDebugf("path.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n",
            pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY);
#endif
    fPathPtr->quadTo(pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY);
    fEmpty = false;
}

bool SkPathWriter::someAssemblyRequired() const {
    return fCloses < fMoves;
}

bool SkPathWriter::changedSlopes(const SkPoint& pt) const {
    if (fDefer[0] == fDefer[1]) {
        return false;
    }
    SkScalar deferDx = fDefer[1].fX - fDefer[0].fX;
    SkScalar deferDy = fDefer[1].fY - fDefer[0].fY;
    SkScalar lineDx = pt.fX - fDefer[1].fX;
    SkScalar lineDy = pt.fY - fDefer[1].fY;
    return deferDx * lineDy != deferDy * lineDx;
}

void SkPathWriter::moveTo() {
    if (!fMoved) {
        return;
    }
    fFirstPt = fDefer[0];
#if DEBUG_PATH_CONSTRUCTION
    SkDebugf("path.moveTo(%1.9g,%1.9g);\n", fDefer[0].fX, fDefer[0].fY);
#endif
    fPathPtr->moveTo(fDefer[0].fX, fDefer[0].fY);
    fMoved = false;
    fMoves++;
}
