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

#include "include/core/SkCanvas.h"
#include "include/core/SkImage.h"
#include "modules/svg/include/SkSVGAttributeParser.h"
#include "modules/svg/include/SkSVGImage.h"
#include "modules/svg/include/SkSVGRenderContext.h"
#include "modules/svg/include/SkSVGValue.h"
#include "src/utils/SkOSPath.h"

bool SkSVGImage::parseAndSetAttribute(const char* n, const char* v) {
    return INHERITED::parseAndSetAttribute(n, v) ||
           this->setX(SkSVGAttributeParser::parse<SkSVGLength>("x", n, v)) ||
           this->setY(SkSVGAttributeParser::parse<SkSVGLength>("y", n, v)) ||
           this->setWidth(SkSVGAttributeParser::parse<SkSVGLength>("width", n, v)) ||
           this->setHeight(SkSVGAttributeParser::parse<SkSVGLength>("height", n, v)) ||
           this->setHref(SkSVGAttributeParser::parse<SkSVGIRI>("xlink:href", n, v)) ||
           this->setPreserveAspectRatio(SkSVGAttributeParser::parse<SkSVGPreserveAspectRatio>(
                   "preserveAspectRatio", n, v));
}

bool SkSVGImage::onPrepareToRender(SkSVGRenderContext* ctx) const {
    // Width or height of 0 disables rendering per spec:
    // https://www.w3.org/TR/SVG11/struct.html#ImageElement
    return !fHref.iri().isEmpty() && fWidth.value() > 0 && fHeight.value() > 0 &&
           INHERITED::onPrepareToRender(ctx);
}

static sk_sp<SkImage> LoadImage(const sk_sp<skresources::ResourceProvider>& rp,
                                const SkSVGIRI& href) {
    // TODO: It may be better to use the SVG 'id' attribute as the asset id, to allow
    // clients to perform asset substitution based on element id.
    sk_sp<skresources::ImageAsset> imageAsset;
    switch (href.type()) {
        case SkSVGIRI::Type::kDataURI:
            imageAsset = rp->loadImageAsset("", href.iri().c_str(), "");
            break;
        case SkSVGIRI::Type::kNonlocal: {
            const auto path = SkOSPath::Dirname(href.iri().c_str());
            const auto name = SkOSPath::Basename(href.iri().c_str());
            imageAsset = rp->loadImageAsset(path.c_str(), name.c_str(), /* id */ name.c_str());
            break;
        }
        default:
            SkDebugf("error loading image: unhandled iri type %d\n", href.type());
            return nullptr;
    }

    return imageAsset ? imageAsset->getFrameData(0).image : nullptr;
}

SkRect SkSVGImage::resolveImageRect(const SkRect& viewBox, const SkRect& viewPort) const {
    const SkMatrix m = ComputeViewboxMatrix(viewBox, viewPort, fPreserveAspectRatio);
    // Map and place at x, y specified by image attributes
    return m.mapRect(viewBox).makeOffset(viewPort.fLeft, viewPort.fTop);
}

void SkSVGImage::onRender(const SkSVGRenderContext& ctx) const {
    const auto& rp = ctx.resourceProvider();
    SkASSERT(rp);

    // TODO: svg sources
    sk_sp<SkImage> image = LoadImage(rp, fHref);
    if (!image) {
        SkDebugf("can't render image: load image failed\n");
        return;
    }

    // Per spec: x, w, width, height attributes establish the new viewport.
    const SkSVGLengthContext& lctx = ctx.lengthContext();
    const SkRect viewPort = lctx.resolveRect(fX, fY, fWidth, fHeight);
    // Per spec: raster content has implicit viewbox of '0 0 width height'.
    const SkRect viewBox = SkRect::Make(image->bounds());

    ctx.canvas()->drawImageRect(image,
                                this->resolveImageRect(viewBox, viewPort),
                                SkSamplingOptions(SkFilterMode::kLinear));
}

SkPath SkSVGImage::onAsPath(const SkSVGRenderContext&) const { return {}; }

SkRect SkSVGImage::onObjectBoundingBox(const SkSVGRenderContext& ctx) const {
    const SkSVGLengthContext& lctx = ctx.lengthContext();
    return lctx.resolveRect(fX, fY, fWidth, fHeight);
}
