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

#include "src/core/SkLatticeIter.h"

#include "include/core/SkMatrix.h"
#include "include/core/SkRect.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkTo.h"

#include <cstdint>

/**
 *  Divs must be in increasing order with no duplicates.
 */
static bool valid_divs(const int* divs, int count, int start, int end) {
    int prev = start - 1;
    for (int i = 0; i < count; i++) {
        if (prev >= divs[i] || divs[i] >= end) {
            return false;
        }
        prev = divs[i];
    }

    return true;
}

bool SkLatticeIter::Valid(int width, int height, const SkCanvas::Lattice& lattice) {
    SkIRect totalBounds = SkIRect::MakeWH(width, height);
    SkASSERT(lattice.fBounds);
    const SkIRect latticeBounds = *lattice.fBounds;
    if (!totalBounds.contains(latticeBounds)) {
        return false;
    }

    bool zeroXDivs = lattice.fXCount <= 0 || (1 == lattice.fXCount &&
                                              latticeBounds.fLeft == lattice.fXDivs[0]);
    bool zeroYDivs = lattice.fYCount <= 0 || (1 == lattice.fYCount &&
                                              latticeBounds.fTop == lattice.fYDivs[0]);
    if (zeroXDivs && zeroYDivs) {
        return false;
    }

    return valid_divs(lattice.fXDivs, lattice.fXCount, latticeBounds.fLeft, latticeBounds.fRight)
        && valid_divs(lattice.fYDivs, lattice.fYCount, latticeBounds.fTop, latticeBounds.fBottom);
}

/**
 *  Count the number of pixels that are in "scalable" patches.
 */
static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsScalable,
                                 int start, int end) {
    if (0 == numDivs) {
        return firstIsScalable ? end - start : 0;
    }

    int i;
    int count;
    if (firstIsScalable) {
        count = divs[0] - start;
        i = 1;
    } else {
        count = 0;
        i = 0;
    }

    for (; i < numDivs; i += 2) {
        // Alternatively, we could use |top| and |bottom| as variable names, instead of
        // |left| and |right|.
        int left = divs[i];
        int right = (i + 1 < numDivs) ? divs[i + 1] : end;
        count += right - left;
    }

    return count;
}

/**
 *  Set points for the src and dst rects on subsequent draw calls.
 */
static void set_points(float* dst, int* src, const int* divs, int divCount, int srcFixed,
                       int srcScalable, int srcStart, int srcEnd, float dstStart, float dstEnd,
                       bool isScalable) {
    float dstLen = dstEnd - dstStart;
    float scale;
    if (srcFixed <= dstLen) {
        // This is the "normal" case, where we scale the "scalable" patches and leave
        // the other patches fixed.
        scale = (dstLen - ((float) srcFixed)) / ((float) srcScalable);
    } else {
        // In this case, we eliminate the "scalable" patches and scale the "fixed" patches.
        scale = dstLen / ((float) srcFixed);
    }

    src[0] = srcStart;
    dst[0] = dstStart;
    for (int i = 0; i < divCount; i++) {
        src[i + 1] = divs[i];
        int srcDelta = src[i + 1] - src[i];
        float dstDelta;
        if (srcFixed <= dstLen) {
            dstDelta = isScalable ? scale * srcDelta : srcDelta;
        } else {
            dstDelta = isScalable ? 0.0f : scale * srcDelta;
        }
        dst[i + 1] = dst[i] + dstDelta;

        // Alternate between "scalable" and "fixed" patches.
        isScalable = !isScalable;
    }

    src[divCount + 1] = srcEnd;
    dst[divCount + 1] = dstEnd;
}

SkLatticeIter::SkLatticeIter(const SkCanvas::Lattice& lattice, const SkRect& dst) {
    const int* xDivs = lattice.fXDivs;
    const int origXCount = lattice.fXCount;
    const int* yDivs = lattice.fYDivs;
    const int origYCount = lattice.fYCount;
    SkASSERT(lattice.fBounds);
    const SkIRect src = *lattice.fBounds;

    // In the x-dimension, the first rectangle always starts at x = 0 and is "scalable".
    // If xDiv[0] is 0, it indicates that the first rectangle is degenerate, so the
    // first real rectangle "scalable" in the x-direction.
    //
    // The same interpretation applies to the y-dimension.
    //
    // As we move left to right across the image, alternating patches will be "fixed" or
    // "scalable" in the x-direction.  Similarly, as move top to bottom, alternating
    // patches will be "fixed" or "scalable" in the y-direction.
    int xCount = origXCount;
    int yCount = origYCount;
    bool xIsScalable = (xCount > 0 && src.fLeft == xDivs[0]);
    if (xIsScalable) {
        // Once we've decided that the first patch is "scalable", we don't need the
        // xDiv.  It is always implied that we start at the edge of the bounds.
        xDivs++;
        xCount--;
    }
    bool yIsScalable = (yCount > 0 && src.fTop == yDivs[0]);
    if (yIsScalable) {
        // Once we've decided that the first patch is "scalable", we don't need the
        // yDiv.  It is always implied that we start at the edge of the bounds.
        yDivs++;
        yCount--;
    }

    // Count "scalable" and "fixed" pixels in each dimension.
    int xCountScalable = count_scalable_pixels(xDivs, xCount, xIsScalable, src.fLeft, src.fRight);
    int xCountFixed = src.width() - xCountScalable;
    int yCountScalable = count_scalable_pixels(yDivs, yCount, yIsScalable, src.fTop, src.fBottom);
    int yCountFixed = src.height() - yCountScalable;

    fSrcX.reset(xCount + 2);
    fDstX.reset(xCount + 2);
    set_points(fDstX.begin(), fSrcX.begin(), xDivs, xCount, xCountFixed, xCountScalable,
               src.fLeft, src.fRight, dst.fLeft, dst.fRight, xIsScalable);

    fSrcY.reset(yCount + 2);
    fDstY.reset(yCount + 2);
    set_points(fDstY.begin(), fSrcY.begin(), yDivs, yCount, yCountFixed, yCountScalable,
               src.fTop, src.fBottom, dst.fTop, dst.fBottom, yIsScalable);

    fCurrX = fCurrY = 0;
    fNumRectsInLattice = (xCount + 1) * (yCount + 1);
    fNumRectsToDraw = fNumRectsInLattice;

    if (lattice.fRectTypes) {
        fRectTypes.push_back_n(fNumRectsInLattice);
        fColors.push_back_n(fNumRectsInLattice);

        const SkCanvas::Lattice::RectType* flags = lattice.fRectTypes;
        const SkColor* colors = lattice.fColors;

        bool hasPadRow = (yCount != origYCount);
        bool hasPadCol = (xCount != origXCount);
        if (hasPadRow) {
            // The first row of rects are all empty, skip the first row of flags.
            flags += origXCount + 1;
            colors += origXCount + 1;
        }

        int i = 0;
        for (int y = 0; y < yCount + 1; y++) {
            for (int x = 0; x < origXCount + 1; x++) {
                if (0 == x && hasPadCol) {
                    // The first column of rects are all empty.  Skip a rect.
                    flags++;
                    colors++;
                    continue;
                }

                fRectTypes[i] = *flags;
                fColors[i] = SkCanvas::Lattice::kFixedColor == *flags ? *colors : 0;
                flags++;
                colors++;
                i++;
            }
        }

        for (int j = 0; j < fRectTypes.size(); j++) {
            if (SkCanvas::Lattice::kTransparent == fRectTypes[j]) {
                fNumRectsToDraw--;
            }
        }
    }
}

bool SkLatticeIter::Valid(int width, int height, const SkIRect& center) {
    return !center.isEmpty() && SkIRect::MakeWH(width, height).contains(center);
}

SkLatticeIter::SkLatticeIter(int w, int h, const SkIRect& c, const SkRect& dst) {
    SkASSERT(SkIRect::MakeWH(w, h).contains(c));

    fSrcX.reset(4);
    fSrcY.reset(4);
    fDstX.reset(4);
    fDstY.reset(4);

    fSrcX[0] = 0;
    fSrcX[1] = SkIntToScalar(c.fLeft);
    fSrcX[2] = SkIntToScalar(c.fRight);
    fSrcX[3] = SkIntToScalar(w);

    fSrcY[0] = 0;
    fSrcY[1] = SkIntToScalar(c.fTop);
    fSrcY[2] = SkIntToScalar(c.fBottom);
    fSrcY[3] = SkIntToScalar(h);

    fDstX[0] = dst.fLeft;
    fDstX[1] = dst.fLeft + SkIntToScalar(c.fLeft);
    fDstX[2] = dst.fRight - SkIntToScalar(w - c.fRight);
    fDstX[3] = dst.fRight;

    fDstY[0] = dst.fTop;
    fDstY[1] = dst.fTop + SkIntToScalar(c.fTop);
    fDstY[2] = dst.fBottom - SkIntToScalar(h - c.fBottom);
    fDstY[3] = dst.fBottom;

    if (fDstX[1] > fDstX[2]) {
        fDstX[1] = fDstX[0] + (fDstX[3] - fDstX[0]) * c.fLeft / (w - c.width());
        fDstX[2] = fDstX[1];
    }

    if (fDstY[1] > fDstY[2]) {
        fDstY[1] = fDstY[0] + (fDstY[3] - fDstY[0]) * c.fTop / (h - c.height());
        fDstY[2] = fDstY[1];
    }

    fCurrX = fCurrY = 0;
    fNumRectsInLattice = 9;
    fNumRectsToDraw = 9;
}

bool SkLatticeIter::next(SkIRect* src, SkRect* dst, bool* isFixedColor, SkColor* fixedColor) {
    int currRect = fCurrX + fCurrY * (fSrcX.size() - 1);
    if (currRect == fNumRectsInLattice) {
        return false;
    }

    const int x = fCurrX;
    const int y = fCurrY;
    SkASSERT(x >= 0 && x < fSrcX.size() - 1);
    SkASSERT(y >= 0 && y < fSrcY.size() - 1);

    if (fSrcX.size() - 1 == ++fCurrX) {
        fCurrX = 0;
        fCurrY += 1;
    }

    if (!fRectTypes.empty() && SkToBool(SkCanvas::Lattice::kTransparent == fRectTypes[currRect])) {
        return this->next(src, dst, isFixedColor, fixedColor);
    }

    src->setLTRB(fSrcX[x], fSrcY[y], fSrcX[x + 1], fSrcY[y + 1]);
    dst->setLTRB(fDstX[x], fDstY[y], fDstX[x + 1], fDstY[y + 1]);
    if (isFixedColor && fixedColor) {
        *isFixedColor = !fRectTypes.empty() &&
                        SkToBool(SkCanvas::Lattice::kFixedColor == fRectTypes[currRect]);
        if (*isFixedColor) {
            *fixedColor = fColors[currRect];
        }
    }
    return true;
}

void SkLatticeIter::mapDstScaleTranslate(const SkMatrix& matrix) {
    SkASSERT(matrix.isScaleTranslate());
    SkScalar tx = matrix.getTranslateX();
    SkScalar sx = matrix.getScaleX();
    for (int i = 0; i < fDstX.size(); i++) {
        fDstX[i] = fDstX[i] * sx + tx;
    }

    SkScalar ty = matrix.getTranslateY();
    SkScalar sy = matrix.getScaleY();
    for (int i = 0; i < fDstY.size(); i++) {
        fDstY[i] = fDstY[i] * sy + ty;
    }
}
