/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkPathEffectBase_DEFINED
#define SkPathEffectBase_DEFINED

#include "include/core/SkPath.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"

class SkPath;
class SkStrokeRec;

class SkPathEffectBase : public SkPathEffect {
public:
    SkPathEffectBase() {}

    /** \class PointData

        PointData aggregates all the information needed to draw the point
        primitives returned by an 'asPoints' call.
    */
    class PointData {
    public:
        PointData()
            : fFlags(0)
            , fPoints(nullptr)
            , fNumPoints(0) {
            fSize.set(SK_Scalar1, SK_Scalar1);
            // 'asPoints' needs to initialize/fill-in 'fClipRect' if it sets
            // the kUseClip flag
        }
        ~PointData() {
            delete [] fPoints;
        }

        // TODO: consider using passed-in flags to limit the work asPoints does.
        // For example, a kNoPath flag could indicate don't bother generating
        // stamped solutions.

        // Currently none of these flags are supported.
        enum PointFlags {
            kCircles_PointFlag            = 0x01,   // draw points as circles (instead of rects)
            kUsePath_PointFlag            = 0x02,   // draw points as stamps of the returned path
            kUseClip_PointFlag            = 0x04,   // apply 'fClipRect' before drawing the points
        };

        uint32_t           fFlags;      // flags that impact the drawing of the points
        SkPoint*           fPoints;     // the center point of each generated point
        int                fNumPoints;  // number of points in fPoints
        SkVector           fSize;       // the size to draw the points
        SkRect             fClipRect;   // clip required to draw the points (if kUseClip is set)
        SkPath             fPath;       // 'stamp' to be used at each point (if kUsePath is set)

        SkPath             fFirst;      // If not empty, contains geometry for first point
        SkPath             fLast;       // If not empty, contains geometry for last point
    };

    /**
     *  Does applying this path effect to 'src' yield a set of points? If so,
     *  optionally return the points in 'results'.
     */
    bool asPoints(PointData* results, const SkPath& src,
                          const SkStrokeRec&, const SkMatrix&,
                          const SkRect* cullR) const;

    /**
     *  If the PathEffect can be represented as a dash pattern, asADash will return kDash_DashType
     *  and None otherwise. If a non NULL info is passed in, the various DashInfo will be filled
     *  in if the PathEffect can be a dash pattern. If passed in info has an fCount equal or
     *  greater to that of the effect, it will memcpy the values of the dash intervals into the
     *  info. Thus the general approach will be call asADash once with default info to get DashType
     *  and fCount. If effect can be represented as a dash pattern, allocate space for the intervals
     *  in info, then call asADash again with the same info and the intervals will get copied in.
     */

    SkFlattenable::Type getFlattenableType() const override {
        return kSkPathEffect_Type;
    }

    static sk_sp<SkPathEffect> Deserialize(const void* data, size_t size,
                                          const SkDeserialProcs* procs = nullptr) {
        return sk_sp<SkPathEffect>(static_cast<SkPathEffect*>(
                                  SkFlattenable::Deserialize(
                                  kSkPathEffect_Type, data, size, procs).release()));
    }

    /**
     * Filter the input path.
     *
     * The CTM parameter is provided for path effects that can use the information.
     * The output of path effects must always be in the original (input) coordinate system,
     * regardless of whether the path effect uses the CTM or not.
     */
    virtual bool onFilterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*,
                              const SkMatrix& /* ctm */) const = 0;

    /** Path effects *requiring* a valid CTM should override to return true. */
    virtual bool onNeedsCTM() const { return false; }

    virtual bool onAsPoints(PointData*, const SkPath&, const SkStrokeRec&, const SkMatrix&,
                            const SkRect*) const {
        return false;
    }
    virtual DashType onAsADash(DashInfo*) const {
        return kNone_DashType;
    }


    // Compute a conservative bounds for its effect, given the bounds of the path. 'bounds' is
    // both the input and output; if false is returned, fast bounds could not be calculated and
    // 'bounds' is undefined.
    //
    // If 'bounds' is null, performs a dry-run determining if bounds could be computed.
    virtual bool computeFastBounds(SkRect* bounds) const = 0;

    static void RegisterFlattenables();

private:
    using INHERITED = SkPathEffect;
};

////////////////////////////////////////////////////////////////////////////////////////////////

static inline SkPathEffectBase* as_PEB(SkPathEffect* effect) {
    return static_cast<SkPathEffectBase*>(effect);
}

static inline const SkPathEffectBase* as_PEB(const SkPathEffect* effect) {
    return static_cast<const SkPathEffectBase*>(effect);
}

static inline const SkPathEffectBase* as_PEB(const sk_sp<SkPathEffect>& effect) {
    return static_cast<SkPathEffectBase*>(effect.get());
}

static inline sk_sp<SkPathEffectBase> as_PEB_sp(sk_sp<SkPathEffect> effect) {
    return sk_sp<SkPathEffectBase>(static_cast<SkPathEffectBase*>(effect.release()));
}

#endif
