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

 // this cheats and assumes that the perpendicular to the point is the closest ray to the curve
 // this case (where the line and the curve are nearly coincident) may be the only case that counts
double SkDCurve::nearPoint(SkPath::Verb verb, const SkDPoint& xy, const SkDPoint& opp) const {
    int count = SkPathOpsVerbToPoints(verb);
    double minX = fCubic.fPts[0].fX;
    double maxX = minX;
    for (int index = 1; index <= count; ++index) {
        minX = SkTMin(minX, fCubic.fPts[index].fX);
        maxX = SkTMax(maxX, fCubic.fPts[index].fX);
    }
    if (!AlmostBetweenUlps(minX, xy.fX, maxX)) {
        return -1;
    }
    double minY = fCubic.fPts[0].fY;
    double maxY = minY;
    for (int index = 1; index <= count; ++index) {
        minY = SkTMin(minY, fCubic.fPts[index].fY);
        maxY = SkTMax(maxY, fCubic.fPts[index].fY);
    }
    if (!AlmostBetweenUlps(minY, xy.fY, maxY)) {
        return -1;
    }
    SkIntersections i;
    SkDLine perp = {{ xy, { xy.fX + opp.fY - xy.fY, xy.fY + xy.fX - opp.fX }}};
    (*CurveDIntersectRay[verb])(*this, perp, &i);
    int minIndex = -1;
    double minDist = FLT_MAX;
    for (int index = 0; index < i.used(); ++index) {
        double dist = xy.distance(i.pt(index));
        if (minDist > dist) {
            minDist = dist;
            minIndex = index;
        }
    }
    if (minIndex < 0) {
        return -1;
    }
    double largest = SkTMax(SkTMax(maxX, maxY), -SkTMin(minX, minY));
    if (!AlmostEqualUlps_Pin(largest, largest + minDist)) { // is distance within ULPS tolerance?
        return -1;
    }
    return SkPinT(i[0][minIndex]);
}

void SkDCurve::offset(SkPath::Verb verb, const SkDVector& off) {
    int count = SkPathOpsVerbToPoints(verb);
    for (int index = 0; index < count; ++index) {
        fCubic.fPts[index] += off;
    }
}

void SkDCurve::setConicBounds(const SkPoint curve[3], SkScalar curveWeight,
        double tStart, double tEnd, SkPathOpsBounds* bounds) {
    SkDConic dCurve;
    dCurve.set(curve, curveWeight);
    SkDRect dRect;
    dRect.setBounds(dCurve, fConic, tStart, tEnd);
    bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop),
            SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
}

void SkDCurve::setCubicBounds(const SkPoint curve[4], SkScalar ,
        double tStart, double tEnd, SkPathOpsBounds* bounds) {
    SkDCubic dCurve;
    dCurve.set(curve);
    SkDRect dRect;
    dRect.setBounds(dCurve, fCubic, tStart, tEnd);
    bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop),
            SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
}

void SkDCurve::setQuadBounds(const SkPoint curve[3], SkScalar ,
        double tStart, double tEnd, SkPathOpsBounds* bounds) {
    SkDQuad dCurve;
    dCurve.set(curve);
    SkDRect dRect;
    dRect.setBounds(dCurve, fQuad, tStart, tEnd);
    bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop),
            SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
}

void SkDCurveSweep::setCurveHullSweep(SkPath::Verb verb) {
    fOrdered = true;
    fSweep[0] = fCurve[1] - fCurve[0];
    if (SkPath::kLine_Verb == verb) {
        fSweep[1] = fSweep[0];
        fIsCurve = false;
        return;
    }
    fSweep[1] = fCurve[2] - fCurve[0];
    // OPTIMIZE: I do the following float check a lot -- probably need a
    // central place for this val-is-small-compared-to-curve check
    double maxVal = 0;
    for (int index = 0; index < SkPathOpsVerbToPoints(verb); ++index) {
        maxVal = SkTMax(maxVal, SkTMax(SkTAbs(fCurve[index].fX),
                SkTAbs(fCurve[index].fY)));
    }
    {
        if (SkPath::kCubic_Verb != verb) {
            if (roughly_zero_when_compared_to(fSweep[0].fX, maxVal)
                    && roughly_zero_when_compared_to(fSweep[0].fY, maxVal)) {
                fSweep[0] = fSweep[1];
            }
            goto setIsCurve;
        }
        SkDVector thirdSweep = fCurve[3] - fCurve[0];
        if (fSweep[0].fX == 0 && fSweep[0].fY == 0) {
            fSweep[0] = fSweep[1];
            fSweep[1] = thirdSweep;
            if (roughly_zero_when_compared_to(fSweep[0].fX, maxVal)
                    && roughly_zero_when_compared_to(fSweep[0].fY, maxVal)) {
                fSweep[0] = fSweep[1];
                fCurve[1] = fCurve[3];
            }
            goto setIsCurve;
        }
        double s1x3 = fSweep[0].crossCheck(thirdSweep);
        double s3x2 = thirdSweep.crossCheck(fSweep[1]);
        if (s1x3 * s3x2 >= 0) {  // if third vector is on or between first two vectors
            goto setIsCurve;
        }
        double s2x1 = fSweep[1].crossCheck(fSweep[0]);
        // FIXME: If the sweep of the cubic is greater than 180 degrees, we're in trouble
        // probably such wide sweeps should be artificially subdivided earlier so that never happens
        SkASSERT(s1x3 * s2x1 < 0 || s1x3 * s3x2 < 0);
        if (s3x2 * s2x1 < 0) {
            SkASSERT(s2x1 * s1x3 > 0);
            fSweep[0] = fSweep[1];
            fOrdered = false;
        }
        fSweep[1] = thirdSweep;
    }
setIsCurve:
    fIsCurve = fSweep[0].crossCheck(fSweep[1]) != 0;
}
