/*
 * 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_examples_halter.rs
 */

package examples;

import android.renderscript.*;
import examples.reduce_general_examples_halterBitCode;

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

    private Element __I32;
    private Element __I32_2;
    private RenderScript mRSLocal;
    // To obtain the result, invoke get(), which blocks
    // until the asynchronously-launched operation has completed.
    public static class result_int {
        public int get() {
            if (!mGotResult) {
                int[] outArray = new int[1];
                mOut.copyTo(outArray);
                mResult = outArray[0];
                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  result_int(Allocation out) {
            mTempIns = null;
            mOut = out;
            mGotResult = false;
        }

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

    // To obtain the result, invoke get(), which blocks
    // until the asynchronously-launched operation has completed.
    public static class result_int2 {
        public Int2 get() {
            if (!mGotResult) {
                int[] outArray = new int[2];
                mOut.copyTo(outArray);
                mResult = new Int2(outArray[0], outArray[1]);
                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  result_int2(Allocation out) {
            mTempIns = null;
            mOut = out;
            mGotResult = false;
        }

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

    private final static int mExportReduceIdx_fz = 0;
    // in1 = "inVal"
    public result_int reduce_fz(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);

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

    // ain1 = "int inVal"
    public result_int reduce_fz(Allocation ain1) {
        return reduce_fz(ain1, null);
    }

    // ain1 = "int inVal"
    public result_int reduce_fz(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, 1);
        aout.setAutoPadding(true);
        reduce(mExportReduceIdx_fz, new Allocation[]{ain1}, aout, sc);
        return new result_int(aout);
    }

    private final static int mExportReduceIdx_fz2 = 1;
    // in1 = "inVal"
    public result_int2 reduce_fz2(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);

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

    // ain1 = "int inVal"
    public result_int2 reduce_fz2(Allocation ain1) {
        return reduce_fz2(ain1, null);
    }

    // ain1 = "int inVal"
    public result_int2 reduce_fz2(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_2, 1);
        aout.setAutoPadding(true);
        reduce(mExportReduceIdx_fz2, new Allocation[]{ain1}, aout, sc);
        return new result_int2(aout);
    }

}

