/*
 * 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 androidx.renderscript;

import android.util.Log;

/**
 * Intrinsic Histogram filter.
 *
 * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
 * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
 * guide</a> for the proposed alternatives.
 **/
@Deprecated
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("Unsupported 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);
    }
}

