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

/*
 * This file is auto-generated. DO NOT MODIFY!
 * The source Renderscript file: reduce_general_duplicate_array.rs
 */

package array;

import android.renderscript.*;
import array.reduce_general_duplicate_arrayBitCode;

/**
 * @hide
 */
public class ScriptC_reduce_general_duplicate_array extends ScriptC {
    private static final String __rs_resource_name = "reduce_general_duplicate_array";
    // Constructor
    public  ScriptC_reduce_general_duplicate_array(RenderScript rs) {
        super(rs,
              __rs_resource_name,
              reduce_general_duplicate_arrayBitCode.getBitCode32(),
              reduce_general_duplicate_arrayBitCode.getBitCode64());
        mRSLocal = rs;
        __I32 = Element.I32(rs);
    }

    private Element __I32;
    private RenderScript mRSLocal;
    // To obtain the result, invoke get(), which blocks
    // until the asynchronously-launched operation has completed.
    public static class resultArray4_int {
        public int[] get() {
            if (!mGotResult) {
                int[] outArray = new int[4];
                mOut.copyTo(outArray);
                mResult = outArray;
                mOut.destroy();
                mOut = null;  // make Java object eligible for garbage collection
                if (mTempIns != null) {
                    for (Allocation tempIn : mTempIns) {
                        tempIn.destroy();
                    }

                    mTempIns = null;  // make Java objects eligible for garbage collection
                }

                mGotResult = true;
            }

            return mResult;
        }

        private  resultArray4_int(Allocation out) {
            mTempIns = null;
            mOut = out;
            mGotResult = false;
        }

        private Allocation[] mTempIns;
        private Allocation mOut;
        private boolean mGotResult;
        private int[] mResult;
    }

    private final static int mExportReduceIdx_sumDec = 0;
    // in1 = "val"
    public resultArray4_int reduce_sumDec(int[] in1) {
        // Verify that "in1" is non-null.
        if (in1 == null) {
            throw new RSIllegalArgumentException("Array \"in1\" is null!");
        }
        Allocation ain1 = Allocation.createSized(mRSLocal, __I32, in1.length);
        ain1.setAutoPadding(true);
        ain1.copyFrom(in1);

        resultArray4_int result = reduce_sumDec(ain1, null);
        result.mTempIns = new Allocation[]{ain1};
        return result;
    }

    // ain1 = "int val"
    public resultArray4_int reduce_sumDec(Allocation ain1) {
        return reduce_sumDec(ain1, null);
    }

    // ain1 = "int val"
    public resultArray4_int reduce_sumDec(Allocation ain1, Script.LaunchOptions sc) {
        // check ain1
        if (!ain1.getType().getElement().isCompatible(__I32)) {
            throw new RSRuntimeException("Type mismatch with I32!");
        }
        Allocation aout = Allocation.createSized(mRSLocal, __I32, 4);
        aout.setAutoPadding(true);
        reduce(mExportReduceIdx_sumDec, new Allocation[]{ain1}, aout, sc);
        return new resultArray4_int(aout);
    }

    private final static int mExportReduceIdx_sumInc = 1;
    // in1 = "val"
    public resultArray4_int reduce_sumInc(int[] in1) {
        // Verify that "in1" is non-null.
        if (in1 == null) {
            throw new RSIllegalArgumentException("Array \"in1\" is null!");
        }
        Allocation ain1 = Allocation.createSized(mRSLocal, __I32, in1.length);
        ain1.setAutoPadding(true);
        ain1.copyFrom(in1);

        resultArray4_int result = reduce_sumInc(ain1, null);
        result.mTempIns = new Allocation[]{ain1};
        return result;
    }

    // ain1 = "int val"
    public resultArray4_int reduce_sumInc(Allocation ain1) {
        return reduce_sumInc(ain1, null);
    }

    // ain1 = "int val"
    public resultArray4_int reduce_sumInc(Allocation ain1, Script.LaunchOptions sc) {
        // check ain1
        if (!ain1.getType().getElement().isCompatible(__I32)) {
            throw new RSRuntimeException("Type mismatch with I32!");
        }
        Allocation aout = Allocation.createSized(mRSLocal, __I32, 4);
        aout.setAutoPadding(true);
        reduce(mExportReduceIdx_sumInc, new Allocation[]{ain1}, aout, sc);
        return new resultArray4_int(aout);
    }

}

