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

import android.util.Log;

/**
 * Intrinsic for applying a per-channel lookup table. Each
 * channel of the input has an independant lookup table. The
 * tables are 256 entries in size and can cover the full value
 * range of {@link Element#U8_4}.
 **/
public final class ScriptIntrinsicLUT extends ScriptIntrinsic {
    private final Matrix4f mMatrix = new Matrix4f();
    private Allocation mTables;
    private final byte mCache[] = new byte[1024];
    private boolean mDirty = true;

    private ScriptIntrinsicLUT(int id, RenderScript rs) {
        super(id, rs);
        mTables = Allocation.createSized(rs, Element.U8(rs), 1024);
        for (int ct=0; ct < 256; ct++) {
            mCache[ct] = (byte)ct;
            mCache[ct + 256] = (byte)ct;
            mCache[ct + 512] = (byte)ct;
            mCache[ct + 768] = (byte)ct;
        }
        setVar(0, mTables);
    }

    /**
     * Supported elements types are {@link Element#U8_4}
     *
     * The defaults tables are identity.
     *
     * @param rs The RenderScript context
     * @param e Element type for intputs and outputs
     *
     * @return ScriptIntrinsicLUT
     */
    public static ScriptIntrinsicLUT create(RenderScript rs, Element e) {
        int id = rs.nScriptIntrinsicCreate(3, e.getID(rs));
        return new ScriptIntrinsicLUT(id, rs);

    }


    private void validate(int index, int value) {
        if (index < 0 || index > 255) {
            throw new RSIllegalArgumentException("Index out of range (0-255).");
        }
        if (value < 0 || value > 255) {
            throw new RSIllegalArgumentException("Value out of range (0-255).");
        }
    }

    /**
     * Set an entry in the red channel lookup table
     *
     * @param index Must be 0-255
     * @param value Must be 0-255
     */
    public void setRed(int index, int value) {
        validate(index, value);
        mCache[index] = (byte)value;
        mDirty = true;
    }

    /**
     * Set an entry in the green channel lookup table
     *
     * @param index Must be 0-255
     * @param value Must be 0-255
     */
    public void setGreen(int index, int value) {
        validate(index, value);
        mCache[index+256] = (byte)value;
        mDirty = true;
    }

    /**
     * Set an entry in the blue channel lookup table
     *
     * @param index Must be 0-255
     * @param value Must be 0-255
     */
    public void setBlue(int index, int value) {
        validate(index, value);
        mCache[index+512] = (byte)value;
        mDirty = true;
    }

    /**
     * Set an entry in the alpha channel lookup table
     *
     * @param index Must be 0-255
     * @param value Must be 0-255
     */
    public void setAlpha(int index, int value) {
        validate(index, value);
        mCache[index+768] = (byte)value;
        mDirty = true;
    }


    /**
     * Invoke the kernel and apply the lookup to each cell of ain
     * and copy to aout.
     *
     * @param ain Input allocation
     * @param aout Output allocation
     */
    public void forEach(Allocation ain, Allocation aout) {
        if (mDirty) {
            mDirty = false;
            mTables.copyFromUnchecked(mCache);
        }
        forEach(0, ain, aout, null);
    }

    /**
     * Get a KernelID for this intrinsic kernel.
     *
     * @return Script.KernelID The KernelID object.
     */
    public Script.KernelID getKernelID() {
        return createKernelID(0, 3, null, null);
    }
}

