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

#include "SkPaint.h"

class SkPath;

SK_BEGIN_REQUIRE_DENSE
class SkStrokeRec {
public:
    enum InitStyle {
        kHairline_InitStyle,
        kFill_InitStyle
    };
    SkStrokeRec(InitStyle style);
    SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1);
    explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1);

    enum Style {
        kHairline_Style,
        kFill_Style,
        kStroke_Style,
        kStrokeAndFill_Style
    };
    enum {
        kStyleCount = kStrokeAndFill_Style + 1
    };

    Style getStyle() const;
    SkScalar getWidth() const { return fWidth; }
    SkScalar getMiter() const { return fMiterLimit; }
    SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; }
    SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; }

    bool isHairlineStyle() const {
        return kHairline_Style == this->getStyle();
    }

    bool isFillStyle() const {
        return kFill_Style == this->getStyle();
    }

    void setFillStyle();
    void setHairlineStyle();
    /**
     *  Specify the strokewidth, and optionally if you want stroke + fill.
     *  Note, if width==0, then this request is taken to mean:
     *      strokeAndFill==true -> new style will be Fill
     *      strokeAndFill==false -> new style will be Hairline
     */
    void setStrokeStyle(SkScalar width, bool strokeAndFill = false);

    void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) {
        fCap = cap;
        fJoin = join;
        fMiterLimit = miterLimit;
    }

    SkScalar getResScale() const {
        return fResScale;
    }

    void setResScale(SkScalar rs) {
        SkASSERT(rs > 0 && SkScalarIsFinite(rs));
        fResScale = rs;
    }

    /**
     *  Returns true if this specifes any thick stroking, i.e. applyToPath()
     *  will return true.
     */
    bool needToApply() const {
        Style style = this->getStyle();
        return (kStroke_Style == style) || (kStrokeAndFill_Style == style);
    }

    /**
     *  Apply these stroke parameters to the src path, returning the result
     *  in dst.
     *
     *  If there was no change (i.e. style == hairline or fill) this returns
     *  false and dst is unchanged. Otherwise returns true and the result is
     *  stored in dst.
     *
     *  src and dst may be the same path.
     */
    bool applyToPath(SkPath* dst, const SkPath& src) const;

    /**
     *  Apply these stroke parameters to a paint.
     */
    void applyToPaint(SkPaint* paint) const;

    /**
     * Gives a conservative value for the outset that should applied to a
     * geometries bounds to account for any inflation due to applying this
     * strokeRec to the geometry.
     */
    SkScalar getInflationRadius() const;

    /**
     * Equivalent to:
     *   SkStrokeRec rec(paint, style);
     *   rec.getInflationRadius();
     * This does not account for other effects on the paint (i.e. path
     * effect).
     */
    static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style);

    /**
     * Compare if two SkStrokeRecs have an equal effect on a path.
     * Equal SkStrokeRecs produce equal paths. Equality of produced
     * paths does not take the ResScale parameter into account.
     */
    bool hasEqualEffect(const SkStrokeRec& other) const {
        if (!this->needToApply()) {
            return this->getStyle() == other.getStyle();
        }
        return fWidth == other.fWidth &&
               fMiterLimit == other.fMiterLimit &&
               fCap == other.fCap &&
               fJoin == other.fJoin &&
               fStrokeAndFill == other.fStrokeAndFill;
    }

private:
    void init(const SkPaint&, SkPaint::Style, SkScalar resScale);

    SkScalar        fResScale;
    SkScalar        fWidth;
    SkScalar        fMiterLimit;
    // The following three members are packed together into a single u32.
    // This is to avoid unnecessary padding and ensure binary equality for
    // hashing (because the padded areas might contain garbage values).
    //
    // fCap and fJoin are larger than needed to avoid having to initialize
    // any pad values
    uint32_t        fCap : 16;             // SkPaint::Cap
    uint32_t        fJoin : 15;            // SkPaint::Join
    uint32_t        fStrokeAndFill : 1;    // bool
};
SK_END_REQUIRE_DENSE

#endif
