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

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkEncodedImageFormat.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "tools/Resources.h"

namespace skiagm {

static const int imageWidth = 128;
static const int imageHeight = 128;

static sk_sp<SkImage> make_image(SkColorType colorType, SkAlphaType alphaType) {
    const char* resource;
    switch (colorType) {
        case kGray_8_SkColorType:
            if (alphaType != kOpaque_SkAlphaType) {
                return nullptr;
            }
            resource = "images/grayscale.jpg";
            break;
        case kRGB_565_SkColorType:
        case kRGB_888x_SkColorType:
        case kRGB_101010x_SkColorType:
        case kBGR_101010x_SkColorType:
            if (alphaType != kOpaque_SkAlphaType) {
                return nullptr;
            }
            resource = "images/color_wheel.jpg";
            break;
        default:
            resource = (kOpaque_SkAlphaType == alphaType) ? "images/color_wheel.jpg"
                                                          : "images/rainbow-gradient.png";
            break;
    }

    auto image = GetResourceAsImage(resource);
    if (!image) {
        return nullptr;
    }

    auto surface = SkSurface::MakeRaster(SkImageInfo::Make(image->width(), image->height(),
            colorType, alphaType, image->refColorSpace()));
    surface->getCanvas()->drawImage(image, 0, 0);
    return surface->makeImageSnapshot();
}

// This GM looks different depending on the colortype used, so we use different
// names to treat them as different GMs.
// All Variants draw images in pairs:
// - First as an image of the SkColorType of the destination
// - Next as the result of encoding and decoding the first image
enum class Variant {
    // One pair, using an opaque image.
    kOpaque,
    // One pair, using a grayscale image.
    kGray,
    // An opaque pair followed by two more for premul and unpremul.
    kNormal,
};

class EncodeColorTypesGM : public GM {
public:
    EncodeColorTypesGM(SkEncodedImageFormat format, int quality, Variant variant, const char* name)
        : fFormat(format)
        , fQuality(quality)
        , fVariant(variant)
        , fName(name)
    {}

protected:
    SkString onShortName() override {
        const char* variant = fVariant == Variant::kOpaque ? "opaque-":
                              fVariant == Variant::kGray   ? "gray-"  :
                                                             ""       ;
        return SkStringPrintf("encode-%scolor-types-%s", variant, fName);
    }

    SkISize onISize() override {
        const int width = fVariant == Variant::kNormal ? imageWidth * 7 : imageWidth * 2;
        return SkISize::Make(width, imageHeight);
    }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        const auto colorType = canvas->imageInfo().colorType();
        switch (fVariant) {
            case Variant::kGray:
                if (colorType != kGray_8_SkColorType) {
                    return DrawResult::kSkip;
                }
                break;
            case Variant::kOpaque:
                if (colorType != kRGB_565_SkColorType     &&
                    colorType != kRGB_888x_SkColorType    &&
                    colorType != kRGB_101010x_SkColorType &&
                    colorType != kBGR_101010x_SkColorType)
                {
                    return DrawResult::kSkip;
                }
                break;
            case Variant::kNormal:
                if (colorType != kARGB_4444_SkColorType    &&
                    colorType != kRGBA_8888_SkColorType    &&
                    colorType != kBGRA_8888_SkColorType    &&
                    colorType != kRGBA_1010102_SkColorType &&
                    colorType != kBGRA_1010102_SkColorType &&
                    colorType != kRGBA_F16Norm_SkColorType &&
                    colorType != kRGBA_F16_SkColorType     &&
                    colorType != kRGBA_F32_SkColorType)
                {
                    return DrawResult::kSkip;
                }
            break;
        }
        const SkAlphaType alphaTypes[] = {
            kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType,
        };

        for (SkAlphaType alphaType : alphaTypes) {
            auto src = make_image(colorType, alphaType);
            auto decoded = src ? SkImage::MakeFromEncoded(src->encodeToData(fFormat, fQuality))
                               : nullptr;
            if (!src || !decoded) {
                break;
            }

            canvas->drawImage(src, 0.0f, 0.0f);
            canvas->translate((float) imageWidth, 0.0f);

            canvas->drawImage(decoded, 0.0f, 0.0f);
            canvas->translate((float) imageWidth * 1.5, 0.0f);
        }
        return DrawResult::kOk;
    }

private:
    const SkEncodedImageFormat fFormat;
    const int                  fQuality;
    const Variant              fVariant;
    const char*                fName;

    using INHERITED = GM;
};


#define DEF_ENCODE_GM(format, quality, variant, name) \
    static skiagm::GMRegistry SK_MACRO_CONCAT(SK_MACRO_APPEND_LINE(REG_), variant)(\
            [](){return std::unique_ptr<skiagm::GM>([](){\
                    return new EncodeColorTypesGM(format, quality, Variant::variant, name);\
                }());});

#define DEF_VARIANTS(format, quality, name)         \
    DEF_ENCODE_GM(format, quality, kNormal, name);  \
    DEF_ENCODE_GM(format, quality, kOpaque, name);  \
    DEF_ENCODE_GM(format, quality, kGray, name);

DEF_VARIANTS(SkEncodedImageFormat::kWEBP, 100, "webp-lossless")
DEF_VARIANTS(SkEncodedImageFormat::kWEBP,  80, "webp-lossy")
}  // namespace skiagm
