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

#include "SkIntersections.h"

#ifndef SK_RELEASE
#include "SkPath.h"
#endif

struct SkPathOpsBounds;

struct SkOpCurve {
    SkPoint fPts[4];
    SkScalar fWeight;
    SkDEBUGCODE(SkPath::Verb fVerb);

    const SkPoint& operator[](int n) const {
        SkASSERT(n >= 0 && n <= SkPathOpsVerbToPoints(fVerb));
        return fPts[n];
    }

    void dump() const;

    void set(const SkDQuad& quad) {
        for (int index = 0; index < SkDQuad::kPointCount; ++index) {
            fPts[index] = quad[index].asSkPoint();
        }
        SkDEBUGCODE(fWeight = 1);
        SkDEBUGCODE(fVerb = SkPath::kQuad_Verb);
    }

    void set(const SkDCubic& cubic) {
        for (int index = 0; index < SkDCubic::kPointCount; ++index) {
            fPts[index] = cubic[index].asSkPoint();
        }
        SkDEBUGCODE(fWeight = 1);
        SkDEBUGCODE(fVerb = SkPath::kCubic_Verb);
    }

};

struct SkDCurve {
    union {
        SkDLine fLine;
        SkDQuad fQuad;
        SkDConic fConic;
        SkDCubic fCubic;
    };
    SkDEBUGCODE(SkPath::Verb fVerb);

    const SkDPoint& operator[](int n) const {
        SkASSERT(n >= 0 && n <= SkPathOpsVerbToPoints(fVerb));
        return fCubic[n];
    }

    SkDPoint& operator[](int n) {
        SkASSERT(n >= 0 && n <= SkPathOpsVerbToPoints(fVerb));
        return fCubic[n];
    }

    SkDPoint conicTop(const SkPoint curve[3], SkScalar curveWeight,
                      double s, double e, double* topT);
    SkDPoint cubicTop(const SkPoint curve[4], SkScalar , double s, double e, double* topT);
    void dump() const;
    void dumpID(int ) const;
    SkDPoint lineTop(const SkPoint[2], SkScalar , double , double , double* topT);
    double nearPoint(SkPath::Verb verb, const SkDPoint& xy, const SkDPoint& opp) const;
    void offset(SkPath::Verb verb, const SkDVector& );
    SkDPoint quadTop(const SkPoint curve[3], SkScalar , double s, double e, double* topT);

    void setConicBounds(const SkPoint curve[3], SkScalar curveWeight,
                        double s, double e, SkPathOpsBounds* );
    void setCubicBounds(const SkPoint curve[4], SkScalar ,
                        double s, double e, SkPathOpsBounds* );
    void setQuadBounds(const SkPoint curve[3], SkScalar ,
                       double s, double e, SkPathOpsBounds*);
};

class SkDCurveSweep {
public:
    bool isCurve() const { return fIsCurve; }
    bool isOrdered() const { return fOrdered; }
    void setCurveHullSweep(SkPath::Verb verb);

    SkDCurve fCurve;
    SkDVector fSweep[2];
private:
    bool fIsCurve;
    bool fOrdered;  // cleared when a cubic's control point isn't between the sweep vectors

};

extern SkDPoint (SkDCurve::* const Top[])(const SkPoint curve[], SkScalar cWeight,
    double tStart, double tEnd, double* topT);

static SkDPoint dline_xy_at_t(const SkPoint a[2], SkScalar , double t) {
    SkDLine line;
    line.set(a);
    return line.ptAtT(t);
}

static SkDPoint dquad_xy_at_t(const SkPoint a[3], SkScalar , double t) {
    SkDQuad quad;
    quad.set(a);
    return quad.ptAtT(t);
}

static SkDPoint dconic_xy_at_t(const SkPoint a[3], SkScalar weight, double t) {
    SkDConic conic;
    conic.set(a, weight);
    return conic.ptAtT(t);
}

static SkDPoint dcubic_xy_at_t(const SkPoint a[4], SkScalar , double t) {
    SkDCubic cubic;
    cubic.set(a);
    return cubic.ptAtT(t);
}

static SkDPoint (* const CurveDPointAtT[])(const SkPoint[], SkScalar , double ) = {
    nullptr,
    dline_xy_at_t,
    dquad_xy_at_t,
    dconic_xy_at_t,
    dcubic_xy_at_t
};

static SkDPoint ddline_xy_at_t(const SkDCurve& c, double t) {
    return c.fLine.ptAtT(t);
}

static SkDPoint ddquad_xy_at_t(const SkDCurve& c, double t) {
    return c.fQuad.ptAtT(t);
}

static SkDPoint ddconic_xy_at_t(const SkDCurve& c, double t) {
    return c.fConic.ptAtT(t);
}

static SkDPoint ddcubic_xy_at_t(const SkDCurve& c, double t) {
    return c.fCubic.ptAtT(t);
}

static SkDPoint (* const CurveDDPointAtT[])(const SkDCurve& , double ) = {
    nullptr,
    ddline_xy_at_t,
    ddquad_xy_at_t,
    ddconic_xy_at_t,
    ddcubic_xy_at_t
};

static SkPoint fline_xy_at_t(const SkPoint a[2], SkScalar weight, double t) {
    return dline_xy_at_t(a, weight, t).asSkPoint();
}

static SkPoint fquad_xy_at_t(const SkPoint a[3], SkScalar weight, double t) {
    return dquad_xy_at_t(a, weight, t).asSkPoint();
}

static SkPoint fconic_xy_at_t(const SkPoint a[3], SkScalar weight, double t) {
    return dconic_xy_at_t(a, weight, t).asSkPoint();
}

static SkPoint fcubic_xy_at_t(const SkPoint a[4], SkScalar weight, double t) {
    return dcubic_xy_at_t(a, weight, t).asSkPoint();
}

static SkPoint (* const CurvePointAtT[])(const SkPoint[], SkScalar , double ) = {
    nullptr,
    fline_xy_at_t,
    fquad_xy_at_t,
    fconic_xy_at_t,
    fcubic_xy_at_t
};

static SkDVector dline_dxdy_at_t(const SkPoint a[2], SkScalar , double ) {
    SkDLine line;
    line.set(a);
    return line[1] - line[0];
}

static SkDVector dquad_dxdy_at_t(const SkPoint a[3], SkScalar , double t) {
    SkDQuad quad;
    quad.set(a);
    return quad.dxdyAtT(t);
}

static SkDVector dconic_dxdy_at_t(const SkPoint a[3], SkScalar weight, double t) {
    SkDConic conic;
    conic.set(a, weight);
    return conic.dxdyAtT(t);
}

static SkDVector dcubic_dxdy_at_t(const SkPoint a[4], SkScalar , double t) {
    SkDCubic cubic;
    cubic.set(a);
    return cubic.dxdyAtT(t);
}

static SkDVector (* const CurveDSlopeAtT[])(const SkPoint[], SkScalar , double ) = {
    nullptr,
    dline_dxdy_at_t,
    dquad_dxdy_at_t,
    dconic_dxdy_at_t,
    dcubic_dxdy_at_t
};

static SkDVector ddline_dxdy_at_t(const SkDCurve& c, double ) {
    return c.fLine.fPts[1] - c.fLine.fPts[0];
}

static SkDVector ddquad_dxdy_at_t(const SkDCurve& c, double t) {
    return c.fQuad.dxdyAtT(t);
}

static SkDVector ddconic_dxdy_at_t(const SkDCurve& c, double t) {
    return c.fConic.dxdyAtT(t);
}

static SkDVector ddcubic_dxdy_at_t(const SkDCurve& c, double t) {
    return c.fCubic.dxdyAtT(t);
}

static SkDVector (* const CurveDDSlopeAtT[])(const SkDCurve& , double ) = {
    nullptr,
    ddline_dxdy_at_t,
    ddquad_dxdy_at_t,
    ddconic_dxdy_at_t,
    ddcubic_dxdy_at_t
};

static SkVector fline_dxdy_at_t(const SkPoint a[2], SkScalar , double ) {
    return a[1] - a[0];
}

static SkVector fquad_dxdy_at_t(const SkPoint a[3], SkScalar weight, double t) {
    return dquad_dxdy_at_t(a, weight, t).asSkVector();
}

static SkVector fconic_dxdy_at_t(const SkPoint a[3], SkScalar weight, double t) {
    return dconic_dxdy_at_t(a, weight, t).asSkVector();
}

static SkVector fcubic_dxdy_at_t(const SkPoint a[4], SkScalar weight, double t) {
    return dcubic_dxdy_at_t(a, weight, t).asSkVector();
}

static SkVector (* const CurveSlopeAtT[])(const SkPoint[], SkScalar , double ) = {
    nullptr,
    fline_dxdy_at_t,
    fquad_dxdy_at_t,
    fconic_dxdy_at_t,
    fcubic_dxdy_at_t
};

static bool line_is_vertical(const SkPoint a[2], SkScalar , double startT, double endT) {
    SkDLine line;
    line.set(a);
    SkDPoint dst[2] = { line.ptAtT(startT), line.ptAtT(endT) };
    return AlmostEqualUlps(dst[0].fX, dst[1].fX);
}

static bool quad_is_vertical(const SkPoint a[3], SkScalar , double startT, double endT) {
    SkDQuad quad;
    quad.set(a);
    SkDQuad dst = quad.subDivide(startT, endT);
    return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX);
}

static bool conic_is_vertical(const SkPoint a[3], SkScalar weight, double startT, double endT) {
    SkDConic conic;
    conic.set(a, weight);
    SkDConic dst = conic.subDivide(startT, endT);
    return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX);
}

static bool cubic_is_vertical(const SkPoint a[4], SkScalar , double startT, double endT) {
    SkDCubic cubic;
    cubic.set(a);
    SkDCubic dst = cubic.subDivide(startT, endT);
    return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX)
            && AlmostEqualUlps(dst[2].fX, dst[3].fX);
}

static bool (* const CurveIsVertical[])(const SkPoint[], SkScalar , double , double) = {
    nullptr,
    line_is_vertical,
    quad_is_vertical,
    conic_is_vertical,
    cubic_is_vertical
};

static void line_intersect_ray(const SkPoint a[2], SkScalar , const SkDLine& ray,
        SkIntersections* i) {
    SkDLine line;
    line.set(a);
    i->intersectRay(line, ray);
}

static void quad_intersect_ray(const SkPoint a[3], SkScalar , const SkDLine& ray,
        SkIntersections* i) {
    SkDQuad quad;
    quad.set(a);
    i->intersectRay(quad, ray);
}

static void conic_intersect_ray(const SkPoint a[3], SkScalar weight, const SkDLine& ray,
        SkIntersections* i) {
    SkDConic conic;
    conic.set(a, weight);
    i->intersectRay(conic, ray);
}

static void cubic_intersect_ray(const SkPoint a[4], SkScalar , const SkDLine& ray,
        SkIntersections* i) {
    SkDCubic cubic;
    cubic.set(a);
    i->intersectRay(cubic, ray);
}

static void (* const CurveIntersectRay[])(const SkPoint[] , SkScalar , const SkDLine& ,
        SkIntersections* ) = {
    nullptr,
    line_intersect_ray,
    quad_intersect_ray,
    conic_intersect_ray,
    cubic_intersect_ray
};

static void dline_intersect_ray(const SkDCurve& c, const SkDLine& ray,  SkIntersections* i) {
    i->intersectRay(c.fLine, ray);
}

static void dquad_intersect_ray(const SkDCurve& c, const SkDLine& ray, SkIntersections* i) {
    i->intersectRay(c.fQuad, ray);
}

static void dconic_intersect_ray(const SkDCurve& c, const SkDLine& ray, SkIntersections* i) {
    i->intersectRay(c.fConic, ray);
}

static void dcubic_intersect_ray(const SkDCurve& c, const SkDLine& ray, SkIntersections* i) {
    i->intersectRay(c.fCubic, ray);
}

static void (* const CurveDIntersectRay[])(const SkDCurve& , const SkDLine& , SkIntersections* ) = {
    nullptr,
    dline_intersect_ray,
    dquad_intersect_ray,
    dconic_intersect_ray,
    dcubic_intersect_ray
};

static int line_intercept_h(const SkPoint a[2], SkScalar , SkScalar y, double* roots) {
    SkDLine line;
    roots[0] = SkIntersections::HorizontalIntercept(line.set(a), y);
    return between(0, roots[0], 1);
}

static int line_intercept_v(const SkPoint a[2], SkScalar , SkScalar x, double* roots) {
    SkDLine line;
    roots[0] = SkIntersections::VerticalIntercept(line.set(a), x);
    return between(0, roots[0], 1);
}

static int quad_intercept_h(const SkPoint a[2], SkScalar , SkScalar y, double* roots) {
    SkDQuad quad;
    return SkIntersections::HorizontalIntercept(quad.set(a), y, roots);
}

static int quad_intercept_v(const SkPoint a[2], SkScalar , SkScalar x, double* roots) {
    SkDQuad quad;
    return SkIntersections::VerticalIntercept(quad.set(a), x, roots);
}

static int conic_intercept_h(const SkPoint a[2], SkScalar w, SkScalar y, double* roots) {
    SkDConic conic;
    return SkIntersections::HorizontalIntercept(conic.set(a, w), y, roots);
}

static int conic_intercept_v(const SkPoint a[2], SkScalar w, SkScalar x, double* roots) {
    SkDConic conic;
    return SkIntersections::VerticalIntercept(conic.set(a, w), x, roots);
}

static int cubic_intercept_h(const SkPoint a[3], SkScalar , SkScalar y, double* roots) {
    SkDCubic cubic;
    return cubic.set(a).horizontalIntersect(y, roots);
}

static int cubic_intercept_v(const SkPoint a[3], SkScalar , SkScalar x, double* roots) {
    SkDCubic cubic;
    return cubic.set(a).verticalIntersect(x, roots);
}

static int (* const CurveIntercept[])(const SkPoint[] , SkScalar , SkScalar , double* ) = {
    nullptr,
    nullptr,
    line_intercept_h,
    line_intercept_v,
    quad_intercept_h,
    quad_intercept_v,
    conic_intercept_h,
    conic_intercept_v,
    cubic_intercept_h,
    cubic_intercept_v,
};

#endif
