/*
**
** 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.
*/

#include "utils/NinePatch.h"

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

#include <utils/Log.h>

namespace android {

static const bool kUseTrace = true;
static bool gTrace = false;

static bool getColor(const SkBitmap& bitmap, int x, int y, SkColor* c) {
    switch (bitmap.colorType()) {
        case kN32_SkColorType:
            *c = SkUnPreMultiply::PMColorToColor(*bitmap.getAddr32(x, y));
            break;
        case kRGB_565_SkColorType:
            *c = SkPixel16ToPixel32(*bitmap.getAddr16(x, y));
            break;
        case kARGB_4444_SkColorType:
            *c = SkUnPreMultiply::PMColorToColor(
                                SkPixel4444ToPixel32(*bitmap.getAddr16(x, y)));
            break;
        case kIndex_8_SkColorType: {
            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, SkRect::Make(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 srcSpace * stretchySpaceRemaining / numStrechyPixelsRemaining;
}

void NinePatch::Draw(SkCanvas* canvas, const SkRect& bounds,
                     const SkBitmap& bitmap, const 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;
    }
   
    const int32_t* xDivs = chunk.getXDivs();
    const int32_t* yDivs = chunk.getYDivs();
    // 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,
                              xDivs, chunk.numXDivs,
                              yDivs, chunk.numYDivs,
                              paint);
        return;
    }

    if (kUseTrace) {
        gTrace = true;
    }

    SkASSERT(canvas || outRegion);

    if (kUseTrace) {
        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]));
        }

        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", xDivs[0], xDivs[1]);
        ALOGV("======== ninepatch yDivs [%d,%d]\n", yDivs[0], yDivs[1]);
    }

    if (bounds.isEmpty() ||
        bitmap.width() == 0 || bitmap.height() == 0 ||
        (paint && paint->getXfermode() == NULL && paint->getAlpha() == 0))
    {
        if (kUseTrace) {
            ALOGV("======== abort ninepatch draw\n");
        }
        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 = xDivs[0];
    const int32_t y0 = 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();

    // Number of bytes needed for dstRights array.
    // Need to cast numXDivs to a larger type to avoid overflow.
    const size_t dstBytes = ((size_t) numXDivs + 1) * sizeof(SkScalar);
    SkScalar* dstRights = (SkScalar*) alloca(dstBytes);
    bool dstRightsHaveBeenCached = false;

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

    if (kUseTrace) {
        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);
    }

    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) or 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 = 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.
        const uint32_t* colors = chunk.getColors();
        for (i = xIsStretchable ? 1 : 0;
              i <= numXDivs && src.fLeft < bitmapWidth;
              i++, xIsStretchable = !xIsStretchable) {
            color = colors[colorIndex++];
            if (i == numXDivs) {
                src.fRight = bitmapWidth;
                dst.fRight = bounds.fRight;
            } else {
                src.fRight = 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) {
                if (kUseTrace) {
                    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");
                    }
                }
                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;
    }
}

} // namespace android
