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

#include "SkArenaAlloc.h"
#include "SkRect.h"
#include "SkTDArray.h"
#include "SkEdge.h"
#include "SkAnalyticEdge.h"

struct SkEdge;
struct SkAnalyticEdge;
class SkEdgeClipper;
class SkPath;

class SkEdgeBuilder {
public:
    enum EdgeType {
        // Used in supersampling or non-AA scan coverter; it stores only integral y coordinates.
        kEdge,

        // Used in Analytic AA scan converter; it uses SkFixed to store fractional y.
        kAnalyticEdge,

        // Used in Delta AA scan converter; it's a super-light wrapper of SkPoint, which can then be
        // used to construct SkAnalyticEdge (kAnalyticEdge) later. We use kBezier to save the memory
        // allocation time (a SkBezier is much lighter than SkAnalyticEdge or SkEdge). Note that
        // Delta AA only has to deal with one SkAnalyticEdge at a time (whereas Analytic AA has to
        // deal with all SkAnalyticEdges at the same time). Thus for Delta AA, we only need to
        // allocate memory for n SkBeziers and 1 SkAnalyticEdge. (Analytic AA need to allocate
        // memory for n SkAnalyticEdges.)
        kBezier
    };

    // static constexpr int kEdgeSizes[3] = {sizeof(SkEdge), sizeof(SkAnalyticEdge), sizeof(SkBezier)};

    SkEdgeBuilder();

    // returns the number of built edges. The array of those edge pointers
    // is returned from edgeList().
    int build(const SkPath& path, const SkIRect* clip, int shiftUp, bool clipToTheRight,
              EdgeType edgeType = kEdge);

    int build_edges(const SkPath& path, const SkIRect* shiftedClip,
            int shiftEdgesUp, bool pathContainedInClip, EdgeType edgeType = kEdge);

    SkEdge** edgeList() { return (SkEdge**)fEdgeList; }
    SkAnalyticEdge** analyticEdgeList() { return (SkAnalyticEdge**)fEdgeList; }
    SkBezier** bezierList() { return (SkBezier**)fEdgeList; }

    bool isFinite() const { return fIsFinite; }

private:
    enum Combine {
        kNo_Combine,
        kPartial_Combine,
        kTotal_Combine
    };

    Combine CombineVertical(const SkEdge* edge, SkEdge* last);
    Combine CombineVertical(const SkAnalyticEdge* edge, SkAnalyticEdge* last);
    Combine checkVertical(const SkEdge* edge, SkEdge** edgePtr);
    Combine checkVertical(const SkAnalyticEdge* edge, SkAnalyticEdge** edgePtr);
    bool vertical_line(const SkEdge* edge);
    bool vertical_line(const SkAnalyticEdge* edge);

    SkSTArenaAlloc<512> fAlloc;
    SkTDArray<void*>    fList;

    /*
     *  If we're in general mode, we allcoate the pointers in fList, and this
     *  will point at fList.begin(). If we're in polygon mode, fList will be
     *  empty, as we will have preallocated room for the pointers in fAlloc's
     *  block, and fEdgeList will point into that.
     */
    void**      fEdgeList;

    int         fShiftUp;
    EdgeType    fEdgeType;
    bool        fIsFinite = true;

public:
    void addLine(const SkPoint pts[]);
    void addQuad(const SkPoint pts[]);
    void addCubic(const SkPoint pts[]);
    void addClipper(SkEdgeClipper*);

    EdgeType edgeType() const { return fEdgeType; }

    int buildPoly(const SkPath& path, const SkIRect* clip, int shiftUp, bool clipToTheRight);

    inline void addPolyLine(SkPoint pts[], char* &edge, size_t edgeSize, char** &edgePtr,
            int shiftUp) {
        if (fEdgeType == kBezier) {
            if (((SkLine*)edge)->set(pts)) {
                *edgePtr++ = edge;
                edge += edgeSize;
            }
            return;
        }
        bool analyticAA = fEdgeType == kAnalyticEdge;
        bool setLineResult = analyticAA ?
                ((SkAnalyticEdge*)edge)->setLine(pts[0], pts[1]) :
                ((SkEdge*)edge)->setLine(pts[0], pts[1], shiftUp);
        if (setLineResult) {
            Combine combine = analyticAA ?
                    checkVertical((SkAnalyticEdge*)edge, (SkAnalyticEdge**)edgePtr) :
                    checkVertical((SkEdge*)edge, (SkEdge**)edgePtr);
            if (kNo_Combine == combine) {
                *edgePtr++ = edge;
                edge += edgeSize;
            } else if (kTotal_Combine == combine) {
                --edgePtr;
            }
        }
    }
};

#endif
