/*
 * Copyright 2022 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef skgpu_DrawGeometry_DEFINED
#define skgpu_DrawGeometry_DEFINED


#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "src/gpu/graphite/DrawOrder.h"
#include "src/gpu/graphite/geom/Rect.h"
#include "src/gpu/graphite/geom/Shape.h"
#include "src/gpu/graphite/geom/Transform_graphite.h"

#include <optional>

namespace skgpu::graphite {

// NOTE: Only represents the stroke or hairline styles; stroke-and-fill must be handled higher up.
class StrokeStyle {
public:
    StrokeStyle() : fHalfWidth(0.f), fJoinLimit(0.f), fCap(SkPaint::kButt_Cap) {}
    StrokeStyle(float width,
                float miterLimit,
                SkPaint::Join join,
                SkPaint::Cap cap)
            : fHalfWidth(std::max(0.f, 0.5f * width))
            , fJoinLimit(join == SkPaint::kMiter_Join ? std::max(0.f, miterLimit) :
                         (join == SkPaint::kBevel_Join ? 0.f : -1.f))
            , fCap(cap) {}

    StrokeStyle(const StrokeStyle&) = default;

    StrokeStyle& operator=(const StrokeStyle&) = default;

    bool isMiterJoin() const { return fJoinLimit > 0.f;  }
    bool isBevelJoin() const { return fJoinLimit == 0.f; }
    bool isRoundJoin() const { return fJoinLimit < 0.f;  }

    float         halfWidth()  const { return fHalfWidth;                }
    float         width()      const { return 2.f * fHalfWidth;          }
    float         miterLimit() const { return std::max(0.f, fJoinLimit); }
    SkPaint::Cap  cap()        const { return fCap;                      }
    SkPaint::Join join()       const {
        return fJoinLimit > 0.f ? SkPaint::kMiter_Join :
               (fJoinLimit == 0.f ? SkPaint::kBevel_Join : SkPaint::kRound_Join);
    }

private:
    float        fHalfWidth; // >0: relative to transform; ==0: hairline, 1px in device space
    float        fJoinLimit; // >0: miter join; ==0: bevel join; <0: round join
    SkPaint::Cap fCap;
};

// TBD: Separate DashParams extracted from an SkDashPathEffect? Or folded into StrokeStyle?

class Clip {
public:
    Clip(const Rect& drawBounds, const SkIRect& scissor)
            : fDrawBounds(drawBounds)
            , fScissor(scissor) {}

    const Rect&    drawBounds() const { return fDrawBounds; }
    const SkIRect& scissor()    const { return fScissor;    }

private:
    // Draw bounds represent the tight bounds of the draw, including any padding/outset for stroking
    // and intersected with the scissor.
    // - DrawList assumes the DrawBounds are correct for a given shape, transform, and style. They
    //   are provided to the DrawList to avoid re-calculating the same bounds.
    Rect    fDrawBounds;
    // The scissor must contain fDrawBounds, and must already be intersected with the device bounds.
    SkIRect fScissor;
    // TODO: If we add more complex analytic shapes for clipping, e.g. coverage rrect, it should
    // go here.
};

// Encapsulates all geometric state for a single high-level draw call. RenderSteps are responsible
// for transforming this state into actual rendering; shading from PaintParams is handled separately
class DrawGeometry {
public:
    DrawGeometry(const Transform& transform,
                 const Shape& shape,
                 const Clip& clip,
                 DrawOrder drawOrder,
                 const StrokeStyle* stroke)
            : fTransform(transform)
            , fShape(shape)
            , fClip(clip)
            , fOrder(drawOrder)
            , fStroke(stroke ? std::optional<StrokeStyle>(*stroke) : std::nullopt) {}

    const Transform& transform() const { return fTransform; }
    const Shape&     shape()     const { return fShape;     }
    const Clip&      clip()      const { return fClip;      }
    DrawOrder        order()     const { return fOrder;     }

    // Optional stroke parameters if the geometry is stroked instead of filled
    bool isStroke() const { return fStroke.has_value(); }
    const StrokeStyle& strokeStyle() const {
        SkASSERT(this->isStroke());
        return *fStroke;
    }

private:
    const Transform& fTransform; // Lifetime of the transform must be held longer than the geometry

    Shape     fShape;
    Clip      fClip;
    DrawOrder fOrder;

    std::optional<StrokeStyle> fStroke; // Not present implies fill
};

}  // namespace skgpu

#endif // skgpu_DrawGeometry_DEFINED
