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

#ifndef SkLinearBitmapPipeline_tile_DEFINED
#define SkLinearBitmapPipeline_tile_DEFINED

#include "SkLinearBitmapPipeline_core.h"
#include "SkPM4f.h"
#include <algorithm>
#include <cmath>
#include <limits>

namespace {
class XClampStrategy {
public:
    XClampStrategy(int32_t max)
        : fXMaxPixel{SkScalar(max - 0.5f)}
        , fXMax{SkScalar(max)} { }

    void tileXPoints(Sk4s* xs) {
        *xs = Sk4s::Min(Sk4s::Max(*xs, 0.0f), fXMaxPixel);
        SkASSERT(0 <= (*xs)[0] && (*xs)[0] < fXMax);
        SkASSERT(0 <= (*xs)[1] && (*xs)[1] < fXMax);
        SkASSERT(0 <= (*xs)[2] && (*xs)[2] < fXMax);
        SkASSERT(0 <= (*xs)[3] && (*xs)[3] < fXMax);
    }

    template<typename Next>
    bool maybeProcessSpan(Span originalSpan, Next* next) {
        SkASSERT(!originalSpan.isEmpty());
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = originalSpan;
        SkScalar x = X(start);
        SkScalar y = Y(start);
        Span span{{x, y}, length, count};

        if (span.completelyWithin(0.0f, fXMax)) {
            next->pointSpan(span);
            return true;
        }
        if (1 == count || 0.0f == length) {
            return false;
        }

        SkScalar dx = length / (count - 1);

        //    A                 B     C
        // +-------+-------+-------++-------+-------+-------+     +-------+-------++------
        // |  *---*|---*---|*---*--||-*---*-|---*---|*---...|     |--*---*|---*---||*---*....
        // |       |       |       ||       |       |       | ... |       |       ||
        // |       |       |       ||       |       |       |     |       |       ||
        // +-------+-------+-------++-------+-------+-------+     +-------+-------++------
        //                         ^                                              ^
        //                         | xMin                                  xMax-1 | xMax
        //
        //     *---*---*---... - track of samples. * = sample
        //
        //     +-+                                 ||
        //     | |  - pixels in source space.      || - tile border.
        //     +-+                                 ||
        //
        // The length from A to B is the length in source space or 4 * dx or (count - 1) * dx
        // where dx is the distance between samples. There are 5 destination pixels
        // corresponding to 5 samples specified in the A, B span. The distance from A to the next
        // span starting at C is 5 * dx, so count * dx.
        // Remember, count is the number of pixels needed for the destination and the number of
        // samples.
        // Overall Strategy:
        // * Under - for portions of the span < xMin, take the color at pixel {xMin, y} and use it
        //   to fill in the 5 pixel sampled from A to B.
        // * Middle - for the portion of the span between xMin and xMax sample normally.
        // * Over - for the portion of the span > xMax, take the color at pixel {xMax-1, y} and
        //   use it to fill in the rest of the destination pixels.
        if (dx >= 0) {
            Span leftClamped = span.breakAt(0.0f, dx);
            if (!leftClamped.isEmpty()) {
                leftClamped.clampToSinglePixel({0.0f, y});
                next->pointSpan(leftClamped);
            }
            Span center = span.breakAt(fXMax, dx);
            if (!center.isEmpty()) {
                next->pointSpan(center);
            }
            if (!span.isEmpty()) {
                span.clampToSinglePixel({fXMax - 1, y});
                next->pointSpan(span);
            }
        } else {
            Span rightClamped = span.breakAt(fXMax, dx);
            if (!rightClamped.isEmpty()) {
                rightClamped.clampToSinglePixel({fXMax - 1, y});
                next->pointSpan(rightClamped);
            }
            Span center = span.breakAt(0.0f, dx);
            if (!center.isEmpty()) {
                next->pointSpan(center);
            }
            if (!span.isEmpty()) {
                span.clampToSinglePixel({0.0f, y});
                next->pointSpan(span);
            }
        }
        return true;
    }

private:
    const SkScalar fXMaxPixel;
    const SkScalar fXMax;
};

class YClampStrategy {
public:
    YClampStrategy(int32_t max)
        : fYMax{SkScalar(max) - 0.5f} { }

    void tileYPoints(Sk4s* ys) {
        *ys = Sk4s::Min(Sk4s::Max(*ys, 0.0f), fYMax);
        SkASSERT(0 <= (*ys)[0] && (*ys)[0] <= fYMax);
        SkASSERT(0 <= (*ys)[1] && (*ys)[1] <= fYMax);
        SkASSERT(0 <= (*ys)[2] && (*ys)[2] <= fYMax);
        SkASSERT(0 <= (*ys)[3] && (*ys)[3] <= fYMax);
    }

    SkScalar tileY(SkScalar y) {
        return std::min(std::max<SkScalar>(0.0f, y), fYMax);
    }

private:
    const SkScalar fYMax;
};

SkScalar tile_mod(SkScalar x, SkScalar base) {
    return x - SkScalarFloorToScalar(x / base) * base;
}

class XRepeatStrategy {
public:
    XRepeatStrategy(int32_t max)
        : fXMax{SkScalar(max)}
        , fXCap{SkScalar(nextafterf(SkScalar(max), 0.0f))}
        , fXInvMax{1.0f / SkScalar(max)} { }

    void tileXPoints(Sk4s* xs) {
        Sk4s divX = *xs * fXInvMax;
        Sk4s modX = *xs - divX.floor() * fXMax;
        *xs = Sk4s::Min(fXCap, modX);
        SkASSERT(0 <= (*xs)[0] && (*xs)[0] < fXMax);
        SkASSERT(0 <= (*xs)[1] && (*xs)[1] < fXMax);
        SkASSERT(0 <= (*xs)[2] && (*xs)[2] < fXMax);
        SkASSERT(0 <= (*xs)[3] && (*xs)[3] < fXMax);
    }

    template<typename Next>
    bool maybeProcessSpan(Span originalSpan, Next* next) {
        SkASSERT(!originalSpan.isEmpty());
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = originalSpan;
        // Make x and y in range on the tile.
        SkScalar x = tile_mod(X(start), fXMax);
        SkScalar y = Y(start);
        SkScalar dx = length / (count - 1);

        // No need trying to go fast because the steps are larger than a tile or there is one point.
        if (SkScalarAbs(dx) >= fXMax || count <= 1) {
            return false;
        }

        //             A        B     C                  D                Z
        // +-------+-------+-------++-------+-------+-------++     +-------+-------++------
        // |       |   *---|*---*--||-*---*-|---*---|*---*--||     |--*---*|       ||
        // |       |       |       ||       |       |       || ... |       |       ||
        // |       |       |       ||       |       |       ||     |       |       ||
        // +-------+-------+-------++-------+-------+-------++     +-------+-------++------
        //                         ^^                       ^^                     ^^
        //                    xMax || xMin             xMax || xMin           xMax || xMin
        //
        //     *---*---*---... - track of samples. * = sample
        //
        //     +-+                                 ||
        //     | |  - pixels in source space.      || - tile border.
        //     +-+                                 ||
        //
        //
        // The given span starts at A and continues on through several tiles to sample point Z.
        // The idea is to break this into several spans one on each tile the entire span
        // intersects. The A to B span only covers a partial tile and has a count of 3 and the
        // distance from A to B is (count - 1) * dx or 2 * dx. The distance from A to the start of
        // the next span is count * dx or 3 * dx. Span C to D covers an entire tile has a count
        // of 5 and a length of 4 * dx. Remember, count is the number of pixels needed for the
        // destination and the number of samples.
        //
        // Overall Strategy:
        // While the span hangs over the edge of the tile, draw the span covering the tile then
        // slide the span over to the next tile.

        // The guard could have been count > 0, but then a bunch of math would be done in the
        // common case.

        Span span({x, y}, length, count);
        if (dx > 0) {
            while (!span.isEmpty() && span.endX() >= fXMax) {
                Span toDraw = span.breakAt(fXMax, dx);
                next->pointSpan(toDraw);
                span.offset(-fXMax);
            }
        } else {
            while (!span.isEmpty() && span.endX() < 0.0f) {
                Span toDraw = span.breakAt(0.0f, dx);
                next->pointSpan(toDraw);
                span.offset(fXMax);
            }
        }

        // All on a single tile.
        if (!span.isEmpty()) {
            next->pointSpan(span);
        }

        return true;
    }

private:
    const SkScalar fXMax;
    const SkScalar fXCap;
    const SkScalar fXInvMax;
};

// The XRepeatUnitScaleStrategy exploits the situation where dx = 1.0. The main advantage is that
// the relationship between the sample points and the source pixels does not change from tile to
// repeated tile. This allows the tiler to calculate the span once and re-use it for each
// repeated tile. This is later exploited by some samplers to avoid converting pixels to linear
// space allowing the use of memmove to place pixel in the destination.
class XRepeatUnitScaleStrategy {
public:
    XRepeatUnitScaleStrategy(int32_t max)
        : fXMax{SkScalar(max)}
        , fXCap{SkScalar(nextafterf(SkScalar(max), 0.0f))}
        , fXInvMax{1.0f / SkScalar(max)} { }

    void tileXPoints(Sk4s* xs) {
        Sk4s divX = *xs * fXInvMax;
        Sk4s modX = *xs - divX.floor() * fXMax;
        *xs = Sk4s::Min(fXCap, modX);
        SkASSERT(0 <= (*xs)[0] && (*xs)[0] < fXMax);
        SkASSERT(0 <= (*xs)[1] && (*xs)[1] < fXMax);
        SkASSERT(0 <= (*xs)[2] && (*xs)[2] < fXMax);
        SkASSERT(0 <= (*xs)[3] && (*xs)[3] < fXMax);
    }

    template<typename Next>
    bool maybeProcessSpan(Span originalSpan, Next* next) {
        SkASSERT(!originalSpan.isEmpty());
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = originalSpan;
        // Make x and y in range on the tile.
        SkScalar x = tile_mod(X(start), fXMax);
        SkScalar y = Y(start);

        // No need trying to go fast because the steps are larger than a tile or there is one point.
        if (fXMax == 1 || count <= 1) {
            return false;
        }

        // x should be on the tile.
        SkASSERT(0.0f <= x && x < fXMax);
        Span span({x, y}, length, count);

        if (SkScalarFloorToScalar(x) != 0.0f) {
            Span toDraw = span.breakAt(fXMax, 1.0f);
            SkASSERT(0.0f <= toDraw.startX() && toDraw.endX() < fXMax);
            next->pointSpan(toDraw);
            span.offset(-fXMax);
        }

        // All of the span could have been on the first tile. If so, then no work to do.
        if (span.isEmpty()) return true;

        // At this point the span should be aligned to zero.
        SkASSERT(SkScalarFloorToScalar(span.startX()) == 0.0f);

        // Note: The span length has an unintuitive relation to the tile width. The tile width is
        // a half open interval [tb, te), but the span is a closed interval [sb, se]. In order to
        // compare the two, you need to convert the span to a half open interval. This is done by
        // adding dx to se. So, the span becomes: [sb, se + dx). Hence the + 1.0f below.
        SkScalar div = (span.length() + 1.0f) / fXMax;
        int32_t repeatCount = SkScalarFloorToInt(div);
        Span repeatableSpan{{0.0f, y}, fXMax - 1.0f, SkScalarFloorToInt(fXMax)};

        // Repeat the center section.
        SkASSERT(0.0f <= repeatableSpan.startX() && repeatableSpan.endX() < fXMax);
        if (repeatCount > 0) {
            next->repeatSpan(repeatableSpan, repeatCount);
        }

        // Calculate the advance past the center portion.
        SkScalar advance = SkScalar(repeatCount) * fXMax;

        // There may be some of the span left over.
        span.breakAt(advance, 1.0f);

        // All on a single tile.
        if (!span.isEmpty()) {
            span.offset(-advance);
            SkASSERT(0.0f <= span.startX() && span.endX() < fXMax);
            next->pointSpan(span);
        }

        return true;
    }

private:
    const SkScalar fXMax;
    const SkScalar fXCap;
    const SkScalar fXInvMax;
};

class YRepeatStrategy {
public:
    YRepeatStrategy(int32_t max)
        : fYMax{SkScalar(max)}
        , fYsInvMax{1.0f / SkScalar(max)} { }

    void tileYPoints(Sk4s* ys) {
        Sk4s divY = *ys * fYsInvMax;
        Sk4s modY = *ys - divY.floor() * fYMax;
        *ys = modY;
        SkASSERT(0 <= (*ys)[0] && (*ys)[0] < fYMax);
        SkASSERT(0 <= (*ys)[1] && (*ys)[1] < fYMax);
        SkASSERT(0 <= (*ys)[2] && (*ys)[2] < fYMax);
        SkASSERT(0 <= (*ys)[3] && (*ys)[3] < fYMax);
    }

    SkScalar tileY(SkScalar y) {
        SkScalar answer = tile_mod(y, fYMax);
        SkASSERT(0 <= answer && answer < fYMax);
        return answer;
    }

private:
    const SkScalar fYMax;
    const SkScalar fYsInvMax;
};
// max = 40
// mq2[x_] := Abs[(x - 40) - Floor[(x - 40)/80] * 80 - 40]
class XMirrorStrategy {
public:
    XMirrorStrategy(int32_t max)
        : fXMax{SkScalar(max)}
        , fXCap{SkScalar(nextafterf(SkScalar(max), 0.0f))}
        , fXDoubleInvMax{1.0f / (2.0f * SkScalar(max))} { }

    void tileXPoints(Sk4s* xs) {
        Sk4f bias   = *xs - fXMax;
        Sk4f div    = bias * fXDoubleInvMax;
        Sk4f mod    = bias - div.floor() * 2.0f * fXMax;
        Sk4f unbias = mod - fXMax;
        *xs = Sk4f::Min(unbias.abs(), fXCap);
        SkASSERT(0 <= (*xs)[0] && (*xs)[0] < fXMax);
        SkASSERT(0 <= (*xs)[1] && (*xs)[1] < fXMax);
        SkASSERT(0 <= (*xs)[2] && (*xs)[2] < fXMax);
        SkASSERT(0 <= (*xs)[3] && (*xs)[3] < fXMax);
    }

    template <typename Next>
    bool maybeProcessSpan(Span originalSpan, Next* next) { return false; }

private:
    SkScalar fXMax;
    SkScalar fXCap;
    SkScalar fXDoubleInvMax;
};

class YMirrorStrategy {
public:
    YMirrorStrategy(int32_t max)
        : fYMax{SkScalar(max)}
        , fYCap{nextafterf(SkScalar(max), 0.0f)}
        , fYDoubleInvMax{1.0f / (2.0f * SkScalar(max))} { }

    void tileYPoints(Sk4s* ys) {
        Sk4f bias   = *ys - fYMax;
        Sk4f div    = bias * fYDoubleInvMax;
        Sk4f mod    = bias - div.floor() * 2.0f * fYMax;
        Sk4f unbias = mod - fYMax;
        *ys = Sk4f::Min(unbias.abs(), fYCap);
        SkASSERT(0 <= (*ys)[0] && (*ys)[0] < fYMax);
        SkASSERT(0 <= (*ys)[1] && (*ys)[1] < fYMax);
        SkASSERT(0 <= (*ys)[2] && (*ys)[2] < fYMax);
        SkASSERT(0 <= (*ys)[3] && (*ys)[3] < fYMax);
    }

    SkScalar tileY(SkScalar y) {
        SkScalar bias   = y - fYMax;
        SkScalar div    = bias * fYDoubleInvMax;
        SkScalar mod    = bias - SkScalarFloorToScalar(div) * 2.0f * fYMax;
        SkScalar unbias = mod - fYMax;
        SkScalar answer = SkMinScalar(SkScalarAbs(unbias), fYCap);
        SkASSERT(0 <= answer && answer < fYMax);
        return answer;
    }

private:
    SkScalar fYMax;
    SkScalar fYCap;
    SkScalar fYDoubleInvMax;
};

}  // namespace
#endif  // SkLinearBitmapPipeline_tile_DEFINED
