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

#include "experimental/svg/model/SkSVGRadialGradient.h"
#include "experimental/svg/model/SkSVGRenderContext.h"
#include "experimental/svg/model/SkSVGValue.h"
#include "include/effects/SkGradientShader.h"

SkSVGRadialGradient::SkSVGRadialGradient() : INHERITED(SkSVGTag::kRadialGradient) {}

void SkSVGRadialGradient::setCx(const SkSVGLength& cx) {
    fCx = cx;
}

void SkSVGRadialGradient::setCy(const SkSVGLength& cy) {
    fCy = cy;
}

void SkSVGRadialGradient::setR(const SkSVGLength& r) {
    fR = r;
}

void SkSVGRadialGradient::setFx(const SkSVGLength& fx) {
    fFx.set(fx);
}

void SkSVGRadialGradient::setFy(const SkSVGLength& fy) {
    fFy.set(fy);
}

void SkSVGRadialGradient::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
    switch (attr) {
    case SkSVGAttribute::kCx:
        if (const auto* cx = v.as<SkSVGLengthValue>()) {
            this->setCx(*cx);
        }
        break;
    case SkSVGAttribute::kCy:
        if (const auto* cy = v.as<SkSVGLengthValue>()) {
            this->setCy(*cy);
        }
        break;
    case SkSVGAttribute::kR:
        if (const auto* r = v.as<SkSVGLengthValue>()) {
            this->setR(*r);
        }
        break;
    case SkSVGAttribute::kFx:
        if (const auto* fx = v.as<SkSVGLengthValue>()) {
            this->setFx(*fx);
        }
        break;
    case SkSVGAttribute::kFy:
        if (const auto* fy = v.as<SkSVGLengthValue>()) {
            this->setFy(*fy);
        }
        break;
    default:
        this->INHERITED::onSetAttribute(attr, v);
    }
}

sk_sp<SkShader> SkSVGRadialGradient::onMakeShader(const SkSVGRenderContext& ctx,
                                                  const SkColor* colors, const SkScalar* pos,
                                                  int count, SkTileMode tm,
                                                  const SkMatrix& m) const {
    const auto&  lctx = ctx.lengthContext();
    const auto      r = lctx.resolve(fR , SkSVGLengthContext::LengthType::kOther);
    const auto center = SkPoint::Make(
            lctx.resolve(fCx, SkSVGLengthContext::LengthType::kHorizontal),
            lctx.resolve(fCy, SkSVGLengthContext::LengthType::kVertical));
    const auto  focal = SkPoint::Make(
        fFx.isValid() ? lctx.resolve(*fFx.get(), SkSVGLengthContext::LengthType::kHorizontal)
                      : center.x(),
        fFy.isValid() ? lctx.resolve(*fFy.get(), SkSVGLengthContext::LengthType::kVertical)
                      : center.y());

    return center == focal
        ? SkGradientShader::MakeRadial(center, r, colors, pos, count, tm, 0, &m)
        : SkGradientShader::MakeTwoPointConical(focal, 0, center, r, colors, pos, count, tm, 0, &m);
}
