/*
 * 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 SkOpAngle_DEFINED
#define SkOpAngle_DEFINED

#include "SkLineParameters.h"

class SkOpSegment;
struct SkOpSpan;

// sorting angles
// given angles of {dx dy ddx ddy dddx dddy} sort them
class SkOpAngle {
public:
    enum { kStackBasedCount = 8 }; // FIXME: determine what this should be
    enum IncludeType {
        kUnaryWinding,
        kUnaryXor,
        kBinarySingle,
        kBinaryOpp,
    };


    int end() const {
        return fEnd;
    }

    const SkOpAngle* findFirst() const;

    bool inLoop() const {
        return !!fNext;
    }

    void insert(SkOpAngle* );
    bool isHorizontal() const;
    SkOpSpan* lastMarked() const;
    bool loopContains(const SkOpAngle& ) const;
    int loopCount() const;
    void markStops();
    bool merge(SkOpAngle* );

    SkOpAngle* next() const {
        return fNext;
    }

    SkOpAngle* previous() const;

    void set(const SkOpSegment* segment, int start, int end);

    void setLastMarked(SkOpSpan* marked) {
        fLastMarked = marked;
    }

    SkOpSegment* segment() const {
        return const_cast<SkOpSegment*>(fSegment);
    }

    int sign() const {
        return SkSign32(fStart - fEnd);
    }

    bool small() const;

    int start() const {
        return fStart;
    }

    bool unorderable() const {
        return fUnorderable;
    }

    // available to testing only
#if DEBUG_SORT
    void debugLoop() const;  // called by code during run
#endif
#if DEBUG_ANGLE
    void debugSameAs(const SkOpAngle* compare) const;
#endif
    void dump() const;
    void dumpFromTo(const SkOpSegment* fromSeg, int from, int to) const;

#if DEBUG_ANGLE
    void setID(int id) {
        fID = id;
    }
#endif
#if DEBUG_VALIDATE
    void debugValidateLoop() const;
#endif

private:
    bool after(const SkOpAngle* test) const;
    int allOnOneSide(const SkOpAngle& test) const;
    bool calcSlop(double x, double y, double rx, double ry, bool* result) const;
    bool checkCrossesZero() const;
    bool checkParallel(const SkOpAngle& ) const;
    bool computeSector();
    int convexHullOverlaps(const SkOpAngle& ) const;
    double distEndRatio(double dist) const;
    int findSector(SkPath::Verb verb, double x, double y) const;
    bool endsIntersect(const SkOpAngle& ) const;
    double midT() const;
    bool oppositePlanes(const SkOpAngle& rh) const;
    bool orderable(const SkOpAngle& rh) const;  // false == this < rh ; true == this > rh
    bool overlap(const SkOpAngle& test) const;
    void setCurveHullSweep();
    void setSector();
    void setSpans();
    bool tangentsDiverge(const SkOpAngle& rh, double s0xt0) const;

    SkDCubic fCurvePart; // the curve from start to end
    double fSide;
    SkLineParameters fTangentHalf;  // used only to sort a pair of lines or line-like sections
    const SkOpSegment* fSegment;
    SkOpAngle* fNext;
    SkOpSpan* fLastMarked;
    SkDVector fSweep[2];
    int fStart;
    int fEnd;
    int fSectorMask;
    int8_t fSectorStart;  // in 32nds of a circle
    int8_t fSectorEnd;
    bool fIsCurve;
    bool fStop; // set if ordered angle is greater than the previous
    mutable bool fUnorderable;  // this is editable by orderable()
    bool fUnorderedSweep;  // set when a cubic's first control point between the sweep vectors
    bool fComputeSector;
    bool fComputedSector;

#if DEBUG_SORT
    void debugOne(bool showFunc) const;  // available to testing only
#endif
#if DEBUG_ANGLE
    int debugID() const { return fID; }
    int fID;
#endif
#if DEBUG_VALIDATE
    void debugValidateNext() const;  // in debug builds, verify that angle loop is uncorrupted
#else
    void debugValidateNext() const {}
#endif
    void dumpLoop() const;  // utility to be called by user from debugger
    void dumpPartials() const;  // utility to be called by user from debugger
    friend class PathOpsAngleTester;
};

#endif
