/*
**
** Copyright 2006, 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.
*/

#define LOG_TAG "NinePatch"
#define LOG_NDEBUG 1

#include <androidfw/ResourceTypes.h>
#include <utils/Log.h>

#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkNinePatch.h"
#include "SkPaint.h"
#include "SkUnPreMultiply.h"

#define USE_TRACE

#ifdef USE_TRACE
    static bool gTrace;
#endif

#include "SkColorPriv.h"

#include <utils/Log.h>

static bool getColor(const SkBitmap& bitmap, int x, int y, SkColor* c) {
    switch (bitmap.config()) {
        case SkBitmap::kARGB_8888_Config:
            *c = SkUnPreMultiply::PMColorToColor(*bitmap.getAddr32(x, y));
            break;
        case SkBitmap::kRGB_565_Config:
            *c = SkPixel16ToPixel32(*bitmap.getAddr16(x, y));
            break;
        case SkBitmap::kARGB_4444_Config:
            *c = SkUnPreMultiply::PMColorToColor(
                                SkPixel4444ToPixel32(*bitmap.getAddr16(x, y)));
            break;
        case SkBitmap::kIndex8_Config: {
            SkColorTable* ctable = bitmap.getColorTable();
            *c = SkUnPreMultiply::PMColorToColor(
                                            (*ctable)[*bitmap.getAddr8(x, y)]);
            break;
        }
        default:
            return false;
    }
    return true;
}

static SkColor modAlpha(SkColor c, int alpha) {
    int scale = alpha + (alpha >> 7);
    int a = SkColorGetA(c) * scale >> 8;
    return SkColorSetA(c, a);
}

static void drawStretchyPatch(SkCanvas* canvas, SkIRect& src, const SkRect& dst,
                              const SkBitmap& bitmap, const SkPaint& paint,
                              SkColor initColor, uint32_t colorHint,
                              bool hasXfer) {
    if (colorHint !=  android::Res_png_9patch::NO_COLOR) {
        ((SkPaint*)&paint)->setColor(modAlpha(colorHint, paint.getAlpha()));
        canvas->drawRect(dst, paint);
        ((SkPaint*)&paint)->setColor(initColor);
    } else if (src.width() == 1 && src.height() == 1) {
        SkColor c;
        if (!getColor(bitmap, src.fLeft, src.fTop, &c)) {
            goto SLOW_CASE;
        }
        if (0 != c || hasXfer) {
            SkColor prev = paint.getColor();
            ((SkPaint*)&paint)->setColor(c);
            canvas->drawRect(dst, paint);
            ((SkPaint*)&paint)->setColor(prev);
        }
    } else {
    SLOW_CASE:
        canvas->drawBitmapRect(bitmap, &src, dst, &paint);
    }
}

SkScalar calculateStretch(SkScalar boundsLimit, SkScalar startingPoint,
                          int srcSpace, int numStrechyPixelsRemaining,
                          int numFixedPixelsRemaining) {
    SkScalar spaceRemaining = boundsLimit - startingPoint;
    SkScalar stretchySpaceRemaining =
                spaceRemaining - SkIntToScalar(numFixedPixelsRemaining);
    return SkScalarMulDiv(srcSpace, stretchySpaceRemaining,
                          numStrechyPixelsRemaining);
}

void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds,
                       const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
                       const SkPaint* paint, SkRegion** outRegion) {
    if (canvas && canvas->quickReject(bounds)) {
        return;
    }

    SkPaint defaultPaint;
    if (NULL == paint) {
        // matches default dither in NinePatchDrawable.java.
        defaultPaint.setDither(true);
        paint = &defaultPaint;
    }
    
    // if our SkCanvas were back by GL we should enable this and draw this as
    // a mesh, which will be faster in most cases.
    if (false) {
        SkNinePatch::DrawMesh(canvas, bounds, bitmap,
                              chunk.xDivs, chunk.numXDivs,
                              chunk.yDivs, chunk.numYDivs,
                              paint);
        return;
    }

#ifdef USE_TRACE
    gTrace = true;
#endif

    SkASSERT(canvas || outRegion);

#ifdef USE_TRACE
    if (canvas) {
        const SkMatrix& m = canvas->getTotalMatrix();
        ALOGV("ninepatch [%g %g %g] [%g %g %g]\n",
                 SkScalarToFloat(m[0]), SkScalarToFloat(m[1]), SkScalarToFloat(m[2]),
                 SkScalarToFloat(m[3]), SkScalarToFloat(m[4]), SkScalarToFloat(m[5]));
    }
#endif

#ifdef USE_TRACE
    if (gTrace) {
        ALOGV("======== ninepatch bounds [%g %g]\n", SkScalarToFloat(bounds.width()), SkScalarToFloat(bounds.height()));
        ALOGV("======== ninepatch paint bm [%d,%d]\n", bitmap.width(), bitmap.height());
        ALOGV("======== ninepatch xDivs [%d,%d]\n", chunk.xDivs[0], chunk.xDivs[1]);
        ALOGV("======== ninepatch yDivs [%d,%d]\n", chunk.yDivs[0], chunk.yDivs[1]);
    }
#endif

    if (bounds.isEmpty() ||
        bitmap.width() == 0 || bitmap.height() == 0 ||
        (paint && paint->getXfermode() == NULL && paint->getAlpha() == 0))
    {
#ifdef USE_TRACE
        if (gTrace) ALOGV("======== abort ninepatch draw\n");
#endif
        return;
    }
    
    // should try a quick-reject test before calling lockPixels 

    SkAutoLockPixels alp(bitmap);
    // after the lock, it is valid to check getPixels()
    if (bitmap.getPixels() == NULL)
        return;

    const bool hasXfer = paint->getXfermode() != NULL;
    SkRect      dst;
    SkIRect     src;

    const int32_t x0 = chunk.xDivs[0];
    const int32_t y0 = chunk.yDivs[0];
    const SkColor initColor = ((SkPaint*)paint)->getColor();
    const uint8_t numXDivs = chunk.numXDivs;
    const uint8_t numYDivs = chunk.numYDivs;
    int i;
    int j;
    int colorIndex = 0;
    uint32_t color;
    bool xIsStretchable;
    const bool initialXIsStretchable =  (x0 == 0);
    bool yIsStretchable = (y0 == 0);
    const int bitmapWidth = bitmap.width();
    const int bitmapHeight = bitmap.height();

    SkScalar* dstRights = (SkScalar*) alloca((numXDivs + 1) * sizeof(SkScalar));
    bool dstRightsHaveBeenCached = false;

    int numStretchyXPixelsRemaining = 0;
    for (i = 0; i < numXDivs; i += 2) {
        numStretchyXPixelsRemaining += chunk.xDivs[i + 1] - chunk.xDivs[i];
    }
    int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining;
    int numStretchyYPixelsRemaining = 0;
    for (i = 0; i < numYDivs; i += 2) {
        numStretchyYPixelsRemaining += chunk.yDivs[i + 1] - chunk.yDivs[i];
    }
    int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;

#ifdef USE_TRACE
    ALOGV("NinePatch [%d %d] bounds [%g %g %g %g] divs [%d %d]\n",
             bitmap.width(), bitmap.height(),
             SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
             SkScalarToFloat(bounds.width()), SkScalarToFloat(bounds.height()),
             numXDivs, numYDivs);
#endif

    src.fTop = 0;
    dst.fTop = bounds.fTop;
    // The first row always starts with the top being at y=0 and the bottom
    // being either yDivs[1] (if yDivs[0]=0) of yDivs[0].  In the former case
    // the first row is stretchable along the Y axis, otherwise it is fixed.
    // The last row always ends with the bottom being bitmap.height and the top
    // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or
    // yDivs[numYDivs-1]. In the former case the last row is stretchable along
    // the Y axis, otherwise it is fixed.
    //
    // The first and last columns are similarly treated with respect to the X
    // axis.
    //
    // The above is to help explain some of the special casing that goes on the
    // code below.

    // The initial yDiv and whether the first row is considered stretchable or
    // not depends on whether yDiv[0] was zero or not.
    for (j = yIsStretchable ? 1 : 0;
          j <= numYDivs && src.fTop < bitmapHeight;
          j++, yIsStretchable = !yIsStretchable) {
        src.fLeft = 0;
        dst.fLeft = bounds.fLeft;
        if (j == numYDivs) {
            src.fBottom = bitmapHeight;
            dst.fBottom = bounds.fBottom;
        } else {
            src.fBottom = chunk.yDivs[j];
            const int srcYSize = src.fBottom - src.fTop;
            if (yIsStretchable) {
                dst.fBottom = dst.fTop + calculateStretch(bounds.fBottom, dst.fTop,
                                                          srcYSize,
                                                          numStretchyYPixelsRemaining,
                                                          numFixedYPixelsRemaining);
                numStretchyYPixelsRemaining -= srcYSize;
            } else {
                dst.fBottom = dst.fTop + SkIntToScalar(srcYSize);
                numFixedYPixelsRemaining -= srcYSize;
            }
        }

        xIsStretchable = initialXIsStretchable;
        // The initial xDiv and whether the first column is considered
        // stretchable or not depends on whether xDiv[0] was zero or not.
        for (i = xIsStretchable ? 1 : 0;
              i <= numXDivs && src.fLeft < bitmapWidth;
              i++, xIsStretchable = !xIsStretchable) {
            color = chunk.colors[colorIndex++];
            if (i == numXDivs) {
                src.fRight = bitmapWidth;
                dst.fRight = bounds.fRight;
            } else {
                src.fRight = chunk.xDivs[i];
                if (dstRightsHaveBeenCached) {
                    dst.fRight = dstRights[i];
                } else {
                    const int srcXSize = src.fRight - src.fLeft;
                    if (xIsStretchable) {
                        dst.fRight = dst.fLeft + calculateStretch(bounds.fRight, dst.fLeft,
                                                                  srcXSize,
                                                                  numStretchyXPixelsRemaining,
                                                                  numFixedXPixelsRemaining);
                        numStretchyXPixelsRemaining -= srcXSize;
                    } else {
                        dst.fRight = dst.fLeft + SkIntToScalar(srcXSize);
                        numFixedXPixelsRemaining -= srcXSize;
                    }
                    dstRights[i] = dst.fRight;
                }
            }
            // If this horizontal patch is too small to be displayed, leave
            // the destination left edge where it is and go on to the next patch
            // in the source.
            if (src.fLeft >= src.fRight) {
                src.fLeft = src.fRight;
                continue;
            }
            // Make sure that we actually have room to draw any bits
            if (dst.fRight <= dst.fLeft || dst.fBottom <= dst.fTop) {
                goto nextDiv;
            }
            // If this patch is transparent, skip and don't draw.
            if (color == android::Res_png_9patch::TRANSPARENT_COLOR && !hasXfer) {
                if (outRegion) {
                    if (*outRegion == NULL) {
                        *outRegion = new SkRegion();
                    }
                    SkIRect idst;
                    dst.round(&idst);
                    //ALOGI("Adding trans rect: (%d,%d)-(%d,%d)\n",
                    //     idst.fLeft, idst.fTop, idst.fRight, idst.fBottom);
                    (*outRegion)->op(idst, SkRegion::kUnion_Op);
                }
                goto nextDiv;
            }
            if (canvas) {
#ifdef USE_TRACE
                ALOGV("-- src [%d %d %d %d] dst [%g %g %g %g]\n",
                         src.fLeft, src.fTop, src.width(), src.height(),
                         SkScalarToFloat(dst.fLeft), SkScalarToFloat(dst.fTop),
                         SkScalarToFloat(dst.width()), SkScalarToFloat(dst.height()));
                if (2 == src.width() && SkIntToScalar(5) == dst.width()) {
                    ALOGV("--- skip patch\n");
                }
#endif
                drawStretchyPatch(canvas, src, dst, bitmap, *paint, initColor,
                                  color, hasXfer);
            }

nextDiv:
            src.fLeft = src.fRight;
            dst.fLeft = dst.fRight;
        }
        src.fTop = src.fBottom;
        dst.fTop = dst.fBottom;
        dstRightsHaveBeenCached = true;
    }
}
