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

#include "modules/skottie/src/text/RangeSelector.h"

#include "include/core/SkCubicMap.h"
#include "include/private/SkMacros.h"
#include "modules/skottie/src/SkottieJson.h"
#include "modules/skottie/src/SkottieValue.h"

#include <algorithm>
#include <cmath>

namespace skottie {
namespace internal {

namespace  {

// Maps a 1-based JSON enum to one of the values in the array.
template <typename T, typename TArray>
T ParseEnum(const TArray& arr, const skjson::Value& jenum,
            const AnimationBuilder* abuilder, const char* warn_name) {

    const auto idx = ParseDefault<int>(jenum, 1);

    if (idx > 0 && SkToSizeT(idx) <= SK_ARRAY_COUNT(arr)) {
        return arr[idx - 1];
    }

    // For animators without selectors, BM emits dummy selector entries with 0 (inval) props.
    // Supress warnings for these as they are "normal".
    if (idx != 0) {
        abuilder->log(Logger::Level::kWarning, nullptr,
                      "Ignoring unknown range selector %s '%d'", warn_name, idx);
    }

    static_assert(SK_ARRAY_COUNT(arr) > 0, "");
    return arr[0];
}

template <RangeSelector::Units>
struct UnitTraits;

template <>
struct UnitTraits<RangeSelector::Units::kPercentage> {
    static constexpr auto Defaults() {
        return std::make_tuple<float, float, float>(0, 100, 0);
    }

    static auto Resolve(float s, float e, float o, size_t domain_size) {
        return std::make_tuple(domain_size * (s + o) / 100,
                               domain_size * (e + o) / 100);
    }
};

template <>
struct UnitTraits<RangeSelector::Units::kIndex> {
    static constexpr auto Defaults() {
        // It's OK to default fEnd to FLOAT_MAX, as it gets clamped when resolved.
        return std::make_tuple<float, float, float>(0, std::numeric_limits<float>::max(), 0);
    }

    static auto Resolve(float s, float e, float o, size_t domain_size) {
        return std::make_tuple(s + o, e + o);
    }
};

class CoverageProcessor {
public:
    CoverageProcessor(const TextAnimator::DomainMaps& maps,
                      RangeSelector::Domain domain,
                      RangeSelector::Mode mode,
                      TextAnimator::ModulatorBuffer& dst)
        : fDst(dst)
        , fDomainSize(dst.size()) {

        SkASSERT(mode == RangeSelector::Mode::kAdd);
        fProc = &CoverageProcessor::add_proc;

        switch (domain) {
        case RangeSelector::Domain::kChars:
            // Direct (1-to-1) index mapping.
            break;
        case RangeSelector::Domain::kCharsExcludingSpaces:
            fMap = &maps.fNonWhitespaceMap;
            break;
        case RangeSelector::Domain::kWords:
            fMap = &maps.fWordsMap;
            break;
        case RangeSelector::Domain::kLines:
            fMap = &maps.fLinesMap;
            break;
        }

        // When no domain map is active, fProc points directly to the mode proc.
        // Otherwise, we punt through a domain mapper proxy.
        if (fMap) {
            fMappedProc = fProc;
            fProc = &CoverageProcessor::domain_map_proc;
            fDomainSize = fMap->size();
        }
    }

    size_t size() const { return fDomainSize; }

    void operator()(float amount, size_t offset, size_t count) const {
        (this->*fProc)(amount, offset, count);
    }

private:
    // mode: kAdd
    void add_proc(float amount, size_t offset, size_t count) const {
        if (!amount || !count) return;

        for (auto* dst = fDst.data() + offset; dst < fDst.data() + offset + count; ++dst) {
            dst->coverage = SkTPin<float>(dst->coverage + amount, -1, 1);
        }
    }

    // A proxy for mapping domain indices to the target buffer.
    void domain_map_proc(float amount, size_t offset, size_t count) const {
        SkASSERT(fMap);
        SkASSERT(fMappedProc);

        for (auto i = offset; i < offset + count; ++i) {
            const auto& span = (*fMap)[i];
            (this->*fMappedProc)(amount, span.fOffset, span.fCount);
        }
    }

    using ProcT = void(CoverageProcessor::*)(float amount, size_t offset, size_t count) const;

    TextAnimator::ModulatorBuffer& fDst;
    ProcT                          fProc,
                                   fMappedProc = nullptr;
    const TextAnimator::DomainMap* fMap = nullptr;
    size_t                         fDomainSize;
};


/*
  Selector shapes can be generalized as a signal generator with the following
  parameters/properties:


  1  +               -------------------------
     |              /.           .           .\
     |             / .           .           . \
     |            /  .           .           .  \
     |           /   .           .           .   \
     |          /    .           .           .    \
     |         /     .           .           .     \
     |        /      .           .           .      \
     |       /       .           .           .       \
  0  +----------------------------------------------------------
            ^ <----->            ^            <-----> ^
           e0   crs             sp              crs    e1


    * e0, e1: left/right edges
    * sp    : symmetry/reflection point (sp == (e0+e1)/2)
    * crs   : cubic ramp size (transitional portion mapped using a Bezier easing function)

  Based on these,

            |  0                  , t <= e0
            |
            |  Bez((t-e0)/crs)    , e0 < t < e0+crs
     F(t) = |
            |  1                  , e0 + crs <= t <= sp
            |
            |  F(reflect(t,sp))   , t > sp


   Tweaking this function's parameters, we can achieve all range selectors shapes:

     - square    -> e0:    0, e1:    1, crs: 0
     - ramp up   -> e0:    0, e1: +inf, crs: 1
     - ramp down -> e0: -inf, e1:    1, crs: 1
     - triangle  -> e0:    0, e1:    1, crs: 0.5
     - round     -> e0:    0, e1:    1, crs: 0.5   (nonlinear cubic mapper)
     - smooth    -> e0:    0, e1:    1, crs: 0.5   (nonlinear cubic mapper)

*/

struct ShapeInfo {
   SkVector ctrl0,
            ctrl1;
   float    e0, e1, crs;
};

SkVector EaseVec(float ease) {
    return (ease < 0) ? SkVector{0, -ease} : SkVector{ease, 0};
}

struct ShapeGenerator {
    SkCubicMap shape_mapper,
                ease_mapper;
    float      e0, e1, crs;

    ShapeGenerator(const ShapeInfo& sinfo, float ease_lo, float ease_hi)
        : shape_mapper(sinfo.ctrl0, sinfo.ctrl1)
        , ease_mapper(EaseVec(ease_lo), SkVector{1,1} - EaseVec(ease_hi))
        , e0(sinfo.e0)
        , e1(sinfo.e1)
        , crs(sinfo.crs) {}

    float operator()(float t) const {
        // SkCubicMap clamps its input, so we can let it all hang out.
        t = std::min(t - e0, e1 - t);
        t = sk_ieee_float_divide(t, crs);

        return ease_mapper.computeYFromX(shape_mapper.computeYFromX(t));
    }
};

static constexpr ShapeInfo gShapeInfo[] = {
    { {0  ,0  }, {1  ,1}, 0                       , 1               , 0.0f }, // Shape::kSquare
    { {0  ,0  }, {1  ,1}, 0                       , SK_FloatInfinity, 1.0f }, // Shape::kRampUp
    { {0  ,0  }, {1  ,1}, SK_FloatNegativeInfinity, 1               , 1.0f }, // Shape::kRampDown
    { {0  ,0  }, {1  ,1}, 0                       , 1               , 0.5f }, // Shape::kTriangle
    { {0  ,.5f}, {.5f,1}, 0                       , 1               , 0.5f }, // Shape::kRound
    { {.5f,0  }, {.5f,1}, 0                       , 1               , 0.5f }, // Shape::kSmooth
};

} // namespace

sk_sp<RangeSelector> RangeSelector::Make(const skjson::ObjectValue* jrange,
                                         const AnimationBuilder* abuilder) {
    if (!jrange) {
        return nullptr;
    }

    enum : int32_t {
             kRange_SelectorType = 0,
        kExpression_SelectorType = 1,

        // kWiggly_SelectorType = ? (not exported)
    };

    {
        const auto type = ParseDefault<int>((*jrange)["t"], kRange_SelectorType);
        if (type != kRange_SelectorType) {
            abuilder->log(Logger::Level::kWarning, nullptr,
                          "Ignoring unsupported selector type '%d'", type);
            return nullptr;
        }
    }

    static constexpr Units gUnitMap[] = {
        Units::kPercentage,  // 'r': 1
        Units::kIndex,       // 'r': 2
    };

    static constexpr Domain gDomainMap[] = {
        Domain::kChars,                 // 'b': 1
        Domain::kCharsExcludingSpaces,  // 'b': 2
        Domain::kWords,                 // 'b': 3
        Domain::kLines,                 // 'b': 4
    };

    static constexpr Mode gModeMap[] = {
        Mode::kAdd,          // 'm': 1
    };

    static constexpr Shape gShapeMap[] = {
        Shape::kSquare,      // 'sh': 1
        Shape::kRampUp,      // 'sh': 2
        Shape::kRampDown,    // 'sh': 3
        Shape::kTriangle,    // 'sh': 4
        Shape::kRound,       // 'sh': 5
        Shape::kSmooth,      // 'sh': 6
    };

    auto selector = sk_sp<RangeSelector>(
            new RangeSelector(ParseEnum<Units> (gUnitMap  , (*jrange)["r" ], abuilder, "units" ),
                              ParseEnum<Domain>(gDomainMap, (*jrange)["b" ], abuilder, "domain"),
                              ParseEnum<Mode>  (gModeMap  , (*jrange)["m" ], abuilder, "mode"  ),
                              ParseEnum<Shape> (gShapeMap , (*jrange)["sh"], abuilder, "shape" )));
    auto* raw_selector = selector.get();

    abuilder->bindProperty<ScalarValue>((*jrange)["s"],
        [raw_selector](const ScalarValue& s) {
            raw_selector->fStart = s;
        });
    abuilder->bindProperty<ScalarValue>((*jrange)["e"],
        [raw_selector](const ScalarValue& e) {
            raw_selector->fEnd = e;
        });
    abuilder->bindProperty<ScalarValue>((*jrange)["o"],
        [raw_selector](const ScalarValue& o) {
            raw_selector->fOffset = o;
        });
    abuilder->bindProperty<ScalarValue>((*jrange)["a"],
        [raw_selector](const ScalarValue& a) {
            raw_selector->fAmount = a;
        });
    abuilder->bindProperty<ScalarValue>((*jrange)["ne"],
        [raw_selector](const ScalarValue& ne) {
            raw_selector->fEaseLo = ne;
        });
    abuilder->bindProperty<ScalarValue>((*jrange)["xe"],
        [raw_selector](const ScalarValue& xe) {
            raw_selector->fEaseHi = xe;
        });

    // Optional square "smoothness" prop.
    if (selector->fShape == Shape::kSquare) {
        abuilder->bindProperty<ScalarValue>((*jrange)["sm"],
            [selector](const ScalarValue& sm) {
                selector->fSmoothness = sm;
            });
    }

    return selector;
}

RangeSelector::RangeSelector(Units u, Domain d, Mode m, Shape sh)
    : fUnits(u)
    , fDomain(d)
    , fMode(m)
    , fShape(sh) {

    // Range defaults are unit-specific.
    switch (fUnits) {
    case Units::kPercentage:
        std::tie(fStart, fEnd, fOffset) = UnitTraits<Units::kPercentage>::Defaults();
        break;
    case Units::kIndex:
        std::tie(fStart, fEnd, fOffset) = UnitTraits<Units::kIndex     >::Defaults();
        break;
    }
}

std::tuple<float, float> RangeSelector::resolve(size_t len) const {
    float f_i0, f_i1;

    SkASSERT(fUnits == Units::kPercentage || fUnits == Units::kIndex);
    const auto resolver = (fUnits == Units::kPercentage)
            ? UnitTraits<Units::kPercentage>::Resolve
            : UnitTraits<Units::kIndex     >::Resolve;

    std::tie(f_i0, f_i1) = resolver(fStart, fEnd, fOffset, len);
    if (f_i0 > f_i1) {
        std::swap(f_i0, f_i1);
    }

    return std::make_tuple(f_i0, f_i1);
}

/*
 * General RangeSelector operation:
 *
 *   1) The range is resolved to a target domain (characters, words, etc) interval, based on
 *      |start|, |end|, |offset|, |units|.
 *
 *   2) A shape generator is mapped to this interval and applied across the whole domain, yielding
 *      coverage values in [0..1].
 *
 *   3) The coverage is then scaled by the |amount| parameter.
 *
 *   4) Finally, the resulting coverage is accumulated to existing fragment coverage based on
 *      the specified Mode (add, difference, etc).
 */
void RangeSelector::modulateCoverage(const TextAnimator::DomainMaps& maps,
                                     TextAnimator::ModulatorBuffer& mbuf) const {
    const CoverageProcessor coverage_proc(maps, fDomain, fMode, mbuf);
    if (coverage_proc.size() == 0) {
        return;
    }

    // Amount, ease-low and ease-high are percentage-based [-100% .. 100%].
    const auto amount = SkTPin<float>(fAmount / 100, -1, 1),
              ease_lo = SkTPin<float>(fEaseLo / 100, -1, 1),
              ease_hi = SkTPin<float>(fEaseHi / 100, -1, 1);

    // Resolve to a float range in the given domain.
    const auto range = this->resolve(coverage_proc.size());
    auto          r0 = std::get<0>(range),
                 len = std::max(std::get<1>(range) - r0, std::numeric_limits<float>::epsilon());

    SkASSERT(static_cast<size_t>(fShape) < SK_ARRAY_COUNT(gShapeInfo));
    ShapeGenerator gen(gShapeInfo[static_cast<size_t>(fShape)], ease_lo, ease_hi);

    if (fShape == Shape::kSquare) {
        // Canonical square generators have collapsed ramps, but AE square selectors have
        // an additional "smoothness" property (0..1) which introduces a non-zero transition.
        // We achieve this by moving the range edges outward by |smoothness|/2, and adjusting
        // the generator cubic ramp size.

        // smoothness is percentage-based [0..100]
        const auto smoothness = SkTPin<float>(fSmoothness / 100, 0, 1);

        r0  -= smoothness / 2;
        len += smoothness;

        gen.crs += smoothness / len;
    }

    SkASSERT(len > 0);
    const auto dt = 1 / len;
          auto  t = (0.5f - r0) / len; // sampling bias: mid-unit

    for (size_t i = 0; i < coverage_proc.size(); ++i, t += dt) {
        coverage_proc(amount * gen(t), i, 1);
    }
}

} // namespace internal
} // namespace skottie
