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

#ifndef SkImageSampling_DEFINED
#define SkImageSampling_DEFINED

#include "include/core/SkTypes.h"

#include <algorithm>
#include <new>

enum class SkFilterMode {
    kNearest,   // single sample point (nearest neighbor)
    kLinear,    // interporate between 2x2 sample points (bilinear interpolation)

    kLast = kLinear,
};
static constexpr int kSkFilterModeCount = static_cast<int>(SkFilterMode::kLast) + 1;

enum class SkMipmapMode {
    kNone,      // ignore mipmap levels, sample from the "base"
    kNearest,   // sample from the nearest level
    kLinear,    // interpolate between the two nearest levels

    kLast = kLinear,
};
static constexpr int kSkMipmapModeCount = static_cast<int>(SkMipmapMode::kLast) + 1;

/*
 *  Specify B and C (each between 0...1) to create a shader that applies the corresponding
 *  cubic reconstruction filter to the image.
 *
 *  Example values:
 *      B = 1/3, C = 1/3        "Mitchell" filter
 *      B = 0,   C = 1/2        "Catmull-Rom" filter
 *
 *  See "Reconstruction Filters in Computer Graphics"
 *          Don P. Mitchell
 *          Arun N. Netravali
 *          1988
 *  https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf
 *
 *  Desmos worksheet https://www.desmos.com/calculator/aghdpicrvr
 *  Nice overview https://entropymine.com/imageworsener/bicubic/
 */
struct SkCubicResampler {
    float B, C;

    // Historic default for kHigh_SkFilterQuality
    static constexpr SkCubicResampler Mitchell() { return {1/3.0f, 1/3.0f}; }
    static constexpr SkCubicResampler CatmullRom() { return {0.0f, 1/2.0f}; }
};

struct SK_API SkSamplingOptions {
    const int              maxAniso = 0;
    const bool             useCubic = false;
    const SkCubicResampler cubic    = {0, 0};
    const SkFilterMode     filter   = SkFilterMode::kNearest;
    const SkMipmapMode     mipmap   = SkMipmapMode::kNone;

    constexpr SkSamplingOptions() = default;
    SkSamplingOptions(const SkSamplingOptions&) = default;
    SkSamplingOptions& operator=(const SkSamplingOptions& that) {
        this->~SkSamplingOptions();   // A pedantic no-op.
        new (this) SkSamplingOptions(that);
        return *this;
    }

    constexpr SkSamplingOptions(SkFilterMode fm, SkMipmapMode mm)
        : filter(fm)
        , mipmap(mm) {}

    // These are intentionally implicit because the single parameter clearly conveys what the
    // implicitly created SkSamplingOptions will be.
    constexpr SkSamplingOptions(SkFilterMode fm)
        : filter(fm)
        , mipmap(SkMipmapMode::kNone) {}

    constexpr SkSamplingOptions(const SkCubicResampler& c)
        : useCubic(true)
        , cubic(c) {}

    static constexpr SkSamplingOptions Aniso(int maxAniso) {
        return SkSamplingOptions{std::max(maxAniso, 1)};
    }

    bool operator==(const SkSamplingOptions& other) const {
        return maxAniso == other.maxAniso
            && useCubic == other.useCubic
            && cubic.B  == other.cubic.B
            && cubic.C  == other.cubic.C
            && filter   == other.filter
            && mipmap   == other.mipmap;
    }
    bool operator!=(const SkSamplingOptions& other) const { return !(*this == other); }

    bool isAniso() const { return maxAniso != 0; }

private:
    constexpr SkSamplingOptions(int maxAniso) : maxAniso(maxAniso) {}
};

#endif
