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

import android.util.Log;

/**
 * Intrinsic Histogram filter.
 *
 *
 **/
public class ScriptIntrinsicHistogram extends ScriptIntrinsic {
    private Allocation mOut;
    // API level for the intrinsic
    private static final int INTRINSIC_API_LEVEL = 19;

    protected ScriptIntrinsicHistogram(long id, RenderScript rs) {
        super(id, rs);
    }

    /**
     * Create an intrinsic for calculating the histogram of an uchar
     * or uchar4 image.
     *
     * Supported elements types are
     * {@link Element#U8_4}, {@link Element#U8_3},
     * {@link Element#U8_2}, {@link Element#U8}
     *
     * @param rs The RenderScript context
     * @param e Element type for inputs
     *
     * @return ScriptIntrinsicHistogram
     */
    public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
        if ((!e.isCompatible(Element.U8_4(rs))) &&
            (!e.isCompatible(Element.U8_3(rs))) &&
            (!e.isCompatible(Element.U8_2(rs))) &&
            (!e.isCompatible(Element.U8(rs)))) {
            throw new RSIllegalArgumentException("Unsuported element type.");
        }
        long id;
        boolean mUseIncSupp = rs.isUseNative() &&
                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;

        id = rs.nScriptIntrinsicCreate(9, e.getID(rs), mUseIncSupp);

        ScriptIntrinsicHistogram si = new ScriptIntrinsicHistogram(id, rs);
        si.setIncSupp(mUseIncSupp);
        return si;
    }

    /**
     * Process an input buffer and place the histogram into the
     * output allocation. The output allocation may be a narrower
     * vector size than the input. In this case the vector size of
     * the output is used to determine how many of the input
     * channels are used in the computation. This is useful if you
     * have an RGBA input buffer but only want the histogram for
     * RGB.
     *
     * 1D and 2D input allocations are supported.
     *
     * @param ain The input image
     */
    public void forEach(Allocation ain) {
        forEach(ain, null);
    }

    /**
     * Process an input buffer and place the histogram into the
     * output allocation. The output allocation may be a narrower
     * vector size than the input. In this case the vector size of
     * the output is used to determine how many of the input
     * channels are used in the computation. This is useful if you
     * have an RGBA input buffer but only want the histogram for
     * RGB.
     *
     * 1D and 2D input allocations are supported.
     *
     * @param ain The input image
     * @param opt LaunchOptions for clipping
     */
    public void forEach(Allocation ain, Script.LaunchOptions opt) {
        if (ain.getType().getElement().getVectorSize() <
            mOut.getType().getElement().getVectorSize()) {

            throw new RSIllegalArgumentException(
                "Input vector size must be >= output vector size.");
        }
        if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
            !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
            !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
            !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
            throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
        }

        forEach(0, ain, null, null, opt);
    }



    /**
     * Set the coefficients used for the RGBA to Luminocity
     * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
     *
     * Coefficients must be >= 0 and sum to 1.0 or less.
     *
     * @param r Red coefficient
     * @param g Green coefficient
     * @param b Blue coefficient
     * @param a Alpha coefficient
     */
    public void setDotCoefficients(float r, float g, float b, float a) {
        if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
            throw new RSIllegalArgumentException("Coefficient may not be negative.");
        }
        if ((r + g + b + a) > 1.f) {
            throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
        }

        FieldPacker fp = new FieldPacker(16);
        fp.addF32(r);
        fp.addF32(g);
        fp.addF32(b);
        fp.addF32(a);
        setVar(0, fp);
    }

    /**
     * Set the output of the histogram.  32 bit integer types are
     * supported.
     *
     * @param aout The output allocation
     */
    public void setOutput(Allocation aout) {
        mOut = aout;
        if (mOut.getType().getElement() != Element.U32(mRS) &&
            mOut.getType().getElement() != Element.U32_2(mRS) &&
            mOut.getType().getElement() != Element.U32_3(mRS) &&
            mOut.getType().getElement() != Element.U32_4(mRS) &&
            mOut.getType().getElement() != Element.I32(mRS) &&
            mOut.getType().getElement() != Element.I32_2(mRS) &&
            mOut.getType().getElement() != Element.I32_3(mRS) &&
            mOut.getType().getElement() != Element.I32_4(mRS)) {

            throw new RSIllegalArgumentException("Output type must be U32 or I32.");
        }
        if ((mOut.getType().getX() != 256) ||
            (mOut.getType().getY() != 0) ||
            mOut.getType().hasMipmaps() ||
            (mOut.getType().getYuv() != 0)) {

            throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
        }
        setVar(1, aout);
    }


    /**
     * Process an input buffer and place the histogram into the
     * output allocation. The dot product of the input channel and
     * the coefficients from 'setDotCoefficients' are used to
     * calculate the output values.
     *
     * 1D and 2D input allocations are supported.
     *
     * @param ain The input image
     */
    public void forEach_Dot(Allocation ain) {
        forEach_Dot(ain, null);
    }

    /**
     * Process an input buffer and place the histogram into the
     * output allocation. The dot product of the input channel and
     * the coefficients from 'setDotCoefficients' are used to
     * calculate the output values.
     *
     * 1D and 2D input allocations are supported.
     *
     * @param ain The input image
     * @param opt LaunchOptions for clipping
     */
    public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
        if (mOut.getType().getElement().getVectorSize() != 1) {
            throw new RSIllegalArgumentException("Output vector size must be one.");
        }
        if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
            !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
            !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
            !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
            throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
        }

        forEach(1, ain, null, null, opt);
    }



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

    /**
     * Get a FieldID for the input field of this intrinsic.
     *
     * @return Script.FieldID The FieldID object.
     */
    public Script.FieldID getFieldID_Input() {
        return createFieldID(1, null);
    }
}

