/*
 * 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 "SkChunkAlloc.h"
#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 dumpLoop() const;
    void dumpTo(const SkOpSegment* fromSeg, const SkOpAngle* ) const;

#if DEBUG_ANGLE
    int debugID() const { return fID; }

    void setID(int id) {
        fID = id;
    }
#else
    int debugID() const { return 0; }
#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 fComputedEnd;
    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_ANGLE
    int fID;
#endif
#if DEBUG_VALIDATE
    void debugValidateNext() const;  // in debug builds, verify that angle loop is uncorrupted
#else
    void debugValidateNext() const {}
#endif
    void dumpOne(bool showFunc) const;  // available to testing only
    void dumpPartials() const;  // utility to be called by user from debugger
    friend class PathOpsAngleTester;
};

class SkOpAngleSet {
public:
    SkOpAngleSet();
    ~SkOpAngleSet();
    SkOpAngle& push_back();
    void reset();
private:
    void dump() const;  // utility to be called by user from debugger
#if DEBUG_ANGLE
    int fCount;
#endif
    SkChunkAlloc* fAngles;
};

#endif
