// LAF OS Library
// Copyright (c) 2022  Igara Studio S.A.
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.

#ifndef OS_SKIA_PAINT_H_INCLUDED
#define OS_SKIA_PAINT_H_INCLUDED
#pragma once

#include "gfx/color.h"

#include "include/core/SkPaint.h"

namespace os {

// SkPaint wrapper, information how to paint a shape/primitive in a
// canvas (stroke, fill or both; stroke width; color, etc.).
class Paint : public PaintBase {
public:
  bool antialias() const { return m_skPaint.isAntiAlias(); }
  void antialias(const bool state) { m_skPaint.setAntiAlias(state); }

  Style style() const { return static_cast<Style>(m_skPaint.getStyle()); }
  void style(const Style style) { m_skPaint.setStyle(static_cast<SkPaint::Style>(style)); }

  gfx::Color color() const
  {
    const SkColor c = m_skPaint.getColor();
    return gfx::rgba(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), SkColorGetA(c));
  }
  void color(const gfx::Color c)
  {
    m_skPaint.setColor(SkColorSetARGB(gfx::geta(c), gfx::getr(c), gfx::getg(c), gfx::getb(c)));
  }

  float strokeWidth() const { return m_skPaint.getStrokeWidth(); }
  void strokeWidth(const float strokeWidth) { return m_skPaint.setStrokeWidth(strokeWidth); }

  BlendMode blendMode() const
  {
    auto bm = m_skPaint.asBlendMode();
    if (bm.has_value()) {
      return static_cast<BlendMode>(*bm);
    }
    else
      return BlendMode::Src;
  }
  void blendMode(const BlendMode blendMode)
  {
    m_skPaint.setBlendMode(static_cast<SkBlendMode>(blendMode));
  }

  const SkPaint& skPaint() const { return m_skPaint; }
  SkPaint& skPaint() { return m_skPaint; }

private:
  SkPaint m_skPaint;
};

static_assert((int)SkPaint::kFill_Style == (int)Paint::Fill &&
                (int)SkPaint::kStroke_Style == (int)Paint::Stroke &&
                (int)SkPaint::kStrokeAndFill_Style == (int)Paint::StrokeAndFill,
              "Paint styles don't match with Skia");

static_assert((int)SkBlendMode::kClear == (int)BlendMode::Clear &&
                (int)SkBlendMode::kSrc == (int)BlendMode::Src &&
                (int)SkBlendMode::kDst == (int)BlendMode::Dst &&
                (int)SkBlendMode::kSrcOver == (int)BlendMode::SrcOver &&
                (int)SkBlendMode::kDstOver == (int)BlendMode::DstOver &&
                (int)SkBlendMode::kSrcIn == (int)BlendMode::SrcIn &&
                (int)SkBlendMode::kDstIn == (int)BlendMode::DstIn &&
                (int)SkBlendMode::kSrcOut == (int)BlendMode::SrcOut &&
                (int)SkBlendMode::kDstOut == (int)BlendMode::DstOut &&
                (int)SkBlendMode::kSrcATop == (int)BlendMode::SrcATop &&
                (int)SkBlendMode::kDstATop == (int)BlendMode::DstATop &&
                (int)SkBlendMode::kXor == (int)BlendMode::Xor &&
                (int)SkBlendMode::kPlus == (int)BlendMode::Plus &&
                (int)SkBlendMode::kModulate == (int)BlendMode::Modulate &&
                (int)SkBlendMode::kScreen == (int)BlendMode::Screen &&
                (int)SkBlendMode::kLastCoeffMode == (int)BlendMode::LastCoeffMode &&
                (int)SkBlendMode::kOverlay == (int)BlendMode::Overlay &&
                (int)SkBlendMode::kDarken == (int)BlendMode::Darken &&
                (int)SkBlendMode::kLighten == (int)BlendMode::Lighten &&
                (int)SkBlendMode::kColorDodge == (int)BlendMode::ColorDodge &&
                (int)SkBlendMode::kColorBurn == (int)BlendMode::ColorBurn &&
                (int)SkBlendMode::kHardLight == (int)BlendMode::HardLight &&
                (int)SkBlendMode::kSoftLight == (int)BlendMode::SoftLight &&
                (int)SkBlendMode::kDifference == (int)BlendMode::Difference &&
                (int)SkBlendMode::kExclusion == (int)BlendMode::Exclusion &&
                (int)SkBlendMode::kMultiply == (int)BlendMode::Multiply &&
                (int)SkBlendMode::kLastSeparableMode == (int)BlendMode::LastSeparableMode &&
                (int)SkBlendMode::kHue == (int)BlendMode::Hue &&
                (int)SkBlendMode::kSaturation == (int)BlendMode::Saturation &&
                (int)SkBlendMode::kColor == (int)BlendMode::Color &&
                (int)SkBlendMode::kLuminosity == (int)BlendMode::Luminosity &&
                (int)SkBlendMode::kLastMode == (int)BlendMode::LastMode,
              "Blend modes don't match with Skia");

} // namespace os

#endif
