/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

namespace android {
namespace NinePatchUtils {

static inline void SetLatticeDivs(SkCanvas::Lattice* lattice, const Res_png_9patch& chunk,
                                  int width, int height) {
    lattice->fXCount = chunk.numXDivs;
    lattice->fYCount = chunk.numYDivs;
    lattice->fXDivs = chunk.getXDivs();
    lattice->fYDivs = chunk.getYDivs();

    // We'll often see ninepatches where the last div is equal to the width or height.
    // This doesn't provide any additional information and is not supported by Skia.
    if (lattice->fXCount > 0 && width == lattice->fXDivs[lattice->fXCount - 1]) {
        lattice->fXCount--;
    }
    if (lattice->fYCount > 0 && height == lattice->fYDivs[lattice->fYCount - 1]) {
        lattice->fYCount--;
    }
}

static inline int NumDistinctRects(const SkCanvas::Lattice& lattice) {
    int xRects;
    if (lattice.fXCount > 0) {
        xRects = (0 == lattice.fXDivs[0]) ? lattice.fXCount : lattice.fXCount + 1;
    } else {
        xRects = 1;
    }

    int yRects;
    if (lattice.fYCount > 0) {
        yRects = (0 == lattice.fYDivs[0]) ? lattice.fYCount : lattice.fYCount + 1;
    } else {
        yRects = 1;
    }
    return xRects * yRects;
}

static inline void SetLatticeFlags(SkCanvas::Lattice* lattice, SkCanvas::Lattice::Flags* flags,
                                   int numFlags, const Res_png_9patch& chunk) {
    lattice->fFlags = flags;
    sk_bzero(flags, numFlags * sizeof(SkCanvas::Lattice::Flags));

    bool needPadRow = lattice->fYCount > 0 && 0 == lattice->fYDivs[0];
    bool needPadCol = lattice->fXCount > 0 && 0 == lattice->fXDivs[0];

    int yCount = lattice->fYCount;
    if (needPadRow) {
        // Skip flags for the degenerate first row of rects.
        flags += lattice->fXCount + 1;
        yCount--;
    }

    int i = 0;
    bool setFlags = false;
    for (int y = 0; y < yCount + 1; y++) {
        for (int x = 0; x < lattice->fXCount + 1; x++) {
            if (0 == x && needPadCol) {
                // First rect of each column is degenerate, skip the flag.
                flags++;
                continue;
            }

            if (0 == chunk.getColors()[i++]) {
                *flags = SkCanvas::Lattice::kTransparent_Flags;
                setFlags = true;
            }

            flags++;
        }
    }

    if (!setFlags) {
        lattice->fFlags = nullptr;
    }
}

};  // namespace NinePatchUtils
};  // namespace android
