/*
 * Copyright (C) 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.
 */

package android.graphics;


/**
 * The NinePatch class permits drawing a bitmap in nine sections.
 * The four corners are unscaled; the four edges are scaled in one axis,
 * and the middle is scaled in both axes. Normally, the middle is 
 * transparent so that the patch can provide a selection about a rectangle.
 * Essentially, it allows the creation of custom graphics that will scale the 
 * way that you define, when content added within the image exceeds the normal
 * bounds of the graphic. For a thorough explanation of a NinePatch image, 
 * read the discussion in the 
 * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D
 * Graphics</a> document.
 * <p>
 * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a> 
 * tool offers an extremely handy way to create your NinePatch images,
 * using a WYSIWYG graphics editor.
 * </p>
 */
public class NinePatch {
    /** 
     * Create a drawable projection from a bitmap to nine patches.
     *
     * @param bitmap    The bitmap describing the patches.
     * @param chunk     The 9-patch data chunk describing how the underlying
     *                  bitmap is split apart and drawn.
     * @param srcName   The name of the source for the bitmap. Might be null.
     */
    public NinePatch(Bitmap bitmap, byte[] chunk, String srcName) {
        mBitmap = bitmap;
        mChunk = chunk;
        mSrcName = srcName;
        validateNinePatchChunk(mBitmap.ni(), chunk);
    }

    /**
     * @hide
     */
    public NinePatch(NinePatch patch) {
        mBitmap = patch.mBitmap;
        mChunk = patch.mChunk;
        mSrcName = patch.mSrcName;
        mPaint = new Paint(patch.mPaint);
        validateNinePatchChunk(mBitmap.ni(), mChunk);
    }

    public void setPaint(Paint p) {
        mPaint = p;
    }
    
    /** 
     * Draw a bitmap to nine patches.
     *
     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
     * @param location  Where to draw the bitmap.
     */
    public void draw(Canvas canvas, RectF location) {
        nativeDraw(canvas.mNativeCanvas, location,
                   mBitmap.ni(), mChunk,
                   mPaint != null ? mPaint.mNativePaint : 0);
    }
    
    /** 
     * Draw a bitmap to nine patches.
     *
     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
     * @param location  Where to draw the bitmap.
     */
    public void draw(Canvas canvas, Rect location) {
        nativeDraw(canvas.mNativeCanvas, location,
                   mBitmap.ni(), mChunk,
                   mPaint != null ? mPaint.mNativePaint : 0);
    }

    /** 
     * Draw a bitmap to nine patches.
     *
     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
     * @param location  Where to draw the bitmap.
     * @param paint     The Paint to draw through.
     */
    public void draw(Canvas canvas, Rect location, Paint paint) {
        nativeDraw(canvas.mNativeCanvas, location,
                   mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0);
    }

    public int getWidth() {
        return mBitmap.getWidth();
    }

    public int getHeight() {
        return mBitmap.getHeight();
    }

    public final boolean hasAlpha() {
        return mBitmap.hasAlpha();
    }

    public final Region getTransparentRegion(Rect location) {
        int r = nativeGetTransparentRegion(mBitmap.ni(), mChunk, location);
        return r != 0 ? new Region(r) : null;
    }
    
    public native static boolean isNinePatchChunk(byte[] chunk);

    private final Rect   mRect = new Rect();
    private final Bitmap mBitmap;
    private final byte[] mChunk;
    private Paint        mPaint;
    private String       mSrcName;  // Useful for debugging

    private static native void validateNinePatchChunk(int bitmap, byte[] chunk);
    private static native void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
                                          byte[] c, int paint_instance_or_null);
    private static native void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
                                          byte[] c, int paint_instance_or_null);
    private static native int nativeGetTransparentRegion(
            int bitmap, byte[] chunk, Rect location);
}
