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

/**
 * Shader is the based class for objects that return horizontal spans of colors
 * during drawing. A subclass of Shader is installed in a Paint calling
 * paint.setShader(shader). After that any object (other than a bitmap) that is
 * drawn with that paint will get its color(s) from the shader.
 */
public class Shader {
    /**
     * This is set by subclasses, but don't make it public.
     */
    private long native_instance;

    /**
     * Initialization step that should be called by subclasses in their
     * constructors. Calling again may result in memory leaks.
     * @hide
     */
    protected void init(long ni) {
        native_instance = ni;
    }

    private Matrix mLocalMatrix;

    public enum TileMode {
        /**
         * replicate the edge color if the shader draws outside of its
         * original bounds
         */
        CLAMP   (0),
        /**
         * repeat the shader's image horizontally and vertically
         */
        REPEAT  (1),
        /**
         * repeat the shader's image horizontally and vertically, alternating
         * mirror images so that adjacent images always seam
         */
        MIRROR  (2);
    
        TileMode(int nativeInt) {
            this.nativeInt = nativeInt;
        }
        final int nativeInt;
    }

    /**
     * Return true if the shader has a non-identity local matrix.
     * @param localM If not null, it is set to the shader's local matrix.
     * @return true if the shader has a non-identity local matrix
     */
    public boolean getLocalMatrix(Matrix localM) {
        if (mLocalMatrix != null) {
            localM.set(mLocalMatrix);
            return !mLocalMatrix.isIdentity();
        }
        return false;
    }

    /**
     * Set the shader's local matrix. Passing null will reset the shader's
     * matrix to identity.
     *
     * @param localM The shader's new local matrix, or null to specify identity
     */
    public void setLocalMatrix(Matrix localM) {
        mLocalMatrix = localM;
        native_instance = nativeSetLocalMatrix(native_instance,
                localM == null ? 0 : localM.native_instance);
    }

    protected void finalize() throws Throwable {
        try {
            super.finalize();
        } finally {
            nativeDestructor(native_instance);
            native_instance = 0;  // Other finalizers can still call us.
        }
    }

    /**
     * @hide
     */
    protected Shader copy() {
        final Shader copy = new Shader();
        copyLocalMatrix(copy);
        return copy;
    }

    /**
     * @hide
     */
    protected void copyLocalMatrix(Shader dest) {
        if (mLocalMatrix != null) {
            final Matrix lm = new Matrix();
            getLocalMatrix(lm);
            dest.setLocalMatrix(lm);
        } else {
            dest.setLocalMatrix(null);
        }
    }

    /**
     * @hide
     */
    public long getNativeInstance() {
        return native_instance;
    }

    private static native void nativeDestructor(long native_shader);
    private static native long nativeSetLocalMatrix(long native_shader, long matrix_instance);
}
